btrfs: split parse_early_options() in two
Now parse_early_options() is used by both btrfs_mount() and btrfs_mount_root(). However, the former only needs subvol related part and the latter needs the others. Therefore extract the subvol related parts from parse_early_options() and move it to new parse function (parse_subvol_options()). Signed-off-by: Tomohiro Misono <misono.tomohiro@jp.fujitsu.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Родитель
312c89fbca
Коммит
d740760656
|
@ -463,7 +463,8 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
|
|||
case Opt_subvolrootid:
|
||||
case Opt_device:
|
||||
/*
|
||||
* These are parsed by btrfs_parse_early_options
|
||||
* These are parsed by btrfs_parse_subvol_options
|
||||
* and btrfs_parse_early_options
|
||||
* and can be happily ignored here.
|
||||
*/
|
||||
break;
|
||||
|
@ -897,11 +898,60 @@ out:
|
|||
* only when we need to allocate a new super block.
|
||||
*/
|
||||
static int btrfs_parse_early_options(const char *options, fmode_t flags,
|
||||
void *holder, char **subvol_name, u64 *subvol_objectid,
|
||||
struct btrfs_fs_devices **fs_devices)
|
||||
void *holder, struct btrfs_fs_devices **fs_devices)
|
||||
{
|
||||
substring_t args[MAX_OPT_ARGS];
|
||||
char *device_name, *opts, *orig, *p;
|
||||
int error = 0;
|
||||
|
||||
if (!options)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* strsep changes the string, duplicate it because btrfs_parse_options
|
||||
* gets called later
|
||||
*/
|
||||
opts = kstrdup(options, GFP_KERNEL);
|
||||
if (!opts)
|
||||
return -ENOMEM;
|
||||
orig = opts;
|
||||
|
||||
while ((p = strsep(&opts, ",")) != NULL) {
|
||||
int token;
|
||||
|
||||
if (!*p)
|
||||
continue;
|
||||
|
||||
token = match_token(p, tokens, args);
|
||||
if (token == Opt_device) {
|
||||
device_name = match_strdup(&args[0]);
|
||||
if (!device_name) {
|
||||
error = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
error = btrfs_scan_one_device(device_name,
|
||||
flags, holder, fs_devices);
|
||||
kfree(device_name);
|
||||
if (error)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(orig);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse mount options that are related to subvolume id
|
||||
*
|
||||
* The value is later passed to mount_subvol()
|
||||
*/
|
||||
static int btrfs_parse_subvol_options(const char *options, fmode_t flags,
|
||||
void *holder, char **subvol_name, u64 *subvol_objectid)
|
||||
{
|
||||
substring_t args[MAX_OPT_ARGS];
|
||||
char *opts, *orig, *p;
|
||||
char *num = NULL;
|
||||
int error = 0;
|
||||
|
||||
|
@ -909,8 +959,8 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags,
|
|||
return 0;
|
||||
|
||||
/*
|
||||
* strsep changes the string, duplicate it because parse_options
|
||||
* gets called twice
|
||||
* strsep changes the string, duplicate it because
|
||||
* btrfs_parse_early_options gets called later
|
||||
*/
|
||||
opts = kstrdup(options, GFP_KERNEL);
|
||||
if (!opts)
|
||||
|
@ -949,18 +999,6 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags,
|
|||
case Opt_subvolrootid:
|
||||
pr_warn("BTRFS: 'subvolrootid' mount option is deprecated and has no effect\n");
|
||||
break;
|
||||
case Opt_device:
|
||||
device_name = match_strdup(&args[0]);
|
||||
if (!device_name) {
|
||||
error = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
error = btrfs_scan_one_device(device_name,
|
||||
flags, holder, fs_devices);
|
||||
kfree(device_name);
|
||||
if (error)
|
||||
goto out;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1536,18 +1574,14 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type,
|
|||
struct btrfs_fs_info *fs_info = NULL;
|
||||
struct security_mnt_opts new_sec_opts;
|
||||
fmode_t mode = FMODE_READ;
|
||||
char *subvol_name = NULL;
|
||||
u64 subvol_objectid = 0;
|
||||
int error = 0;
|
||||
|
||||
if (!(flags & SB_RDONLY))
|
||||
mode |= FMODE_WRITE;
|
||||
|
||||
error = btrfs_parse_early_options(data, mode, fs_type,
|
||||
&subvol_name, &subvol_objectid,
|
||||
&fs_devices);
|
||||
if (error) {
|
||||
kfree(subvol_name);
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
|
||||
|
@ -1659,7 +1693,6 @@ error_sec_opts:
|
|||
static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
|
||||
const char *device_name, void *data)
|
||||
{
|
||||
struct btrfs_fs_devices *fs_devices = NULL;
|
||||
struct vfsmount *mnt_root;
|
||||
struct dentry *root;
|
||||
fmode_t mode = FMODE_READ;
|
||||
|
@ -1670,9 +1703,8 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
|
|||
if (!(flags & SB_RDONLY))
|
||||
mode |= FMODE_WRITE;
|
||||
|
||||
error = btrfs_parse_early_options(data, mode, fs_type,
|
||||
&subvol_name, &subvol_objectid,
|
||||
&fs_devices);
|
||||
error = btrfs_parse_subvol_options(data, mode, fs_type,
|
||||
&subvol_name, &subvol_objectid);
|
||||
if (error) {
|
||||
kfree(subvol_name);
|
||||
return ERR_PTR(error);
|
||||
|
|
Загрузка…
Ссылка в новой задаче