* [PATCH v2 1/3] btrfs: change btrfs_mount() to mount_root()
2017-09-22 5:56 [PATCH v2 0/3] btrfs: cleanup mount path Misono, Tomohiro
@ 2017-09-22 5:58 ` Misono, Tomohiro
2017-09-22 5:59 ` [PATCH v2 2/3] btrfs: split parse_early_options() in two Misono, Tomohiro
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Misono, Tomohiro @ 2017-09-22 5:58 UTC (permalink / raw)
To: linux-btrfs; +Cc: anand.jain
Remove subvol related part from btrfs_mount() and change its name to
mount_root(). Also, file_system_type having mount_root() is defined
for the third patch.
New btrfs_mount() will be introduced in the third patch.
Signed-off-by: Tomohiro Misono <misono.tomohiro@jp.fujitsu.com>
---
fs/btrfs/super.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 12540b6..3c32677 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -66,6 +66,7 @@
static const struct super_operations btrfs_super_ops;
static struct file_system_type btrfs_fs_type;
+static struct file_system_type btrfs_root_fs_type;
static int btrfs_remount(struct super_block *sb, int *flags, char *data);
@@ -1517,10 +1518,10 @@ static int setup_security_options(struct btrfs_fs_info *fs_info,
/*
* Find a superblock for the given device / mount point.
*
- * Note: This is based on get_sb_bdev from fs/super.c with a few additions
+ * Note: This is based on mount_bdev from fs/super.c with a few additions
* for multiple device setup. Make sure to keep it in sync.
*/
-static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
+static struct dentry *mount_root(struct file_system_type *fs_type, int flags,
const char *device_name, void *data)
{
struct block_device *bdev = NULL;
@@ -1529,27 +1530,17 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
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 & MS_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);
}
- if (subvol_name || subvol_objectid != BTRFS_FS_TREE_OBJECTID) {
- /* mount_subvol() will free subvol_name. */
- return mount_subvol(subvol_name, subvol_objectid, flags,
- device_name, data);
- }
-
security_init_mnt_opts(&new_sec_opts);
if (data) {
error = parse_security_options(data, &new_sec_opts);
@@ -2133,6 +2124,15 @@ static struct file_system_type btrfs_fs_type = {
.kill_sb = btrfs_kill_super,
.fs_flags = FS_REQUIRES_DEV | FS_BINARY_MOUNTDATA,
};
+
+static struct file_system_type btrfs_root_fs_type = {
+ .owner = THIS_MODULE,
+ .name = "btrfs",
+ .mount = mount_root,
+ .kill_sb = btrfs_kill_super,
+ .fs_flags = FS_REQUIRES_DEV | FS_BINARY_MOUNTDATA,
+};
+
MODULE_ALIAS_FS("btrfs");
static int btrfs_control_open(struct inode *inode, struct file *file)
--
2.9.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 2/3] btrfs: split parse_early_options() in two
2017-09-22 5:56 [PATCH v2 0/3] btrfs: cleanup mount path Misono, Tomohiro
2017-09-22 5:58 ` [PATCH v2 1/3] btrfs: change btrfs_mount() to mount_root() Misono, Tomohiro
@ 2017-09-22 5:59 ` Misono, Tomohiro
2017-09-22 5:59 ` [PATCH v2 3/3] btrfs: introduce new btrfs_mount() Misono, Tomohiro
2017-09-24 13:22 ` [PATCH v2 0/3] btrfs: cleanup mount path David Sterba
3 siblings, 0 replies; 6+ messages in thread
From: Misono, Tomohiro @ 2017-09-22 5:59 UTC (permalink / raw)
To: linux-btrfs; +Cc: anand.jain
Extract the part related to subvol option from parse_early_options() and
move it to new parse function (parse_subvol_options()).
This is because mount_root() doesn't need to handle subvol options.
Signed-off-by: Tomohiro Misono <misono.tomohiro@jp.fujitsu.com>
---
fs/btrfs/super.c | 75 +++++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 58 insertions(+), 17 deletions(-)
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 3c32677..9498743 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -448,7 +448,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;
@@ -855,11 +856,63 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
* 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);
+ switch (token) {
+ 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;
+ }
+ }
+
+out:
+ kfree(orig);
+ return error;
+}
+
+/*
+ * Parse mount options that are related to subvolume id
+ *
+ * The parsed 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;
@@ -867,8 +920,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)
@@ -907,18 +960,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;
}
--
2.9.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 3/3] btrfs: introduce new btrfs_mount()
2017-09-22 5:56 [PATCH v2 0/3] btrfs: cleanup mount path Misono, Tomohiro
2017-09-22 5:58 ` [PATCH v2 1/3] btrfs: change btrfs_mount() to mount_root() Misono, Tomohiro
2017-09-22 5:59 ` [PATCH v2 2/3] btrfs: split parse_early_options() in two Misono, Tomohiro
@ 2017-09-22 5:59 ` Misono, Tomohiro
2017-09-22 6:05 ` Misono, Tomohiro
2017-09-24 13:22 ` [PATCH v2 0/3] btrfs: cleanup mount path David Sterba
3 siblings, 1 reply; 6+ messages in thread
From: Misono, Tomohiro @ 2017-09-22 5:59 UTC (permalink / raw)
To: linux-btrfs; +Cc: anand.jain
Introduce new btrfs_mount() using previous setups.
This will do:
(1) parse subvol id related options for later use in mount_subtree()
(2) mount device's root by calling vfs_kern_mount() with
btrfs_root_fs_type. As a result, mount_root() is called
(3) return by calling mount_subtree()
The code of (2) is moved from the first part of mount_subvol().
setup_root_args() is deleted as not needed anymore.
Signed-off-by: Tomohiro Misono <misono.tomohiro@jp.fujitsu.com>
---
fs/btrfs/super.c | 132 ++++++++++++++++++++++++-------------------------------
1 file changed, 58 insertions(+), 74 deletions(-)
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 9498743..47c0692 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1367,85 +1367,13 @@ static inline int is_subvolume_inode(struct inode *inode)
return 0;
}
-/*
- * This will add subvolid=0 to the argument string while removing any subvol=
- * and subvolid= arguments to make sure we get the top-level root for path
- * walking to the subvol we want.
- */
-static char *setup_root_args(char *args)
-{
- char *buf, *dst, *sep;
-
- if (!args)
- return kstrdup("subvolid=0", GFP_NOFS);
-
- /* The worst case is that we add ",subvolid=0" to the end. */
- buf = dst = kmalloc(strlen(args) + strlen(",subvolid=0") + 1, GFP_NOFS);
- if (!buf)
- return NULL;
-
- while (1) {
- sep = strchrnul(args, ',');
- if (!strstarts(args, "subvol=") &&
- !strstarts(args, "subvolid=")) {
- memcpy(dst, args, sep - args);
- dst += sep - args;
- *dst++ = ',';
- }
- if (*sep)
- args = sep + 1;
- else
- break;
- }
- strcpy(dst, "subvolid=0");
-
- return buf;
-}
-
static struct dentry *mount_subvol(const char *subvol_name, u64 subvol_objectid,
int flags, const char *device_name,
- char *data)
+ char *data, struct vfsmount *mnt)
{
struct dentry *root;
- struct vfsmount *mnt = NULL;
- char *newargs;
int ret;
- newargs = setup_root_args(data);
- if (!newargs) {
- root = ERR_PTR(-ENOMEM);
- goto out;
- }
-
- mnt = vfs_kern_mount(&btrfs_fs_type, flags, device_name, newargs);
- if (PTR_ERR_OR_ZERO(mnt) == -EBUSY) {
- if (flags & MS_RDONLY) {
- mnt = vfs_kern_mount(&btrfs_fs_type, flags & ~MS_RDONLY,
- device_name, newargs);
- } else {
- mnt = vfs_kern_mount(&btrfs_fs_type, flags | MS_RDONLY,
- device_name, newargs);
- if (IS_ERR(mnt)) {
- root = ERR_CAST(mnt);
- mnt = NULL;
- goto out;
- }
-
- down_write(&mnt->mnt_sb->s_umount);
- ret = btrfs_remount(mnt->mnt_sb, &flags, NULL);
- up_write(&mnt->mnt_sb->s_umount);
- if (ret < 0) {
- root = ERR_PTR(ret);
- goto out;
- }
- }
- }
- if (IS_ERR(mnt)) {
- root = ERR_CAST(mnt);
- mnt = NULL;
- goto out;
- }
-
if (!subvol_name) {
if (!subvol_objectid) {
ret = get_default_subvol_objectid(btrfs_sb(mnt->mnt_sb),
@@ -1501,7 +1429,6 @@ static struct dentry *mount_subvol(const char *subvol_name, u64 subvol_objectid,
out:
mntput(mnt);
- kfree(newargs);
kfree(subvol_name);
return root;
}
@@ -1665,6 +1592,63 @@ static struct dentry *mount_root(struct file_system_type *fs_type, int flags,
return ERR_PTR(error);
}
+static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
+ const char *device_name, void *data)
+{
+ struct vfsmount *mnt_root;
+ struct dentry *root;
+ fmode_t mode = FMODE_READ;
+ char *subvol_name = NULL;
+ u64 subvol_objectid = 0;
+ int error = 0;
+
+ if (!(flags & MS_RDONLY))
+ mode |= FMODE_WRITE;
+
+ error = btrfs_parse_subvol_options(data, mode, fs_type,
+ &subvol_name, &subvol_objectid);
+ if (error) {
+ kfree(subvol_name);
+ return ERR_PTR(error);
+ }
+
+ /* mount device's root (/) */
+ mnt_root = vfs_kern_mount(&btrfs_root_fs_type, flags, device_name, data);
+ if (PTR_ERR_OR_ZERO(mnt_root) == -EBUSY) {
+ if (flags & MS_RDONLY) {
+ mnt_root = vfs_kern_mount(&btrfs_root_fs_type, flags & ~MS_RDONLY,
+ device_name, data);
+ } else {
+ mnt_root = vfs_kern_mount(&btrfs_root_fs_type, flags | MS_RDONLY,
+ device_name, data);
+ if (IS_ERR(mnt_root)) {
+ root = ERR_CAST(mnt_root);
+ goto out;
+ }
+
+ down_write(&mnt_root->mnt_sb->s_umount);
+ error = btrfs_remount(mnt_root->mnt_sb, &flags, NULL);
+ up_write(&mnt_root->mnt_sb->s_umount);
+ if (error < 0) {
+ root = ERR_PTR(error);
+ mntput(mnt_root);
+ goto out;
+ }
+ }
+ }
+ if (IS_ERR(mnt_root)) {
+ root = ERR_CAST(mnt_root);
+ goto out;
+ }
+
+ /* mount_subvol() will free subvol_name and mnt_root */
+ root = mount_subvol(subvol_name, subvol_objectid, flags,
+ device_name, data, mnt_root);
+
+out:
+ return root;
+}
+
static void btrfs_resize_thread_pool(struct btrfs_fs_info *fs_info,
int new_pool_size, int old_pool_size)
{
--
2.9.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2 0/3] btrfs: cleanup mount path
2017-09-22 5:56 [PATCH v2 0/3] btrfs: cleanup mount path Misono, Tomohiro
` (2 preceding siblings ...)
2017-09-22 5:59 ` [PATCH v2 3/3] btrfs: introduce new btrfs_mount() Misono, Tomohiro
@ 2017-09-24 13:22 ` David Sterba
3 siblings, 0 replies; 6+ messages in thread
From: David Sterba @ 2017-09-24 13:22 UTC (permalink / raw)
To: Misono, Tomohiro; +Cc: linux-btrfs, anand.jain
On Fri, Sep 22, 2017 at 02:56:49PM +0900, Misono, Tomohiro wrote:
> Summary:
> Cleanup mount path by avoiding calling btrfs_mount() twice.
That would be great to get rid of it, but please do it in smaller steps,
each of them being bisectable and preserving the existing functionality.
Patch 1/3 does not compile on any branch (master, v4.13, current devel
queue), removes the ability to mount via subvolume. I don't undserstand
(yet) why the other filesystem type is introduced as it is exactly the
same as the one we have now.
The description in the cover leter of the overall logic of the mount
should be added as a comment before btrfs_mount.
^ permalink raw reply [flat|nested] 6+ messages in thread