We allow recursive mounts with subvol options such as [1] [1] mount -o rw,compress=lzo /dev/sdc /btrfs1 mount -o ro,subvol=sv2 /dev/sdc /btrfs2
And except for the btrfs-specific subvol and subvolid options all-other options are just ignored in the subsequent mounts. In the below example [2] the effect compression is only zlib, even though there was no error for the option -o compress=lzo. [2] ---- # mount -o compress=zlib /dev/sdc /btrfs1 #echo $? 0 # mount -o compress=lzo /dev/sdc /btrfs #echo $? 0 #cat /proc/self/mounts :: /dev/sdc /btrfs1 btrfs rw,relatime,compress=zlib,space_cache,subvolid=5,subvol=/ 0 0 /dev/sdc /btrfs btrfs rw,relatime,compress=zlib,space_cache,subvolid=5,subvol=/ 0 0 ---- Further, random string .. has no error as well. ----- # mount -o compress=zlib /dev/sdc /btrfs1 #echo $? 0 # mount -o something /dev/sdc /btrfs #echo $? 0 ----- This patch fixes the above issue, by checking the if the passed options are only subvol or subvolid in the subsequent mount. Signed-off-by: Anand Jain <anand.j...@oracle.com> --- fs/btrfs/super.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 9530a333d302..e0e542345c38 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -389,6 +389,44 @@ static const match_table_t tokens = { {Opt_err, NULL}, }; +static int parse_recursive_mount_options(char *data) +{ + substring_t args[MAX_OPT_ARGS]; + char *options, *orig; + char *p; + int ret = 0; + + /* + * This is not a remount thread, but we allow recursive mounts + * with varying RO/RW flag to support subvol-mounts. So error-out + * if any other option being passed in here. + */ + + options = kstrdup(data, GFP_NOFS); + if (!options) + return -ENOMEM; + + orig = options; + + while ((p = strsep(&options, ",")) != NULL) { + int token; + if (!*p) + continue; + + token = match_token(p, tokens, args); + switch(token) { + case Opt_subvol: + case Opt_subvolid: + break; + default: + ret = -EBUSY; + } + } + + kfree(orig); + return ret; +} + /* * Regular mount options parser. Everything that is needed only when * reading in a new superblock is parsed here. @@ -1611,6 +1649,8 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, free_fs_info(fs_info); if ((flags ^ s->s_flags) & MS_RDONLY) error = -EBUSY; + if (parse_recursive_mount_options(data)) + error = -EBUSY; } else { snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev); btrfs_sb(s)->bdev_holder = fs_type; -- 2.10.0 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html