Merge patch series "fs/super.c: introduce get_tree_bdev_flags()"

Allison Karlitskaya <allison.karlitskaya@redhat.com> says:

In context of my work on composefs/bootc I've been testing the new support
for directly mounting files with erofs (ie: without a loopback device) and
it's working well.  Thanks for adding this feature --- it's a huge quality
of life improvement for us.

I've observed a strange behaviour, though: when mounting a file as an
erofs, if you read() the filesystem context fd, you always get the
following error message reported: Can't lookup blockdev.

That's caused by the code in erofs_fc_get_tree() trying to call
get_tree_bdev() and recovering from the error in case it was ENOTBLK and
CONFIG_EROFS_FS_BACKED_BY_FILE.  Unfortunately, get_tree_bdev() logs the
error directly on the fs_context, so you get the error message even on
successful mounts.

It looks something like this at the syscall level:

fsopen("erofs", FSOPEN_CLOEXEC)         = 3
fsconfig(3, FSCONFIG_SET_FLAG, "ro", NULL, 0) = 0
fsconfig(3, FSCONFIG_SET_STRING, "source", "/home/lis/src/mountcfs/cfs", 0)
= 0
fsconfig(3, FSCONFIG_CMD_CREATE, NULL, NULL, 0) = 0
fsmount(3, FSMOUNT_CLOEXEC, 0)          = 5
move_mount(5, "", AT_FDCWD, "/tmp/composefs.upper.KuT5aV",
MOVE_MOUNT_F_EMPTY_PATH) = 0
read(3, "e /home/lis/src/mountcfs/cfs: Can't lookup blockdev\n", 1024) = 52

This is kernel 6.12.0-0.rc0.20240926git11a299a7933e.13.fc42.x86_64 from
Fedora Rawhide.

It's a pretty minor issue, but it sent me on a wild goose chase for an hour
or two, so probably it should get fixed before the final release.

Gao Xiang <hsiangkao@linux.alibaba.com>:

Fix this by providing a get_tree_bdev_flags() helper which can be used
to silence such warnings.

* patches from https://lore.kernel.org/r/20241009033151.2334888-1-hsiangkao@linux.alibaba.com:
  erofs: use get_tree_bdev_flags() to avoid misleading messages
  fs/super.c: introduce get_tree_bdev_flags()

Link: https://lore.kernel.org/r/20241009033151.2334888-1-hsiangkao@linux.alibaba.com
Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
Christian Brauner 2024-10-21 14:30:29 +02:00
commit 35100ae2dc
No known key found for this signature in database
GPG Key ID: 91C61BC06578DCA2
3 changed files with 29 additions and 7 deletions

View File

@ -709,7 +709,9 @@ static int erofs_fc_get_tree(struct fs_context *fc)
if (IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND) && sbi->fsid)
return get_tree_nodev(fc, erofs_fc_fill_super);
ret = get_tree_bdev(fc, erofs_fc_fill_super);
ret = get_tree_bdev_flags(fc, erofs_fc_fill_super,
IS_ENABLED(CONFIG_EROFS_FS_BACKED_BY_FILE) ?
GET_TREE_BDEV_QUIET_LOOKUP : 0);
#ifdef CONFIG_EROFS_FS_BACKED_BY_FILE
if (ret == -ENOTBLK) {
if (!fc->source)

View File

@ -1596,13 +1596,14 @@ int setup_bdev_super(struct super_block *sb, int sb_flags,
EXPORT_SYMBOL_GPL(setup_bdev_super);
/**
* get_tree_bdev - Get a superblock based on a single block device
* get_tree_bdev_flags - Get a superblock based on a single block device
* @fc: The filesystem context holding the parameters
* @fill_super: Helper to initialise a new superblock
* @flags: GET_TREE_BDEV_* flags
*/
int get_tree_bdev(struct fs_context *fc,
int (*fill_super)(struct super_block *,
struct fs_context *))
int get_tree_bdev_flags(struct fs_context *fc,
int (*fill_super)(struct super_block *sb,
struct fs_context *fc), unsigned int flags)
{
struct super_block *s;
int error = 0;
@ -1613,10 +1614,10 @@ int get_tree_bdev(struct fs_context *fc,
error = lookup_bdev(fc->source, &dev);
if (error) {
errorf(fc, "%s: Can't lookup blockdev", fc->source);
if (!(flags & GET_TREE_BDEV_QUIET_LOOKUP))
errorf(fc, "%s: Can't lookup blockdev", fc->source);
return error;
}
fc->sb_flags |= SB_NOSEC;
s = sget_dev(fc, dev);
if (IS_ERR(s))
@ -1644,6 +1645,19 @@ int get_tree_bdev(struct fs_context *fc,
fc->root = dget(s->s_root);
return 0;
}
EXPORT_SYMBOL_GPL(get_tree_bdev_flags);
/**
* get_tree_bdev - Get a superblock based on a single block device
* @fc: The filesystem context holding the parameters
* @fill_super: Helper to initialise a new superblock
*/
int get_tree_bdev(struct fs_context *fc,
int (*fill_super)(struct super_block *,
struct fs_context *))
{
return get_tree_bdev_flags(fc, fill_super, 0);
}
EXPORT_SYMBOL(get_tree_bdev);
static int test_bdev_super(struct super_block *s, void *data)

View File

@ -160,6 +160,12 @@ extern int get_tree_keyed(struct fs_context *fc,
int setup_bdev_super(struct super_block *sb, int sb_flags,
struct fs_context *fc);
#define GET_TREE_BDEV_QUIET_LOOKUP 0x0001
int get_tree_bdev_flags(struct fs_context *fc,
int (*fill_super)(struct super_block *sb,
struct fs_context *fc), unsigned int flags);
extern int get_tree_bdev(struct fs_context *fc,
int (*fill_super)(struct super_block *sb,
struct fs_context *fc));