Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 98c7089c authored by Al Viro's avatar Al Viro
Browse files

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: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 48fa57ac
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -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;
}

+5 −1
Original line number Diff line number Diff line
@@ -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;
}