mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 19:13:47 +02:00
btrfs: get rid of re-entering of btrfs_get_tree()
[EXISTING PROBLEM]
Currently btrfs mount is split into two parts:
- btrfs_get_tree_subvol()
Which sets up the very basic fs_info, and eventually calls
mount_subvol() to mount the target subvolume.
- btrfs_get_tree_super()
This is the part doing super block allocation and if there is no
existing super block, do the real open_ctree() to open the fs.
However currently we're doing this in a complex re-entering way:
vfs_get_tree()
|- btrfs_get_tree()
|- btrfs_get_tree_subvol()
|- vfs_get_tree()
| |- btrfs_get_tree()
| |- btrfs_get_tree_super()
|- mount_subvol()
This is definitely not that easy to grasp.
[ENHANCEMENT]
The function vfs_get_tree() is only doing the following work:
- Call get_tree() call back
- Call super_wake()
- Call security_sb_set_mnt_opts()
In our case, super_wake() can be skipped, as after
btrfs_get_tree_subvol() finishes, vfs_get_tree() will call super_wake()
on the super block we got anyway.
The same applies to security_sb_set_mnt_opts(), as long as we do not
free the security from our original fc in btrfs_get_tree_subvol(), the
first vfs_get_tree() call will handle the security correctly.
So here we only need to:
- Replace vfs_get_tree() call with btrfs_get_tree_super()
- Keep the existing fc->security for vfs_get_tree() to handle the
security
This will remove the re-entering behavior and make thing much easier to
follow.
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
ae818824a2
commit
35ea448b75
|
|
@ -2046,15 +2046,7 @@ static int btrfs_get_tree_subvol(struct fs_context *fc)
|
|||
*/
|
||||
dup_fc->s_fs_info = fs_info;
|
||||
|
||||
/*
|
||||
* We'll do the security settings in our btrfs_get_tree_super() mount
|
||||
* loop, they were duplicated into dup_fc, we can drop the originals
|
||||
* here.
|
||||
*/
|
||||
security_free_mnt_opts(&fc->security);
|
||||
fc->security = NULL;
|
||||
|
||||
ret = vfs_get_tree(dup_fc);
|
||||
ret = btrfs_get_tree_super(dup_fc);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
|
|
@ -2086,21 +2078,8 @@ static int btrfs_get_tree_subvol(struct fs_context *fc)
|
|||
|
||||
static int btrfs_get_tree(struct fs_context *fc)
|
||||
{
|
||||
/*
|
||||
* Since we use mount_subtree to mount the default/specified subvol, we
|
||||
* have to do mounts in two steps.
|
||||
*
|
||||
* First pass through we call btrfs_get_tree_subvol(), this is just a
|
||||
* wrapper around fc_mount() to call back into here again, and this time
|
||||
* we'll call btrfs_get_tree_super(). This will do the open_ctree() and
|
||||
* everything to open the devices and file system. Then we return back
|
||||
* with a fully constructed vfsmount in btrfs_get_tree_subvol(), and
|
||||
* from there we can do our mount_subvol() call, which will lookup
|
||||
* whichever subvol we're mounting and setup this fc with the
|
||||
* appropriate dentry for the subvol.
|
||||
*/
|
||||
if (fc->s_fs_info)
|
||||
return btrfs_get_tree_super(fc);
|
||||
ASSERT(fc->s_fs_info == NULL);
|
||||
|
||||
return btrfs_get_tree_subvol(fc);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user