mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-05 10:29:37 +00:00
btrfs: preparation to fixing mount/umount race
We need fs_info and root to live until the moment when the victim superblock leaves the list, so we need to postpone free_fs_info() until after ->put_super(). The call is buried in close_ctree(), though, so we need to lift it into the callers (including btrfs_put_super()) first. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
48fa57ac2c
commit
98c7089c76
2 changed files with 6 additions and 3 deletions
|
@ -2424,6 +2424,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
|
|||
up_read(&fs_info->cleanup_work_sem);
|
||||
if (err) {
|
||||
close_ctree(tree_root);
|
||||
free_fs_info(fs_info);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
}
|
||||
|
@ -3059,8 +3060,6 @@ int close_ctree(struct btrfs_root *root)
|
|||
bdi_destroy(&fs_info->bdi);
|
||||
cleanup_srcu_struct(&fs_info->subvol_srcu);
|
||||
|
||||
free_fs_info(fs_info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -151,6 +151,7 @@ static void btrfs_put_super(struct super_block *sb)
|
|||
int ret;
|
||||
|
||||
ret = close_ctree(root);
|
||||
free_fs_info(root->fs_info);
|
||||
sb->s_fs_info = NULL;
|
||||
|
||||
(void)ret; /* FIXME: need to fix VFS to return error? */
|
||||
|
@ -589,6 +590,7 @@ static int btrfs_fill_super(struct super_block *sb,
|
|||
struct inode *inode;
|
||||
struct dentry *root_dentry;
|
||||
struct btrfs_root *tree_root;
|
||||
struct btrfs_fs_info *fs_info;
|
||||
struct btrfs_key key;
|
||||
int err;
|
||||
|
||||
|
@ -609,12 +611,13 @@ static int btrfs_fill_super(struct super_block *sb,
|
|||
printk("btrfs: open_ctree failed\n");
|
||||
return PTR_ERR(tree_root);
|
||||
}
|
||||
fs_info = tree_root->fs_info;
|
||||
sb->s_fs_info = tree_root;
|
||||
|
||||
key.objectid = BTRFS_FIRST_FREE_OBJECTID;
|
||||
key.type = BTRFS_INODE_ITEM_KEY;
|
||||
key.offset = 0;
|
||||
inode = btrfs_iget(sb, &key, tree_root->fs_info->fs_root, NULL);
|
||||
inode = btrfs_iget(sb, &key, fs_info->fs_root, NULL);
|
||||
if (IS_ERR(inode)) {
|
||||
err = PTR_ERR(inode);
|
||||
goto fail_close;
|
||||
|
@ -635,6 +638,7 @@ static int btrfs_fill_super(struct super_block *sb,
|
|||
|
||||
fail_close:
|
||||
close_ctree(tree_root);
|
||||
free_fs_info(fs_info);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue