diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-06-09 09:22:25 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-06-09 09:22:25 -0400 |
commit | 0cf6c620176a294bdf1bedddc492f6ae857e0019 (patch) | |
tree | 44d3a6cb53a966bce73db711dbcf031b89388e11 /fs/btrfs | |
parent | ad693af684757478e5fcb225aef319cab7ba6c75 (diff) |
Btrfs: remove device tree
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/ctree.h | 105 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 224 | ||||
-rw-r--r-- | fs/btrfs/super.c | 88 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 6 |
4 files changed, 10 insertions, 413 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index e93ba1a5c812..5ab25a0cb16a 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -16,11 +16,10 @@ extern struct kmem_cache *btrfs_path_cachep; | |||
16 | #define BTRFS_MAGIC "_BtRfS_M" | 16 | #define BTRFS_MAGIC "_BtRfS_M" |
17 | 17 | ||
18 | #define BTRFS_ROOT_TREE_OBJECTID 1ULL | 18 | #define BTRFS_ROOT_TREE_OBJECTID 1ULL |
19 | #define BTRFS_DEV_TREE_OBJECTID 2ULL | 19 | #define BTRFS_EXTENT_TREE_OBJECTID 2ULL |
20 | #define BTRFS_EXTENT_TREE_OBJECTID 3ULL | 20 | #define BTRFS_FS_TREE_OBJECTID 3ULL |
21 | #define BTRFS_FS_TREE_OBJECTID 4ULL | 21 | #define BTRFS_ROOT_TREE_DIR_OBJECTID 4ULL |
22 | #define BTRFS_ROOT_TREE_DIR_OBJECTID 5ULL | 22 | #define BTRFS_FIRST_FREE_OBJECTID 5ULL |
23 | #define BTRFS_FIRST_FREE_OBJECTID 6ULL | ||
24 | 23 | ||
25 | /* | 24 | /* |
26 | * we can actually store much bigger names, but lets not confuse the rest | 25 | * we can actually store much bigger names, but lets not confuse the rest |
@@ -111,12 +110,6 @@ struct btrfs_super_block { | |||
111 | __le64 total_blocks; | 110 | __le64 total_blocks; |
112 | __le64 blocks_used; | 111 | __le64 blocks_used; |
113 | __le64 root_dir_objectid; | 112 | __le64 root_dir_objectid; |
114 | __le64 last_device_id; | ||
115 | /* fields below here vary with the underlying disk */ | ||
116 | __le64 device_block_start; | ||
117 | __le64 device_num_blocks; | ||
118 | __le64 device_root; | ||
119 | __le64 device_id; | ||
120 | } __attribute__ ((__packed__)); | 113 | } __attribute__ ((__packed__)); |
121 | 114 | ||
122 | /* | 115 | /* |
@@ -251,11 +244,6 @@ struct btrfs_csum_item { | |||
251 | u8 csum; | 244 | u8 csum; |
252 | } __attribute__ ((__packed__)); | 245 | } __attribute__ ((__packed__)); |
253 | 246 | ||
254 | struct btrfs_device_item { | ||
255 | __le16 pathlen; | ||
256 | __le64 device_id; | ||
257 | } __attribute__ ((__packed__)); | ||
258 | |||
259 | /* tag for the radix tree of block groups in ram */ | 247 | /* tag for the radix tree of block groups in ram */ |
260 | #define BTRFS_BLOCK_GROUP_DIRTY 0 | 248 | #define BTRFS_BLOCK_GROUP_DIRTY 0 |
261 | #define BTRFS_BLOCK_GROUP_AVAIL 1 | 249 | #define BTRFS_BLOCK_GROUP_AVAIL 1 |
@@ -286,11 +274,9 @@ struct btrfs_fs_info { | |||
286 | spinlock_t hash_lock; | 274 | spinlock_t hash_lock; |
287 | struct btrfs_root *extent_root; | 275 | struct btrfs_root *extent_root; |
288 | struct btrfs_root *tree_root; | 276 | struct btrfs_root *tree_root; |
289 | struct btrfs_root *dev_root; | ||
290 | struct radix_tree_root fs_roots_radix; | 277 | struct radix_tree_root fs_roots_radix; |
291 | struct radix_tree_root pending_del_radix; | 278 | struct radix_tree_root pending_del_radix; |
292 | struct radix_tree_root pinned_radix; | 279 | struct radix_tree_root pinned_radix; |
293 | struct radix_tree_root dev_radix; | ||
294 | struct radix_tree_root block_group_radix; | 280 | struct radix_tree_root block_group_radix; |
295 | struct radix_tree_root block_group_data_radix; | 281 | struct radix_tree_root block_group_data_radix; |
296 | struct radix_tree_root extent_map_radix; | 282 | struct radix_tree_root extent_map_radix; |
@@ -386,11 +372,6 @@ struct btrfs_root { | |||
386 | #define BTRFS_BLOCK_GROUP_ITEM_KEY 34 | 372 | #define BTRFS_BLOCK_GROUP_ITEM_KEY 34 |
387 | 373 | ||
388 | /* | 374 | /* |
389 | * dev items list the devices that make up the FS | ||
390 | */ | ||
391 | #define BTRFS_DEV_ITEM_KEY 35 | ||
392 | |||
393 | /* | ||
394 | * string items are for debugging. They just store a short string of | 375 | * string items are for debugging. They just store a short string of |
395 | * data in the FS | 376 | * data in the FS |
396 | */ | 377 | */ |
@@ -880,62 +861,6 @@ static inline void btrfs_set_super_root_dir(struct btrfs_super_block *s, u64 | |||
880 | s->root_dir_objectid = cpu_to_le64(val); | 861 | s->root_dir_objectid = cpu_to_le64(val); |
881 | } | 862 | } |
882 | 863 | ||
883 | static inline u64 btrfs_super_last_device_id(struct btrfs_super_block *s) | ||
884 | { | ||
885 | return le64_to_cpu(s->last_device_id); | ||
886 | } | ||
887 | |||
888 | static inline void btrfs_set_super_last_device_id(struct btrfs_super_block *s, | ||
889 | u64 val) | ||
890 | { | ||
891 | s->last_device_id = cpu_to_le64(val); | ||
892 | } | ||
893 | |||
894 | static inline u64 btrfs_super_device_id(struct btrfs_super_block *s) | ||
895 | { | ||
896 | return le64_to_cpu(s->device_id); | ||
897 | } | ||
898 | |||
899 | static inline void btrfs_set_super_device_id(struct btrfs_super_block *s, | ||
900 | u64 val) | ||
901 | { | ||
902 | s->device_id = cpu_to_le64(val); | ||
903 | } | ||
904 | |||
905 | static inline u64 btrfs_super_device_block_start(struct btrfs_super_block *s) | ||
906 | { | ||
907 | return le64_to_cpu(s->device_block_start); | ||
908 | } | ||
909 | |||
910 | static inline void btrfs_set_super_device_block_start(struct btrfs_super_block | ||
911 | *s, u64 val) | ||
912 | { | ||
913 | s->device_block_start = cpu_to_le64(val); | ||
914 | } | ||
915 | |||
916 | static inline u64 btrfs_super_device_num_blocks(struct btrfs_super_block *s) | ||
917 | { | ||
918 | return le64_to_cpu(s->device_num_blocks); | ||
919 | } | ||
920 | |||
921 | static inline void btrfs_set_super_device_num_blocks(struct btrfs_super_block | ||
922 | *s, u64 val) | ||
923 | { | ||
924 | s->device_num_blocks = cpu_to_le64(val); | ||
925 | } | ||
926 | |||
927 | static inline u64 btrfs_super_device_root(struct btrfs_super_block *s) | ||
928 | { | ||
929 | return le64_to_cpu(s->device_root); | ||
930 | } | ||
931 | |||
932 | static inline void btrfs_set_super_device_root(struct btrfs_super_block | ||
933 | *s, u64 val) | ||
934 | { | ||
935 | s->device_root = cpu_to_le64(val); | ||
936 | } | ||
937 | |||
938 | |||
939 | static inline u8 *btrfs_leaf_data(struct btrfs_leaf *l) | 864 | static inline u8 *btrfs_leaf_data(struct btrfs_leaf *l) |
940 | { | 865 | { |
941 | return (u8 *)l->items; | 866 | return (u8 *)l->items; |
@@ -1031,28 +956,6 @@ static inline void btrfs_set_file_extent_num_blocks(struct | |||
1031 | e->num_blocks = cpu_to_le64(val); | 956 | e->num_blocks = cpu_to_le64(val); |
1032 | } | 957 | } |
1033 | 958 | ||
1034 | static inline u16 btrfs_device_pathlen(struct btrfs_device_item *d) | ||
1035 | { | ||
1036 | return le16_to_cpu(d->pathlen); | ||
1037 | } | ||
1038 | |||
1039 | static inline void btrfs_set_device_pathlen(struct btrfs_device_item *d, | ||
1040 | u16 val) | ||
1041 | { | ||
1042 | d->pathlen = cpu_to_le16(val); | ||
1043 | } | ||
1044 | |||
1045 | static inline u64 btrfs_device_id(struct btrfs_device_item *d) | ||
1046 | { | ||
1047 | return le64_to_cpu(d->device_id); | ||
1048 | } | ||
1049 | |||
1050 | static inline void btrfs_set_device_id(struct btrfs_device_item *d, | ||
1051 | u64 val) | ||
1052 | { | ||
1053 | d->device_id = cpu_to_le64(val); | ||
1054 | } | ||
1055 | |||
1056 | static inline struct btrfs_root *btrfs_sb(struct super_block *sb) | 959 | static inline struct btrfs_root *btrfs_sb(struct super_block *sb) |
1057 | { | 960 | { |
1058 | return sb->s_fs_info; | 961 | return sb->s_fs_info; |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 751069c0e9f5..8a88404525e8 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -11,47 +11,9 @@ | |||
11 | #include "transaction.h" | 11 | #include "transaction.h" |
12 | #include "btrfs_inode.h" | 12 | #include "btrfs_inode.h" |
13 | 13 | ||
14 | struct dev_lookup { | ||
15 | u64 block_start; | ||
16 | u64 num_blocks; | ||
17 | u64 device_id; | ||
18 | struct block_device *bdev; | ||
19 | }; | ||
20 | |||
21 | int btrfs_insert_dev_radix(struct btrfs_root *root, | ||
22 | struct block_device *bdev, | ||
23 | u64 device_id, | ||
24 | u64 block_start, | ||
25 | u64 num_blocks) | ||
26 | { | ||
27 | struct dev_lookup *lookup; | ||
28 | int ret; | ||
29 | |||
30 | lookup = kmalloc(sizeof(*lookup), GFP_NOFS); | ||
31 | if (!lookup) | ||
32 | return -ENOMEM; | ||
33 | lookup->block_start = block_start; | ||
34 | lookup->num_blocks = num_blocks; | ||
35 | lookup->bdev = bdev; | ||
36 | lookup->device_id = device_id; | ||
37 | |||
38 | ret = radix_tree_insert(&root->fs_info->dev_radix, block_start + | ||
39 | num_blocks - 1, lookup); | ||
40 | return ret; | ||
41 | } | ||
42 | |||
43 | u64 bh_blocknr(struct buffer_head *bh) | 14 | u64 bh_blocknr(struct buffer_head *bh) |
44 | { | 15 | { |
45 | int blkbits = bh->b_page->mapping->host->i_blkbits; | 16 | return bh->b_blocknr; |
46 | u64 blocknr = bh->b_page->index << (PAGE_CACHE_SHIFT - blkbits); | ||
47 | unsigned long offset; | ||
48 | |||
49 | if (PageHighMem(bh->b_page)) | ||
50 | offset = (unsigned long)bh->b_data; | ||
51 | else | ||
52 | offset = bh->b_data - (char *)page_address(bh->b_page); | ||
53 | blocknr += offset >> (PAGE_CACHE_SHIFT - blkbits); | ||
54 | return blocknr; | ||
55 | } | 17 | } |
56 | 18 | ||
57 | static int check_tree_block(struct btrfs_root *root, struct buffer_head *buf) | 19 | static int check_tree_block(struct btrfs_root *root, struct buffer_head *buf) |
@@ -102,32 +64,14 @@ out_unlock: | |||
102 | int btrfs_map_bh_to_logical(struct btrfs_root *root, struct buffer_head *bh, | 64 | int btrfs_map_bh_to_logical(struct btrfs_root *root, struct buffer_head *bh, |
103 | u64 logical) | 65 | u64 logical) |
104 | { | 66 | { |
105 | struct dev_lookup *lookup[2]; | ||
106 | |||
107 | int ret; | ||
108 | |||
109 | if (logical == 0) { | 67 | if (logical == 0) { |
110 | bh->b_bdev = NULL; | 68 | bh->b_bdev = NULL; |
111 | bh->b_blocknr = 0; | 69 | bh->b_blocknr = 0; |
112 | set_buffer_mapped(bh); | 70 | set_buffer_mapped(bh); |
113 | return 0; | 71 | } else { |
114 | } | 72 | map_bh(bh, root->fs_info->sb, logical); |
115 | root = root->fs_info->dev_root; | ||
116 | ret = radix_tree_gang_lookup(&root->fs_info->dev_radix, | ||
117 | (void **)lookup, | ||
118 | (unsigned long)logical, | ||
119 | ARRAY_SIZE(lookup)); | ||
120 | if (ret == 0 || lookup[0]->block_start > logical || | ||
121 | lookup[0]->block_start + lookup[0]->num_blocks <= logical) { | ||
122 | ret = -ENOENT; | ||
123 | goto out; | ||
124 | } | 73 | } |
125 | bh->b_bdev = lookup[0]->bdev; | 74 | return 0; |
126 | bh->b_blocknr = logical - lookup[0]->block_start; | ||
127 | set_buffer_mapped(bh); | ||
128 | ret = 0; | ||
129 | out: | ||
130 | return ret; | ||
131 | } | 75 | } |
132 | 76 | ||
133 | struct buffer_head *btrfs_find_create_tree_block(struct btrfs_root *root, | 77 | struct buffer_head *btrfs_find_create_tree_block(struct btrfs_root *root, |
@@ -382,24 +326,18 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info, | |||
382 | u64 highest_inode; | 326 | u64 highest_inode; |
383 | int ret = 0; | 327 | int ret = 0; |
384 | 328 | ||
385 | printk("read_fs_root looking for %Lu %Lu %u\n", location->objectid, location->offset, location->flags); | ||
386 | root = radix_tree_lookup(&fs_info->fs_roots_radix, | 329 | root = radix_tree_lookup(&fs_info->fs_roots_radix, |
387 | (unsigned long)location->objectid); | 330 | (unsigned long)location->objectid); |
388 | if (root) { | 331 | if (root) |
389 | printk("found %p in cache\n", root); | ||
390 | return root; | 332 | return root; |
391 | } | ||
392 | root = kmalloc(sizeof(*root), GFP_NOFS); | 333 | root = kmalloc(sizeof(*root), GFP_NOFS); |
393 | if (!root) { | 334 | if (!root) |
394 | printk("failed1\n"); | ||
395 | return ERR_PTR(-ENOMEM); | 335 | return ERR_PTR(-ENOMEM); |
396 | } | ||
397 | if (location->offset == (u64)-1) { | 336 | if (location->offset == (u64)-1) { |
398 | ret = find_and_setup_root(fs_info->sb->s_blocksize, | 337 | ret = find_and_setup_root(fs_info->sb->s_blocksize, |
399 | fs_info->tree_root, fs_info, | 338 | fs_info->tree_root, fs_info, |
400 | location->objectid, root); | 339 | location->objectid, root); |
401 | if (ret) { | 340 | if (ret) { |
402 | printk("failed2\n"); | ||
403 | kfree(root); | 341 | kfree(root); |
404 | return ERR_PTR(ret); | 342 | return ERR_PTR(ret); |
405 | } | 343 | } |
@@ -413,7 +351,6 @@ printk("failed2\n"); | |||
413 | BUG_ON(!path); | 351 | BUG_ON(!path); |
414 | ret = btrfs_search_slot(NULL, tree_root, location, path, 0, 0); | 352 | ret = btrfs_search_slot(NULL, tree_root, location, path, 0, 0); |
415 | if (ret != 0) { | 353 | if (ret != 0) { |
416 | printk("internal search_slot gives us %d\n", ret); | ||
417 | if (ret > 0) | 354 | if (ret > 0) |
418 | ret = -ENOENT; | 355 | ret = -ENOENT; |
419 | goto out; | 356 | goto out; |
@@ -435,13 +372,11 @@ out: | |||
435 | btrfs_root_blocknr(&root->root_item)); | 372 | btrfs_root_blocknr(&root->root_item)); |
436 | BUG_ON(!root->node); | 373 | BUG_ON(!root->node); |
437 | insert: | 374 | insert: |
438 | printk("inserting %p\n", root); | ||
439 | root->ref_cows = 1; | 375 | root->ref_cows = 1; |
440 | ret = radix_tree_insert(&fs_info->fs_roots_radix, | 376 | ret = radix_tree_insert(&fs_info->fs_roots_radix, |
441 | (unsigned long)root->root_key.objectid, | 377 | (unsigned long)root->root_key.objectid, |
442 | root); | 378 | root); |
443 | if (ret) { | 379 | if (ret) { |
444 | printk("radix_tree_insert gives us %d\n", ret); | ||
445 | brelse(root->node); | 380 | brelse(root->node); |
446 | kfree(root); | 381 | kfree(root); |
447 | return ERR_PTR(ret); | 382 | return ERR_PTR(ret); |
@@ -450,116 +385,25 @@ printk("radix_tree_insert gives us %d\n", ret); | |||
450 | if (ret == 0) { | 385 | if (ret == 0) { |
451 | root->highest_inode = highest_inode; | 386 | root->highest_inode = highest_inode; |
452 | root->last_inode_alloc = highest_inode; | 387 | root->last_inode_alloc = highest_inode; |
453 | printk("highest inode is %Lu\n", highest_inode); | ||
454 | } | 388 | } |
455 | printk("all worked\n"); | ||
456 | return root; | 389 | return root; |
457 | } | 390 | } |
458 | 391 | ||
459 | static int btrfs_open_disk(struct btrfs_root *root, u64 device_id, | ||
460 | u64 block_start, u64 num_blocks, | ||
461 | char *filename, int name_len) | ||
462 | { | ||
463 | char *null_filename; | ||
464 | struct block_device *bdev; | ||
465 | int ret; | ||
466 | |||
467 | null_filename = kmalloc(name_len + 1, GFP_NOFS); | ||
468 | if (!null_filename) | ||
469 | return -ENOMEM; | ||
470 | memcpy(null_filename, filename, name_len); | ||
471 | null_filename[name_len] = '\0'; | ||
472 | |||
473 | bdev = open_bdev_excl(null_filename, O_RDWR, root->fs_info->sb); | ||
474 | if (IS_ERR(bdev)) { | ||
475 | ret = PTR_ERR(bdev); | ||
476 | goto out; | ||
477 | } | ||
478 | set_blocksize(bdev, root->fs_info->sb->s_blocksize); | ||
479 | ret = btrfs_insert_dev_radix(root, bdev, device_id, | ||
480 | block_start, num_blocks); | ||
481 | BUG_ON(ret); | ||
482 | ret = 0; | ||
483 | out: | ||
484 | kfree(null_filename); | ||
485 | return ret; | ||
486 | } | ||
487 | |||
488 | static int read_device_info(struct btrfs_root *root) | ||
489 | { | ||
490 | struct btrfs_path *path; | ||
491 | int ret; | ||
492 | struct btrfs_key key; | ||
493 | struct btrfs_leaf *leaf; | ||
494 | struct btrfs_device_item *dev_item; | ||
495 | int nritems; | ||
496 | int slot; | ||
497 | |||
498 | root = root->fs_info->dev_root; | ||
499 | |||
500 | path = btrfs_alloc_path(); | ||
501 | if (!path) | ||
502 | return -ENOMEM; | ||
503 | key.objectid = 0; | ||
504 | key.offset = 0; | ||
505 | key.flags = 0; | ||
506 | btrfs_set_key_type(&key, BTRFS_DEV_ITEM_KEY); | ||
507 | |||
508 | mutex_lock(&root->fs_info->fs_mutex); | ||
509 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | ||
510 | leaf = btrfs_buffer_leaf(path->nodes[0]); | ||
511 | nritems = btrfs_header_nritems(&leaf->header); | ||
512 | while(1) { | ||
513 | slot = path->slots[0]; | ||
514 | if (slot >= nritems) { | ||
515 | ret = btrfs_next_leaf(root, path); | ||
516 | if (ret) | ||
517 | break; | ||
518 | leaf = btrfs_buffer_leaf(path->nodes[0]); | ||
519 | nritems = btrfs_header_nritems(&leaf->header); | ||
520 | slot = path->slots[0]; | ||
521 | } | ||
522 | btrfs_disk_key_to_cpu(&key, &leaf->items[slot].key); | ||
523 | if (btrfs_key_type(&key) != BTRFS_DEV_ITEM_KEY) { | ||
524 | path->slots[0]++; | ||
525 | continue; | ||
526 | } | ||
527 | dev_item = btrfs_item_ptr(leaf, slot, struct btrfs_device_item); | ||
528 | printk("found key %Lu %Lu\n", key.objectid, key.offset); | ||
529 | if (btrfs_device_id(dev_item) != | ||
530 | btrfs_super_device_id(root->fs_info->disk_super)) { | ||
531 | ret = btrfs_open_disk(root, btrfs_device_id(dev_item), | ||
532 | key.objectid, key.offset, | ||
533 | (char *)(dev_item + 1), | ||
534 | btrfs_device_pathlen(dev_item)); | ||
535 | BUG_ON(ret); | ||
536 | } | ||
537 | path->slots[0]++; | ||
538 | } | ||
539 | btrfs_free_path(path); | ||
540 | mutex_unlock(&root->fs_info->fs_mutex); | ||
541 | return 0; | ||
542 | } | ||
543 | |||
544 | struct btrfs_root *open_ctree(struct super_block *sb) | 392 | struct btrfs_root *open_ctree(struct super_block *sb) |
545 | { | 393 | { |
546 | struct btrfs_root *extent_root = kmalloc(sizeof(struct btrfs_root), | 394 | struct btrfs_root *extent_root = kmalloc(sizeof(struct btrfs_root), |
547 | GFP_NOFS); | 395 | GFP_NOFS); |
548 | struct btrfs_root *dev_root = kmalloc(sizeof(struct btrfs_root), | ||
549 | GFP_NOFS); | ||
550 | struct btrfs_root *tree_root = kmalloc(sizeof(struct btrfs_root), | 396 | struct btrfs_root *tree_root = kmalloc(sizeof(struct btrfs_root), |
551 | GFP_NOFS); | 397 | GFP_NOFS); |
552 | struct btrfs_fs_info *fs_info = kmalloc(sizeof(*fs_info), | 398 | struct btrfs_fs_info *fs_info = kmalloc(sizeof(*fs_info), |
553 | GFP_NOFS); | 399 | GFP_NOFS); |
554 | int ret; | 400 | int ret; |
555 | struct btrfs_super_block *disk_super; | 401 | struct btrfs_super_block *disk_super; |
556 | struct dev_lookup *dev_lookup; | ||
557 | 402 | ||
558 | init_bit_radix(&fs_info->pinned_radix); | 403 | init_bit_radix(&fs_info->pinned_radix); |
559 | init_bit_radix(&fs_info->pending_del_radix); | 404 | init_bit_radix(&fs_info->pending_del_radix); |
560 | init_bit_radix(&fs_info->extent_map_radix); | 405 | init_bit_radix(&fs_info->extent_map_radix); |
561 | INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_NOFS); | 406 | INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_NOFS); |
562 | INIT_RADIX_TREE(&fs_info->dev_radix, GFP_NOFS); | ||
563 | INIT_RADIX_TREE(&fs_info->block_group_radix, GFP_KERNEL); | 407 | INIT_RADIX_TREE(&fs_info->block_group_radix, GFP_KERNEL); |
564 | INIT_RADIX_TREE(&fs_info->block_group_data_radix, GFP_KERNEL); | 408 | INIT_RADIX_TREE(&fs_info->block_group_data_radix, GFP_KERNEL); |
565 | INIT_LIST_HEAD(&fs_info->trans_list); | 409 | INIT_LIST_HEAD(&fs_info->trans_list); |
@@ -568,7 +412,6 @@ struct btrfs_root *open_ctree(struct super_block *sb) | |||
568 | fs_info->running_transaction = NULL; | 412 | fs_info->running_transaction = NULL; |
569 | fs_info->tree_root = tree_root; | 413 | fs_info->tree_root = tree_root; |
570 | fs_info->extent_root = extent_root; | 414 | fs_info->extent_root = extent_root; |
571 | fs_info->dev_root = dev_root; | ||
572 | fs_info->sb = sb; | 415 | fs_info->sb = sb; |
573 | fs_info->btree_inode = new_inode(sb); | 416 | fs_info->btree_inode = new_inode(sb); |
574 | fs_info->btree_inode->i_ino = 1; | 417 | fs_info->btree_inode->i_ino = 1; |
@@ -595,19 +438,9 @@ struct btrfs_root *open_ctree(struct super_block *sb) | |||
595 | mutex_init(&fs_info->trans_mutex); | 438 | mutex_init(&fs_info->trans_mutex); |
596 | mutex_init(&fs_info->fs_mutex); | 439 | mutex_init(&fs_info->fs_mutex); |
597 | 440 | ||
598 | __setup_root(sb->s_blocksize, dev_root, | ||
599 | fs_info, BTRFS_DEV_TREE_OBJECTID); | ||
600 | |||
601 | __setup_root(sb->s_blocksize, tree_root, | 441 | __setup_root(sb->s_blocksize, tree_root, |
602 | fs_info, BTRFS_ROOT_TREE_OBJECTID); | 442 | fs_info, BTRFS_ROOT_TREE_OBJECTID); |
603 | 443 | ||
604 | dev_lookup = kmalloc(sizeof(*dev_lookup), GFP_NOFS); | ||
605 | dev_lookup->block_start = 0; | ||
606 | dev_lookup->num_blocks = (u32)-2; | ||
607 | dev_lookup->bdev = sb->s_bdev; | ||
608 | dev_lookup->device_id = 0; | ||
609 | ret = radix_tree_insert(&fs_info->dev_radix, (u32)-2, dev_lookup); | ||
610 | BUG_ON(ret); | ||
611 | fs_info->sb_buffer = read_tree_block(tree_root, | 444 | fs_info->sb_buffer = read_tree_block(tree_root, |
612 | BTRFS_SUPER_INFO_OFFSET / | 445 | BTRFS_SUPER_INFO_OFFSET / |
613 | sb->s_blocksize); | 446 | sb->s_blocksize); |
@@ -622,24 +455,7 @@ struct btrfs_root *open_ctree(struct super_block *sb) | |||
622 | btrfs_super_total_blocks(disk_super) << | 455 | btrfs_super_total_blocks(disk_super) << |
623 | fs_info->btree_inode->i_blkbits); | 456 | fs_info->btree_inode->i_blkbits); |
624 | 457 | ||
625 | radix_tree_delete(&fs_info->dev_radix, (u32)-2); | ||
626 | dev_lookup->block_start = btrfs_super_device_block_start(disk_super); | ||
627 | dev_lookup->num_blocks = btrfs_super_device_num_blocks(disk_super); | ||
628 | dev_lookup->device_id = btrfs_super_device_id(disk_super); | ||
629 | |||
630 | ret = radix_tree_insert(&fs_info->dev_radix, | ||
631 | dev_lookup->block_start + | ||
632 | dev_lookup->num_blocks - 1, dev_lookup); | ||
633 | BUG_ON(ret); | ||
634 | |||
635 | fs_info->disk_super = disk_super; | 458 | fs_info->disk_super = disk_super; |
636 | |||
637 | dev_root->node = read_tree_block(tree_root, | ||
638 | btrfs_super_device_root(disk_super)); | ||
639 | |||
640 | ret = read_device_info(dev_root); | ||
641 | BUG_ON(ret); | ||
642 | |||
643 | tree_root->node = read_tree_block(tree_root, | 459 | tree_root->node = read_tree_block(tree_root, |
644 | btrfs_super_root(disk_super)); | 460 | btrfs_super_root(disk_super)); |
645 | BUG_ON(!tree_root->node); | 461 | BUG_ON(!tree_root->node); |
@@ -719,30 +535,6 @@ static int del_fs_roots(struct btrfs_fs_info *fs_info) | |||
719 | return 0; | 535 | return 0; |
720 | } | 536 | } |
721 | 537 | ||
722 | static int free_dev_radix(struct btrfs_fs_info *fs_info) | ||
723 | { | ||
724 | struct dev_lookup *lookup[8]; | ||
725 | struct block_device *super_bdev = fs_info->sb->s_bdev; | ||
726 | int ret; | ||
727 | int i; | ||
728 | while(1) { | ||
729 | ret = radix_tree_gang_lookup(&fs_info->dev_radix, | ||
730 | (void **)lookup, 0, | ||
731 | ARRAY_SIZE(lookup)); | ||
732 | if (!ret) | ||
733 | break; | ||
734 | for (i = 0; i < ret; i++) { | ||
735 | if (lookup[i]->bdev != super_bdev) | ||
736 | close_bdev_excl(lookup[i]->bdev); | ||
737 | radix_tree_delete(&fs_info->dev_radix, | ||
738 | lookup[i]->block_start + | ||
739 | lookup[i]->num_blocks - 1); | ||
740 | kfree(lookup[i]); | ||
741 | } | ||
742 | } | ||
743 | return 0; | ||
744 | } | ||
745 | |||
746 | int close_ctree(struct btrfs_root *root) | 538 | int close_ctree(struct btrfs_root *root) |
747 | { | 539 | { |
748 | int ret; | 540 | int ret; |
@@ -765,9 +557,6 @@ int close_ctree(struct btrfs_root *root) | |||
765 | if (fs_info->extent_root->node) | 557 | if (fs_info->extent_root->node) |
766 | btrfs_block_release(fs_info->extent_root, | 558 | btrfs_block_release(fs_info->extent_root, |
767 | fs_info->extent_root->node); | 559 | fs_info->extent_root->node); |
768 | if (fs_info->dev_root->node) | ||
769 | btrfs_block_release(fs_info->dev_root, | ||
770 | fs_info->dev_root->node); | ||
771 | if (fs_info->tree_root->node) | 560 | if (fs_info->tree_root->node) |
772 | btrfs_block_release(fs_info->tree_root, | 561 | btrfs_block_release(fs_info->tree_root, |
773 | fs_info->tree_root->node); | 562 | fs_info->tree_root->node); |
@@ -776,7 +565,6 @@ int close_ctree(struct btrfs_root *root) | |||
776 | truncate_inode_pages(fs_info->btree_inode->i_mapping, 0); | 565 | truncate_inode_pages(fs_info->btree_inode->i_mapping, 0); |
777 | iput(fs_info->btree_inode); | 566 | iput(fs_info->btree_inode); |
778 | 567 | ||
779 | free_dev_radix(fs_info); | ||
780 | btrfs_free_block_groups(root->fs_info); | 568 | btrfs_free_block_groups(root->fs_info); |
781 | del_fs_roots(fs_info); | 569 | del_fs_roots(fs_info); |
782 | kfree(fs_info->extent_root); | 570 | kfree(fs_info->extent_root); |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 5864917953a4..2b24a5a2be63 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -2566,83 +2566,6 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen) | |||
2566 | return 0; | 2566 | return 0; |
2567 | } | 2567 | } |
2568 | 2568 | ||
2569 | static int add_disk(struct btrfs_root *root, char *name, int namelen) | ||
2570 | { | ||
2571 | struct block_device *bdev; | ||
2572 | struct btrfs_path *path; | ||
2573 | struct super_block *sb = root->fs_info->sb; | ||
2574 | struct btrfs_root *dev_root = root->fs_info->dev_root; | ||
2575 | struct btrfs_trans_handle *trans; | ||
2576 | struct btrfs_device_item *dev_item; | ||
2577 | struct btrfs_key key; | ||
2578 | u16 item_size; | ||
2579 | u64 num_blocks; | ||
2580 | u64 new_blocks; | ||
2581 | u64 device_id; | ||
2582 | int ret; | ||
2583 | |||
2584 | printk("adding disk %s\n", name); | ||
2585 | path = btrfs_alloc_path(); | ||
2586 | if (!path) | ||
2587 | return -ENOMEM; | ||
2588 | num_blocks = btrfs_super_total_blocks(root->fs_info->disk_super); | ||
2589 | bdev = open_bdev_excl(name, O_RDWR, sb); | ||
2590 | if (IS_ERR(bdev)) { | ||
2591 | ret = PTR_ERR(bdev); | ||
2592 | printk("open bdev excl failed ret %d\n", ret); | ||
2593 | goto out_nolock; | ||
2594 | } | ||
2595 | set_blocksize(bdev, sb->s_blocksize); | ||
2596 | new_blocks = bdev->bd_inode->i_size >> sb->s_blocksize_bits; | ||
2597 | key.objectid = num_blocks; | ||
2598 | key.offset = new_blocks; | ||
2599 | key.flags = 0; | ||
2600 | btrfs_set_key_type(&key, BTRFS_DEV_ITEM_KEY); | ||
2601 | |||
2602 | mutex_lock(&dev_root->fs_info->fs_mutex); | ||
2603 | trans = btrfs_start_transaction(dev_root, 1); | ||
2604 | item_size = sizeof(*dev_item) + namelen; | ||
2605 | printk("insert empty on %Lu %Lu %u size %d\n", num_blocks, new_blocks, key.flags, item_size); | ||
2606 | ret = btrfs_insert_empty_item(trans, dev_root, path, &key, item_size); | ||
2607 | if (ret) { | ||
2608 | printk("insert failed %d\n", ret); | ||
2609 | close_bdev_excl(bdev); | ||
2610 | if (ret > 0) | ||
2611 | ret = -EEXIST; | ||
2612 | goto out; | ||
2613 | } | ||
2614 | dev_item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), | ||
2615 | path->slots[0], struct btrfs_device_item); | ||
2616 | btrfs_set_device_pathlen(dev_item, namelen); | ||
2617 | memcpy(dev_item + 1, name, namelen); | ||
2618 | |||
2619 | device_id = btrfs_super_last_device_id(root->fs_info->disk_super) + 1; | ||
2620 | btrfs_set_super_last_device_id(root->fs_info->disk_super, device_id); | ||
2621 | btrfs_set_device_id(dev_item, device_id); | ||
2622 | mark_buffer_dirty(path->nodes[0]); | ||
2623 | |||
2624 | ret = btrfs_insert_dev_radix(root, bdev, device_id, num_blocks, | ||
2625 | new_blocks); | ||
2626 | |||
2627 | if (!ret) { | ||
2628 | btrfs_set_super_total_blocks(root->fs_info->disk_super, | ||
2629 | num_blocks + new_blocks); | ||
2630 | i_size_write(root->fs_info->btree_inode, | ||
2631 | (num_blocks + new_blocks) << | ||
2632 | root->fs_info->btree_inode->i_blkbits); | ||
2633 | } | ||
2634 | |||
2635 | out: | ||
2636 | ret = btrfs_commit_transaction(trans, dev_root); | ||
2637 | BUG_ON(ret); | ||
2638 | mutex_unlock(&root->fs_info->fs_mutex); | ||
2639 | out_nolock: | ||
2640 | btrfs_free_path(path); | ||
2641 | btrfs_btree_balance_dirty(root); | ||
2642 | |||
2643 | return ret; | ||
2644 | } | ||
2645 | |||
2646 | static int btrfs_ioctl(struct inode *inode, struct file *filp, unsigned int | 2569 | static int btrfs_ioctl(struct inode *inode, struct file *filp, unsigned int |
2647 | cmd, unsigned long arg) | 2570 | cmd, unsigned long arg) |
2648 | { | 2571 | { |
@@ -2682,17 +2605,6 @@ static int btrfs_ioctl(struct inode *inode, struct file *filp, unsigned int | |||
2682 | ret = create_snapshot(root, vol_args.name, namelen); | 2605 | ret = create_snapshot(root, vol_args.name, namelen); |
2683 | WARN_ON(ret); | 2606 | WARN_ON(ret); |
2684 | break; | 2607 | break; |
2685 | case BTRFS_IOC_ADD_DISK: | ||
2686 | if (copy_from_user(&vol_args, | ||
2687 | (struct btrfs_ioctl_vol_args __user *)arg, | ||
2688 | sizeof(vol_args))) | ||
2689 | return -EFAULT; | ||
2690 | namelen = strlen(vol_args.name); | ||
2691 | if (namelen > BTRFS_VOL_NAME_MAX) | ||
2692 | return -EINVAL; | ||
2693 | vol_args.name[namelen] = '\0'; | ||
2694 | ret = add_disk(root, vol_args.name, namelen); | ||
2695 | break; | ||
2696 | default: | 2608 | default: |
2697 | return -ENOTTY; | 2609 | return -ENOTTY; |
2698 | } | 2610 | } |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index a2c5820f1d3d..4f3c8ddcb401 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -150,13 +150,7 @@ int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans, | |||
150 | struct btrfs_fs_info *fs_info = root->fs_info; | 150 | struct btrfs_fs_info *fs_info = root->fs_info; |
151 | struct btrfs_root *tree_root = fs_info->tree_root; | 151 | struct btrfs_root *tree_root = fs_info->tree_root; |
152 | struct btrfs_root *extent_root = fs_info->extent_root; | 152 | struct btrfs_root *extent_root = fs_info->extent_root; |
153 | struct btrfs_root *dev_root = fs_info->dev_root; | ||
154 | 153 | ||
155 | if (btrfs_super_device_root(fs_info->disk_super) != | ||
156 | bh_blocknr(dev_root->node)) { | ||
157 | btrfs_set_super_device_root(fs_info->disk_super, | ||
158 | bh_blocknr(dev_root->node)); | ||
159 | } | ||
160 | btrfs_write_dirty_block_groups(trans, extent_root); | 154 | btrfs_write_dirty_block_groups(trans, extent_root); |
161 | while(1) { | 155 | while(1) { |
162 | old_extent_block = btrfs_root_blocknr(&extent_root->root_item); | 156 | old_extent_block = btrfs_root_blocknr(&extent_root->root_item); |