diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-17 18:52:51 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-17 18:52:51 -0500 |
commit | d65773b22b749252b2805dcf96bdeb951a9481d8 (patch) | |
tree | 1839656e894933267e7466e32ba6ad73b24fa60a /fs/btrfs | |
parent | f9156c7288e2d11501ded4d7fe6d9a3a41ee4057 (diff) | |
parent | f84a8bd60e3ee49eacc9ba824babf149ba3dad7e (diff) |
Merge branch 'btrfs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
* 'btrfs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
btrfs: take allocation of ->tree_root into open_ctree()
btrfs: let ->s_fs_info point to fs_info, not root...
btrfs: consolidate failure exits in btrfs_mount() a bit
btrfs: make free_fs_info() call ->kill_sb() unconditional
btrfs: merge free_fs_info() calls on fill_super failures
btrfs: kill pointless reassignment of ->s_fs_info in btrfs_fill_super()
btrfs: make open_ctree() return int
btrfs: sanitizing ->fs_info, part 5
btrfs: sanitizing ->fs_info, part 4
btrfs: sanitizing ->fs_info, part 3
btrfs: sanitizing ->fs_info, part 2
btrfs: sanitizing ->fs_info, part 1
btrfs: fix a deadlock in btrfs_scan_one_device()
btrfs: fix mount/umount race
btrfs: get ->kill_sb() of its own
btrfs: preparation to fixing mount/umount race
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/ctree.h | 2 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 70 | ||||
-rw-r--r-- | fs/btrfs/disk-io.h | 6 | ||||
-rw-r--r-- | fs/btrfs/export.c | 2 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 7 | ||||
-rw-r--r-- | fs/btrfs/super.c | 143 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 5 |
7 files changed, 110 insertions, 125 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 3c2cbf7b6663..27ebe61d3ccc 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -2364,7 +2364,7 @@ static inline u32 btrfs_file_extent_inline_item_len(struct extent_buffer *eb, | |||
2364 | return btrfs_item_size(eb, e) - offset; | 2364 | return btrfs_item_size(eb, e) - offset; |
2365 | } | 2365 | } |
2366 | 2366 | ||
2367 | static inline struct btrfs_root *btrfs_sb(struct super_block *sb) | 2367 | static inline struct btrfs_fs_info *btrfs_sb(struct super_block *sb) |
2368 | { | 2368 | { |
2369 | return sb->s_fs_info; | 2369 | return sb->s_fs_info; |
2370 | } | 2370 | } |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 89e99eb384db..7aa9cd36bf1b 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -1144,7 +1144,6 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, | |||
1144 | root->orphan_item_inserted = 0; | 1144 | root->orphan_item_inserted = 0; |
1145 | root->orphan_cleanup_state = 0; | 1145 | root->orphan_cleanup_state = 0; |
1146 | 1146 | ||
1147 | root->fs_info = fs_info; | ||
1148 | root->objectid = objectid; | 1147 | root->objectid = objectid; |
1149 | root->last_trans = 0; | 1148 | root->last_trans = 0; |
1150 | root->highest_objectid = 0; | 1149 | root->highest_objectid = 0; |
@@ -1218,6 +1217,14 @@ static int find_and_setup_root(struct btrfs_root *tree_root, | |||
1218 | return 0; | 1217 | return 0; |
1219 | } | 1218 | } |
1220 | 1219 | ||
1220 | static struct btrfs_root *btrfs_alloc_root(struct btrfs_fs_info *fs_info) | ||
1221 | { | ||
1222 | struct btrfs_root *root = kzalloc(sizeof(*root), GFP_NOFS); | ||
1223 | if (root) | ||
1224 | root->fs_info = fs_info; | ||
1225 | return root; | ||
1226 | } | ||
1227 | |||
1221 | static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans, | 1228 | static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans, |
1222 | struct btrfs_fs_info *fs_info) | 1229 | struct btrfs_fs_info *fs_info) |
1223 | { | 1230 | { |
@@ -1225,7 +1232,7 @@ static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans, | |||
1225 | struct btrfs_root *tree_root = fs_info->tree_root; | 1232 | struct btrfs_root *tree_root = fs_info->tree_root; |
1226 | struct extent_buffer *leaf; | 1233 | struct extent_buffer *leaf; |
1227 | 1234 | ||
1228 | root = kzalloc(sizeof(*root), GFP_NOFS); | 1235 | root = btrfs_alloc_root(fs_info); |
1229 | if (!root) | 1236 | if (!root) |
1230 | return ERR_PTR(-ENOMEM); | 1237 | return ERR_PTR(-ENOMEM); |
1231 | 1238 | ||
@@ -1320,7 +1327,7 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root, | |||
1320 | u32 blocksize; | 1327 | u32 blocksize; |
1321 | int ret = 0; | 1328 | int ret = 0; |
1322 | 1329 | ||
1323 | root = kzalloc(sizeof(*root), GFP_NOFS); | 1330 | root = btrfs_alloc_root(fs_info); |
1324 | if (!root) | 1331 | if (!root) |
1325 | return ERR_PTR(-ENOMEM); | 1332 | return ERR_PTR(-ENOMEM); |
1326 | if (location->offset == (u64)-1) { | 1333 | if (location->offset == (u64)-1) { |
@@ -1876,9 +1883,9 @@ static void free_root_pointers(struct btrfs_fs_info *info, int chunk_root) | |||
1876 | } | 1883 | } |
1877 | 1884 | ||
1878 | 1885 | ||
1879 | struct btrfs_root *open_ctree(struct super_block *sb, | 1886 | int open_ctree(struct super_block *sb, |
1880 | struct btrfs_fs_devices *fs_devices, | 1887 | struct btrfs_fs_devices *fs_devices, |
1881 | char *options) | 1888 | char *options) |
1882 | { | 1889 | { |
1883 | u32 sectorsize; | 1890 | u32 sectorsize; |
1884 | u32 nodesize; | 1891 | u32 nodesize; |
@@ -1890,8 +1897,8 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1890 | struct btrfs_key location; | 1897 | struct btrfs_key location; |
1891 | struct buffer_head *bh; | 1898 | struct buffer_head *bh; |
1892 | struct btrfs_super_block *disk_super; | 1899 | struct btrfs_super_block *disk_super; |
1893 | struct btrfs_root *tree_root = btrfs_sb(sb); | 1900 | struct btrfs_fs_info *fs_info = btrfs_sb(sb); |
1894 | struct btrfs_fs_info *fs_info = tree_root->fs_info; | 1901 | struct btrfs_root *tree_root; |
1895 | struct btrfs_root *extent_root; | 1902 | struct btrfs_root *extent_root; |
1896 | struct btrfs_root *csum_root; | 1903 | struct btrfs_root *csum_root; |
1897 | struct btrfs_root *chunk_root; | 1904 | struct btrfs_root *chunk_root; |
@@ -1902,16 +1909,14 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1902 | int num_backups_tried = 0; | 1909 | int num_backups_tried = 0; |
1903 | int backup_index = 0; | 1910 | int backup_index = 0; |
1904 | 1911 | ||
1905 | extent_root = fs_info->extent_root = | 1912 | tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info); |
1906 | kzalloc(sizeof(struct btrfs_root), GFP_NOFS); | 1913 | extent_root = fs_info->extent_root = btrfs_alloc_root(fs_info); |
1907 | csum_root = fs_info->csum_root = | 1914 | csum_root = fs_info->csum_root = btrfs_alloc_root(fs_info); |
1908 | kzalloc(sizeof(struct btrfs_root), GFP_NOFS); | 1915 | chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info); |
1909 | chunk_root = fs_info->chunk_root = | 1916 | dev_root = fs_info->dev_root = btrfs_alloc_root(fs_info); |
1910 | kzalloc(sizeof(struct btrfs_root), GFP_NOFS); | ||
1911 | dev_root = fs_info->dev_root = | ||
1912 | kzalloc(sizeof(struct btrfs_root), GFP_NOFS); | ||
1913 | 1917 | ||
1914 | if (!extent_root || !csum_root || !chunk_root || !dev_root) { | 1918 | if (!tree_root || !extent_root || !csum_root || |
1919 | !chunk_root || !dev_root) { | ||
1915 | err = -ENOMEM; | 1920 | err = -ENOMEM; |
1916 | goto fail; | 1921 | goto fail; |
1917 | } | 1922 | } |
@@ -2389,7 +2394,7 @@ retry_root_backup: | |||
2389 | btrfs_level_size(tree_root, | 2394 | btrfs_level_size(tree_root, |
2390 | btrfs_super_log_root_level(disk_super)); | 2395 | btrfs_super_log_root_level(disk_super)); |
2391 | 2396 | ||
2392 | log_tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS); | 2397 | log_tree_root = btrfs_alloc_root(fs_info); |
2393 | if (!log_tree_root) { | 2398 | if (!log_tree_root) { |
2394 | err = -ENOMEM; | 2399 | err = -ENOMEM; |
2395 | goto fail_trans_kthread; | 2400 | goto fail_trans_kthread; |
@@ -2450,11 +2455,11 @@ retry_root_backup: | |||
2450 | 2455 | ||
2451 | if (err) { | 2456 | if (err) { |
2452 | close_ctree(tree_root); | 2457 | close_ctree(tree_root); |
2453 | return ERR_PTR(err); | 2458 | return err; |
2454 | } | 2459 | } |
2455 | } | 2460 | } |
2456 | 2461 | ||
2457 | return tree_root; | 2462 | return 0; |
2458 | 2463 | ||
2459 | fail_trans_kthread: | 2464 | fail_trans_kthread: |
2460 | kthread_stop(fs_info->transaction_kthread); | 2465 | kthread_stop(fs_info->transaction_kthread); |
@@ -2500,8 +2505,7 @@ fail_srcu: | |||
2500 | cleanup_srcu_struct(&fs_info->subvol_srcu); | 2505 | cleanup_srcu_struct(&fs_info->subvol_srcu); |
2501 | fail: | 2506 | fail: |
2502 | btrfs_close_devices(fs_info->fs_devices); | 2507 | btrfs_close_devices(fs_info->fs_devices); |
2503 | free_fs_info(fs_info); | 2508 | return err; |
2504 | return ERR_PTR(err); | ||
2505 | 2509 | ||
2506 | recovery_tree_root: | 2510 | recovery_tree_root: |
2507 | if (!btrfs_test_opt(tree_root, RECOVERY)) | 2511 | if (!btrfs_test_opt(tree_root, RECOVERY)) |
@@ -3007,7 +3011,7 @@ int close_ctree(struct btrfs_root *root) | |||
3007 | (atomic_read(&fs_info->defrag_running) == 0)); | 3011 | (atomic_read(&fs_info->defrag_running) == 0)); |
3008 | 3012 | ||
3009 | /* clear out the rbtree of defraggable inodes */ | 3013 | /* clear out the rbtree of defraggable inodes */ |
3010 | btrfs_run_defrag_inodes(root->fs_info); | 3014 | btrfs_run_defrag_inodes(fs_info); |
3011 | 3015 | ||
3012 | /* | 3016 | /* |
3013 | * Here come 2 situations when btrfs is broken to flip readonly: | 3017 | * Here come 2 situations when btrfs is broken to flip readonly: |
@@ -3036,8 +3040,8 @@ int close_ctree(struct btrfs_root *root) | |||
3036 | 3040 | ||
3037 | btrfs_put_block_group_cache(fs_info); | 3041 | btrfs_put_block_group_cache(fs_info); |
3038 | 3042 | ||
3039 | kthread_stop(root->fs_info->transaction_kthread); | 3043 | kthread_stop(fs_info->transaction_kthread); |
3040 | kthread_stop(root->fs_info->cleaner_kthread); | 3044 | kthread_stop(fs_info->cleaner_kthread); |
3041 | 3045 | ||
3042 | fs_info->closing = 2; | 3046 | fs_info->closing = 2; |
3043 | smp_mb(); | 3047 | smp_mb(); |
@@ -3055,14 +3059,14 @@ int close_ctree(struct btrfs_root *root) | |||
3055 | free_extent_buffer(fs_info->extent_root->commit_root); | 3059 | free_extent_buffer(fs_info->extent_root->commit_root); |
3056 | free_extent_buffer(fs_info->tree_root->node); | 3060 | free_extent_buffer(fs_info->tree_root->node); |
3057 | free_extent_buffer(fs_info->tree_root->commit_root); | 3061 | free_extent_buffer(fs_info->tree_root->commit_root); |
3058 | free_extent_buffer(root->fs_info->chunk_root->node); | 3062 | free_extent_buffer(fs_info->chunk_root->node); |
3059 | free_extent_buffer(root->fs_info->chunk_root->commit_root); | 3063 | free_extent_buffer(fs_info->chunk_root->commit_root); |
3060 | free_extent_buffer(root->fs_info->dev_root->node); | 3064 | free_extent_buffer(fs_info->dev_root->node); |
3061 | free_extent_buffer(root->fs_info->dev_root->commit_root); | 3065 | free_extent_buffer(fs_info->dev_root->commit_root); |
3062 | free_extent_buffer(root->fs_info->csum_root->node); | 3066 | free_extent_buffer(fs_info->csum_root->node); |
3063 | free_extent_buffer(root->fs_info->csum_root->commit_root); | 3067 | free_extent_buffer(fs_info->csum_root->commit_root); |
3064 | 3068 | ||
3065 | btrfs_free_block_groups(root->fs_info); | 3069 | btrfs_free_block_groups(fs_info); |
3066 | 3070 | ||
3067 | del_fs_roots(fs_info); | 3071 | del_fs_roots(fs_info); |
3068 | 3072 | ||
@@ -3093,8 +3097,6 @@ int close_ctree(struct btrfs_root *root) | |||
3093 | bdi_destroy(&fs_info->bdi); | 3097 | bdi_destroy(&fs_info->bdi); |
3094 | cleanup_srcu_struct(&fs_info->subvol_srcu); | 3098 | cleanup_srcu_struct(&fs_info->subvol_srcu); |
3095 | 3099 | ||
3096 | free_fs_info(fs_info); | ||
3097 | |||
3098 | return 0; | 3100 | return 0; |
3099 | } | 3101 | } |
3100 | 3102 | ||
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index c99d0a8f13fa..e4bc4741319b 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h | |||
@@ -46,9 +46,9 @@ struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root, | |||
46 | u64 bytenr, u32 blocksize); | 46 | u64 bytenr, u32 blocksize); |
47 | int clean_tree_block(struct btrfs_trans_handle *trans, | 47 | int clean_tree_block(struct btrfs_trans_handle *trans, |
48 | struct btrfs_root *root, struct extent_buffer *buf); | 48 | struct btrfs_root *root, struct extent_buffer *buf); |
49 | struct btrfs_root *open_ctree(struct super_block *sb, | 49 | int open_ctree(struct super_block *sb, |
50 | struct btrfs_fs_devices *fs_devices, | 50 | struct btrfs_fs_devices *fs_devices, |
51 | char *options); | 51 | char *options); |
52 | int close_ctree(struct btrfs_root *root); | 52 | int close_ctree(struct btrfs_root *root); |
53 | int write_ctree_super(struct btrfs_trans_handle *trans, | 53 | int write_ctree_super(struct btrfs_trans_handle *trans, |
54 | struct btrfs_root *root, int max_mirrors); | 54 | struct btrfs_root *root, int max_mirrors); |
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c index 1b8dc33778f9..5f77166fd01c 100644 --- a/fs/btrfs/export.c +++ b/fs/btrfs/export.c | |||
@@ -67,7 +67,7 @@ static struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid, | |||
67 | u64 root_objectid, u32 generation, | 67 | u64 root_objectid, u32 generation, |
68 | int check_generation) | 68 | int check_generation) |
69 | { | 69 | { |
70 | struct btrfs_fs_info *fs_info = btrfs_sb(sb)->fs_info; | 70 | struct btrfs_fs_info *fs_info = btrfs_sb(sb); |
71 | struct btrfs_root *root; | 71 | struct btrfs_root *root; |
72 | struct inode *inode; | 72 | struct inode *inode; |
73 | struct btrfs_key key; | 73 | struct btrfs_key key; |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 2db7c1455c7f..ab620014bcc3 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -286,14 +286,13 @@ static int btrfs_ioctl_getversion(struct file *file, int __user *arg) | |||
286 | 286 | ||
287 | static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) | 287 | static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) |
288 | { | 288 | { |
289 | struct btrfs_root *root = fdentry(file)->d_sb->s_fs_info; | 289 | struct btrfs_fs_info *fs_info = btrfs_sb(fdentry(file)->d_sb); |
290 | struct btrfs_fs_info *fs_info = root->fs_info; | ||
291 | struct btrfs_device *device; | 290 | struct btrfs_device *device; |
292 | struct request_queue *q; | 291 | struct request_queue *q; |
293 | struct fstrim_range range; | 292 | struct fstrim_range range; |
294 | u64 minlen = ULLONG_MAX; | 293 | u64 minlen = ULLONG_MAX; |
295 | u64 num_devices = 0; | 294 | u64 num_devices = 0; |
296 | u64 total_bytes = btrfs_super_total_bytes(root->fs_info->super_copy); | 295 | u64 total_bytes = btrfs_super_total_bytes(fs_info->super_copy); |
297 | int ret; | 296 | int ret; |
298 | 297 | ||
299 | if (!capable(CAP_SYS_ADMIN)) | 298 | if (!capable(CAP_SYS_ADMIN)) |
@@ -322,7 +321,7 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) | |||
322 | 321 | ||
323 | range.len = min(range.len, total_bytes - range.start); | 322 | range.len = min(range.len, total_bytes - range.start); |
324 | range.minlen = max(range.minlen, minlen); | 323 | range.minlen = max(range.minlen, minlen); |
325 | ret = btrfs_trim_fs(root, &range); | 324 | ret = btrfs_trim_fs(fs_info->tree_root, &range); |
326 | if (ret < 0) | 325 | if (ret < 0) |
327 | return ret; | 326 | return ret; |
328 | 327 | ||
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 8ffaaa8e3df8..3ce97b217cbe 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -147,13 +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)->tree_root); |
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 | sb->s_fs_info = NULL; | 154 | * last process that kept it busy. Or segfault in the aforementioned |
155 | 155 | * process... Whom would you report that to? | |
156 | (void)ret; /* FIXME: need to fix VFS to return error? */ | 156 | */ |
157 | } | 157 | } |
158 | 158 | ||
159 | enum { | 159 | enum { |
@@ -541,7 +541,8 @@ out: | |||
541 | static struct dentry *get_default_root(struct super_block *sb, | 541 | static struct dentry *get_default_root(struct super_block *sb, |
542 | u64 subvol_objectid) | 542 | u64 subvol_objectid) |
543 | { | 543 | { |
544 | struct btrfs_root *root = sb->s_fs_info; | 544 | struct btrfs_fs_info *fs_info = btrfs_sb(sb); |
545 | struct btrfs_root *root = fs_info->tree_root; | ||
545 | struct btrfs_root *new_root; | 546 | struct btrfs_root *new_root; |
546 | struct btrfs_dir_item *di; | 547 | struct btrfs_dir_item *di; |
547 | struct btrfs_path *path; | 548 | struct btrfs_path *path; |
@@ -571,7 +572,7 @@ static struct dentry *get_default_root(struct super_block *sb, | |||
571 | * will mount by default if we haven't been given a specific subvolume | 572 | * will mount by default if we haven't been given a specific subvolume |
572 | * to mount. | 573 | * to mount. |
573 | */ | 574 | */ |
574 | dir_id = btrfs_super_root_dir(root->fs_info->super_copy); | 575 | dir_id = btrfs_super_root_dir(fs_info->super_copy); |
575 | di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0); | 576 | di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0); |
576 | if (IS_ERR(di)) { | 577 | if (IS_ERR(di)) { |
577 | btrfs_free_path(path); | 578 | btrfs_free_path(path); |
@@ -585,7 +586,7 @@ static struct dentry *get_default_root(struct super_block *sb, | |||
585 | */ | 586 | */ |
586 | btrfs_free_path(path); | 587 | btrfs_free_path(path); |
587 | dir_id = BTRFS_FIRST_FREE_OBJECTID; | 588 | dir_id = BTRFS_FIRST_FREE_OBJECTID; |
588 | new_root = root->fs_info->fs_root; | 589 | new_root = fs_info->fs_root; |
589 | goto setup_root; | 590 | goto setup_root; |
590 | } | 591 | } |
591 | 592 | ||
@@ -593,7 +594,7 @@ static struct dentry *get_default_root(struct super_block *sb, | |||
593 | btrfs_free_path(path); | 594 | btrfs_free_path(path); |
594 | 595 | ||
595 | find_root: | 596 | find_root: |
596 | new_root = btrfs_read_fs_root_no_name(root->fs_info, &location); | 597 | new_root = btrfs_read_fs_root_no_name(fs_info, &location); |
597 | if (IS_ERR(new_root)) | 598 | if (IS_ERR(new_root)) |
598 | return ERR_CAST(new_root); | 599 | return ERR_CAST(new_root); |
599 | 600 | ||
@@ -629,7 +630,7 @@ static int btrfs_fill_super(struct super_block *sb, | |||
629 | { | 630 | { |
630 | struct inode *inode; | 631 | struct inode *inode; |
631 | struct dentry *root_dentry; | 632 | struct dentry *root_dentry; |
632 | struct btrfs_root *tree_root; | 633 | struct btrfs_fs_info *fs_info = btrfs_sb(sb); |
633 | struct btrfs_key key; | 634 | struct btrfs_key key; |
634 | int err; | 635 | int err; |
635 | 636 | ||
@@ -644,18 +645,16 @@ static int btrfs_fill_super(struct super_block *sb, | |||
644 | sb->s_flags |= MS_POSIXACL; | 645 | sb->s_flags |= MS_POSIXACL; |
645 | #endif | 646 | #endif |
646 | 647 | ||
647 | tree_root = open_ctree(sb, fs_devices, (char *)data); | 648 | err = open_ctree(sb, fs_devices, (char *)data); |
648 | 649 | if (err) { | |
649 | if (IS_ERR(tree_root)) { | ||
650 | printk("btrfs: open_ctree failed\n"); | 650 | printk("btrfs: open_ctree failed\n"); |
651 | return PTR_ERR(tree_root); | 651 | return err; |
652 | } | 652 | } |
653 | sb->s_fs_info = tree_root; | ||
654 | 653 | ||
655 | key.objectid = BTRFS_FIRST_FREE_OBJECTID; | 654 | key.objectid = BTRFS_FIRST_FREE_OBJECTID; |
656 | key.type = BTRFS_INODE_ITEM_KEY; | 655 | key.type = BTRFS_INODE_ITEM_KEY; |
657 | key.offset = 0; | 656 | key.offset = 0; |
658 | inode = btrfs_iget(sb, &key, tree_root->fs_info->fs_root, NULL); | 657 | inode = btrfs_iget(sb, &key, fs_info->fs_root, NULL); |
659 | if (IS_ERR(inode)) { | 658 | if (IS_ERR(inode)) { |
660 | err = PTR_ERR(inode); | 659 | err = PTR_ERR(inode); |
661 | goto fail_close; | 660 | goto fail_close; |
@@ -672,23 +671,25 @@ static int btrfs_fill_super(struct super_block *sb, | |||
672 | 671 | ||
673 | save_mount_options(sb, data); | 672 | save_mount_options(sb, data); |
674 | cleancache_init_fs(sb); | 673 | cleancache_init_fs(sb); |
674 | sb->s_flags |= MS_ACTIVE; | ||
675 | return 0; | 675 | return 0; |
676 | 676 | ||
677 | fail_close: | 677 | fail_close: |
678 | close_ctree(tree_root); | 678 | close_ctree(fs_info->tree_root); |
679 | return err; | 679 | return err; |
680 | } | 680 | } |
681 | 681 | ||
682 | int btrfs_sync_fs(struct super_block *sb, int wait) | 682 | int btrfs_sync_fs(struct super_block *sb, int wait) |
683 | { | 683 | { |
684 | struct btrfs_trans_handle *trans; | 684 | struct btrfs_trans_handle *trans; |
685 | struct btrfs_root *root = btrfs_sb(sb); | 685 | struct btrfs_fs_info *fs_info = btrfs_sb(sb); |
686 | struct btrfs_root *root = fs_info->tree_root; | ||
686 | int ret; | 687 | int ret; |
687 | 688 | ||
688 | trace_btrfs_sync_fs(wait); | 689 | trace_btrfs_sync_fs(wait); |
689 | 690 | ||
690 | if (!wait) { | 691 | if (!wait) { |
691 | filemap_flush(root->fs_info->btree_inode->i_mapping); | 692 | filemap_flush(fs_info->btree_inode->i_mapping); |
692 | return 0; | 693 | return 0; |
693 | } | 694 | } |
694 | 695 | ||
@@ -704,8 +705,8 @@ int btrfs_sync_fs(struct super_block *sb, int wait) | |||
704 | 705 | ||
705 | static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry) | 706 | static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry) |
706 | { | 707 | { |
707 | struct btrfs_root *root = btrfs_sb(dentry->d_sb); | 708 | struct btrfs_fs_info *info = btrfs_sb(dentry->d_sb); |
708 | struct btrfs_fs_info *info = root->fs_info; | 709 | struct btrfs_root *root = info->tree_root; |
709 | char *compress_type; | 710 | char *compress_type; |
710 | 711 | ||
711 | if (btrfs_test_opt(root, DEGRADED)) | 712 | if (btrfs_test_opt(root, DEGRADED)) |
@@ -770,23 +771,18 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry) | |||
770 | 771 | ||
771 | static int btrfs_test_super(struct super_block *s, void *data) | 772 | static int btrfs_test_super(struct super_block *s, void *data) |
772 | { | 773 | { |
773 | struct btrfs_root *test_root = data; | 774 | struct btrfs_fs_info *p = data; |
774 | struct btrfs_root *root = btrfs_sb(s); | 775 | struct btrfs_fs_info *fs_info = btrfs_sb(s); |
775 | 776 | ||
776 | /* | 777 | return fs_info->fs_devices == p->fs_devices; |
777 | * If this super block is going away, return false as it | ||
778 | * can't match as an existing super block. | ||
779 | */ | ||
780 | if (!atomic_read(&s->s_active)) | ||
781 | return 0; | ||
782 | return root->fs_info->fs_devices == test_root->fs_info->fs_devices; | ||
783 | } | 778 | } |
784 | 779 | ||
785 | static int btrfs_set_super(struct super_block *s, void *data) | 780 | static int btrfs_set_super(struct super_block *s, void *data) |
786 | { | 781 | { |
787 | s->s_fs_info = data; | 782 | int err = set_anon_super(s, data); |
788 | 783 | if (!err) | |
789 | return set_anon_super(s, data); | 784 | s->s_fs_info = data; |
785 | return err; | ||
790 | } | 786 | } |
791 | 787 | ||
792 | /* | 788 | /* |
@@ -946,12 +942,6 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
946 | if (!fs_info) | 942 | if (!fs_info) |
947 | return ERR_PTR(-ENOMEM); | 943 | return ERR_PTR(-ENOMEM); |
948 | 944 | ||
949 | fs_info->tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS); | ||
950 | if (!fs_info->tree_root) { | ||
951 | error = -ENOMEM; | ||
952 | goto error_fs_info; | ||
953 | } | ||
954 | fs_info->tree_root->fs_info = fs_info; | ||
955 | fs_info->fs_devices = fs_devices; | 945 | fs_info->fs_devices = fs_devices; |
956 | 946 | ||
957 | fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS); | 947 | fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS); |
@@ -971,43 +961,30 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
971 | } | 961 | } |
972 | 962 | ||
973 | bdev = fs_devices->latest_bdev; | 963 | bdev = fs_devices->latest_bdev; |
974 | s = sget(fs_type, btrfs_test_super, btrfs_set_super, | 964 | s = sget(fs_type, btrfs_test_super, btrfs_set_super, fs_info); |
975 | fs_info->tree_root); | ||
976 | if (IS_ERR(s)) { | 965 | if (IS_ERR(s)) { |
977 | error = PTR_ERR(s); | 966 | error = PTR_ERR(s); |
978 | goto error_close_devices; | 967 | goto error_close_devices; |
979 | } | 968 | } |
980 | 969 | ||
981 | if (s->s_root) { | 970 | if (s->s_root) { |
982 | if ((flags ^ s->s_flags) & MS_RDONLY) { | ||
983 | deactivate_locked_super(s); | ||
984 | error = -EBUSY; | ||
985 | goto error_close_devices; | ||
986 | } | ||
987 | |||
988 | btrfs_close_devices(fs_devices); | 971 | btrfs_close_devices(fs_devices); |
989 | free_fs_info(fs_info); | 972 | free_fs_info(fs_info); |
973 | if ((flags ^ s->s_flags) & MS_RDONLY) | ||
974 | error = -EBUSY; | ||
990 | } else { | 975 | } else { |
991 | char b[BDEVNAME_SIZE]; | 976 | char b[BDEVNAME_SIZE]; |
992 | 977 | ||
993 | s->s_flags = flags | MS_NOSEC; | 978 | s->s_flags = flags | MS_NOSEC; |
994 | strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); | 979 | strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); |
995 | btrfs_sb(s)->fs_info->bdev_holder = fs_type; | 980 | btrfs_sb(s)->bdev_holder = fs_type; |
996 | error = btrfs_fill_super(s, fs_devices, data, | 981 | error = btrfs_fill_super(s, fs_devices, data, |
997 | flags & MS_SILENT ? 1 : 0); | 982 | flags & MS_SILENT ? 1 : 0); |
998 | if (error) { | ||
999 | deactivate_locked_super(s); | ||
1000 | return ERR_PTR(error); | ||
1001 | } | ||
1002 | |||
1003 | s->s_flags |= MS_ACTIVE; | ||
1004 | } | 983 | } |
1005 | 984 | ||
1006 | root = get_default_root(s, subvol_objectid); | 985 | root = !error ? get_default_root(s, subvol_objectid) : ERR_PTR(error); |
1007 | if (IS_ERR(root)) { | 986 | if (IS_ERR(root)) |
1008 | deactivate_locked_super(s); | 987 | deactivate_locked_super(s); |
1009 | return root; | ||
1010 | } | ||
1011 | 988 | ||
1012 | return root; | 989 | return root; |
1013 | 990 | ||
@@ -1020,7 +997,8 @@ error_fs_info: | |||
1020 | 997 | ||
1021 | static int btrfs_remount(struct super_block *sb, int *flags, char *data) | 998 | static int btrfs_remount(struct super_block *sb, int *flags, char *data) |
1022 | { | 999 | { |
1023 | struct btrfs_root *root = btrfs_sb(sb); | 1000 | struct btrfs_fs_info *fs_info = btrfs_sb(sb); |
1001 | struct btrfs_root *root = fs_info->tree_root; | ||
1024 | int ret; | 1002 | int ret; |
1025 | 1003 | ||
1026 | ret = btrfs_parse_options(root, data); | 1004 | ret = btrfs_parse_options(root, data); |
@@ -1036,13 +1014,13 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) | |||
1036 | ret = btrfs_commit_super(root); | 1014 | ret = btrfs_commit_super(root); |
1037 | WARN_ON(ret); | 1015 | WARN_ON(ret); |
1038 | } else { | 1016 | } else { |
1039 | if (root->fs_info->fs_devices->rw_devices == 0) | 1017 | if (fs_info->fs_devices->rw_devices == 0) |
1040 | return -EACCES; | 1018 | return -EACCES; |
1041 | 1019 | ||
1042 | if (btrfs_super_log_root(root->fs_info->super_copy) != 0) | 1020 | if (btrfs_super_log_root(fs_info->super_copy) != 0) |
1043 | return -EINVAL; | 1021 | return -EINVAL; |
1044 | 1022 | ||
1045 | ret = btrfs_cleanup_fs_roots(root->fs_info); | 1023 | ret = btrfs_cleanup_fs_roots(fs_info); |
1046 | WARN_ON(ret); | 1024 | WARN_ON(ret); |
1047 | 1025 | ||
1048 | /* recover relocation */ | 1026 | /* recover relocation */ |
@@ -1211,18 +1189,18 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes) | |||
1211 | 1189 | ||
1212 | static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) | 1190 | static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) |
1213 | { | 1191 | { |
1214 | struct btrfs_root *root = btrfs_sb(dentry->d_sb); | 1192 | struct btrfs_fs_info *fs_info = btrfs_sb(dentry->d_sb); |
1215 | struct btrfs_super_block *disk_super = root->fs_info->super_copy; | 1193 | struct btrfs_super_block *disk_super = fs_info->super_copy; |
1216 | struct list_head *head = &root->fs_info->space_info; | 1194 | struct list_head *head = &fs_info->space_info; |
1217 | struct btrfs_space_info *found; | 1195 | struct btrfs_space_info *found; |
1218 | u64 total_used = 0; | 1196 | u64 total_used = 0; |
1219 | u64 total_free_data = 0; | 1197 | u64 total_free_data = 0; |
1220 | int bits = dentry->d_sb->s_blocksize_bits; | 1198 | int bits = dentry->d_sb->s_blocksize_bits; |
1221 | __be32 *fsid = (__be32 *)root->fs_info->fsid; | 1199 | __be32 *fsid = (__be32 *)fs_info->fsid; |
1222 | int ret; | 1200 | int ret; |
1223 | 1201 | ||
1224 | /* holding chunk_muext to avoid allocating new chunks */ | 1202 | /* holding chunk_muext to avoid allocating new chunks */ |
1225 | mutex_lock(&root->fs_info->chunk_mutex); | 1203 | mutex_lock(&fs_info->chunk_mutex); |
1226 | rcu_read_lock(); | 1204 | rcu_read_lock(); |
1227 | list_for_each_entry_rcu(found, head, list) { | 1205 | list_for_each_entry_rcu(found, head, list) { |
1228 | if (found->flags & BTRFS_BLOCK_GROUP_DATA) { | 1206 | if (found->flags & BTRFS_BLOCK_GROUP_DATA) { |
@@ -1241,14 +1219,14 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
1241 | buf->f_bsize = dentry->d_sb->s_blocksize; | 1219 | buf->f_bsize = dentry->d_sb->s_blocksize; |
1242 | buf->f_type = BTRFS_SUPER_MAGIC; | 1220 | buf->f_type = BTRFS_SUPER_MAGIC; |
1243 | buf->f_bavail = total_free_data; | 1221 | buf->f_bavail = total_free_data; |
1244 | ret = btrfs_calc_avail_data_space(root, &total_free_data); | 1222 | ret = btrfs_calc_avail_data_space(fs_info->tree_root, &total_free_data); |
1245 | if (ret) { | 1223 | if (ret) { |
1246 | mutex_unlock(&root->fs_info->chunk_mutex); | 1224 | mutex_unlock(&fs_info->chunk_mutex); |
1247 | return ret; | 1225 | return ret; |
1248 | } | 1226 | } |
1249 | buf->f_bavail += total_free_data; | 1227 | buf->f_bavail += total_free_data; |
1250 | buf->f_bavail = buf->f_bavail >> bits; | 1228 | buf->f_bavail = buf->f_bavail >> bits; |
1251 | mutex_unlock(&root->fs_info->chunk_mutex); | 1229 | mutex_unlock(&fs_info->chunk_mutex); |
1252 | 1230 | ||
1253 | /* We treat it as constant endianness (it doesn't matter _which_) | 1231 | /* We treat it as constant endianness (it doesn't matter _which_) |
1254 | because we want the fsid to come out the same whether mounted | 1232 | because we want the fsid to come out the same whether mounted |
@@ -1262,11 +1240,18 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
1262 | return 0; | 1240 | return 0; |
1263 | } | 1241 | } |
1264 | 1242 | ||
1243 | static void btrfs_kill_super(struct super_block *sb) | ||
1244 | { | ||
1245 | struct btrfs_fs_info *fs_info = btrfs_sb(sb); | ||
1246 | kill_anon_super(sb); | ||
1247 | free_fs_info(fs_info); | ||
1248 | } | ||
1249 | |||
1265 | static struct file_system_type btrfs_fs_type = { | 1250 | static struct file_system_type btrfs_fs_type = { |
1266 | .owner = THIS_MODULE, | 1251 | .owner = THIS_MODULE, |
1267 | .name = "btrfs", | 1252 | .name = "btrfs", |
1268 | .mount = btrfs_mount, | 1253 | .mount = btrfs_mount, |
1269 | .kill_sb = kill_anon_super, | 1254 | .kill_sb = btrfs_kill_super, |
1270 | .fs_flags = FS_REQUIRES_DEV, | 1255 | .fs_flags = FS_REQUIRES_DEV, |
1271 | }; | 1256 | }; |
1272 | 1257 | ||
@@ -1300,17 +1285,17 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd, | |||
1300 | 1285 | ||
1301 | static int btrfs_freeze(struct super_block *sb) | 1286 | static int btrfs_freeze(struct super_block *sb) |
1302 | { | 1287 | { |
1303 | struct btrfs_root *root = btrfs_sb(sb); | 1288 | struct btrfs_fs_info *fs_info = btrfs_sb(sb); |
1304 | mutex_lock(&root->fs_info->transaction_kthread_mutex); | 1289 | mutex_lock(&fs_info->transaction_kthread_mutex); |
1305 | mutex_lock(&root->fs_info->cleaner_mutex); | 1290 | mutex_lock(&fs_info->cleaner_mutex); |
1306 | return 0; | 1291 | return 0; |
1307 | } | 1292 | } |
1308 | 1293 | ||
1309 | static int btrfs_unfreeze(struct super_block *sb) | 1294 | static int btrfs_unfreeze(struct super_block *sb) |
1310 | { | 1295 | { |
1311 | struct btrfs_root *root = btrfs_sb(sb); | 1296 | struct btrfs_fs_info *fs_info = btrfs_sb(sb); |
1312 | mutex_unlock(&root->fs_info->cleaner_mutex); | 1297 | mutex_unlock(&fs_info->cleaner_mutex); |
1313 | mutex_unlock(&root->fs_info->transaction_kthread_mutex); | 1298 | mutex_unlock(&fs_info->transaction_kthread_mutex); |
1314 | return 0; | 1299 | return 0; |
1315 | } | 1300 | } |
1316 | 1301 | ||
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 7ffdb154daec..0b4e2af7954d 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -708,8 +708,6 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder, | |||
708 | u64 devid; | 708 | u64 devid; |
709 | u64 transid; | 709 | u64 transid; |
710 | 710 | ||
711 | mutex_lock(&uuid_mutex); | ||
712 | |||
713 | flags |= FMODE_EXCL; | 711 | flags |= FMODE_EXCL; |
714 | bdev = blkdev_get_by_path(path, flags, holder); | 712 | bdev = blkdev_get_by_path(path, flags, holder); |
715 | 713 | ||
@@ -718,6 +716,7 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder, | |||
718 | goto error; | 716 | goto error; |
719 | } | 717 | } |
720 | 718 | ||
719 | mutex_lock(&uuid_mutex); | ||
721 | ret = set_blocksize(bdev, 4096); | 720 | ret = set_blocksize(bdev, 4096); |
722 | if (ret) | 721 | if (ret) |
723 | goto error_close; | 722 | goto error_close; |
@@ -739,9 +738,9 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder, | |||
739 | 738 | ||
740 | brelse(bh); | 739 | brelse(bh); |
741 | error_close: | 740 | error_close: |
741 | mutex_unlock(&uuid_mutex); | ||
742 | blkdev_put(bdev, flags); | 742 | blkdev_put(bdev, flags); |
743 | error: | 743 | error: |
744 | mutex_unlock(&uuid_mutex); | ||
745 | return ret; | 744 | return ret; |
746 | } | 745 | } |
747 | 746 | ||