diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2011-11-17 01:22:46 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-01-08 19:33:23 -0500 |
commit | aea52e19dd2085617dd7d247afb76a90cf2ea40c (patch) | |
tree | d1416b60797f2a5f0c0f67062bcaaee6b227683a /fs/btrfs/super.c | |
parent | 98c7089c769048f941bd5c5285287f8fc301f8b1 (diff) |
btrfs: get ->kill_sb() of its own
... and move free_fs_info() to that, out of ->put_super(). Do NOT
set ->s_fs_info to NULL in the latter; we need it for sget() to
be able to see and wait for fs in the middle of umount if we get a
mount/umount race.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r-- | fs/btrfs/super.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index a3f435e58987..eca48624a4f0 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -147,14 +147,13 @@ void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function, | |||
147 | 147 | ||
148 | static void btrfs_put_super(struct super_block *sb) | 148 | static void btrfs_put_super(struct super_block *sb) |
149 | { | 149 | { |
150 | struct btrfs_root *root = btrfs_sb(sb); | 150 | (void)close_ctree(btrfs_sb(sb)); |
151 | int ret; | 151 | /* FIXME: need to fix VFS to return error? */ |
152 | 152 | /* AV: return it _where_? ->put_super() can be triggered by any number | |
153 | ret = close_ctree(root); | 153 | * of async events, up to and including delivery of SIGKILL to the |
154 | free_fs_info(root->fs_info); | 154 | * last process that kept it busy. Or segfault in the aforementioned |
155 | sb->s_fs_info = NULL; | 155 | * process... Whom would you report that to? |
156 | 156 | */ | |
157 | (void)ret; /* FIXME: need to fix VFS to return error? */ | ||
158 | } | 157 | } |
159 | 158 | ||
160 | enum { | 159 | enum { |
@@ -1223,11 +1222,21 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
1223 | return 0; | 1222 | return 0; |
1224 | } | 1223 | } |
1225 | 1224 | ||
1225 | static void btrfs_kill_super(struct super_block *sb) | ||
1226 | { | ||
1227 | struct btrfs_fs_info *fs_info = NULL; | ||
1228 | if (sb->s_root) | ||
1229 | fs_info = btrfs_sb(sb)->fs_info; | ||
1230 | kill_anon_super(sb); | ||
1231 | if (fs_info) | ||
1232 | free_fs_info(fs_info); | ||
1233 | } | ||
1234 | |||
1226 | static struct file_system_type btrfs_fs_type = { | 1235 | static struct file_system_type btrfs_fs_type = { |
1227 | .owner = THIS_MODULE, | 1236 | .owner = THIS_MODULE, |
1228 | .name = "btrfs", | 1237 | .name = "btrfs", |
1229 | .mount = btrfs_mount, | 1238 | .mount = btrfs_mount, |
1230 | .kill_sb = kill_anon_super, | 1239 | .kill_sb = btrfs_kill_super, |
1231 | .fs_flags = FS_REQUIRES_DEV, | 1240 | .fs_flags = FS_REQUIRES_DEV, |
1232 | }; | 1241 | }; |
1233 | 1242 | ||