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/disk-io.c | |
parent | ad693af684757478e5fcb225aef319cab7ba6c75 (diff) |
Btrfs: remove device tree
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 224 |
1 files changed, 6 insertions, 218 deletions
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); |