aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-03-24 15:01:56 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:00 -0400
commit0b86a832a1f38abec695864ec2eaedc9d2383f1b (patch)
tree8ec0db0b55f77eb6a23fe7db3c1064d298db55c1 /fs/btrfs/disk-io.c
parent7f93bf8d27653726e3721c01fefc523487ecf2af (diff)
Btrfs: Add support for multiple devices per filesystem
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c97
1 files changed, 91 insertions, 6 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 88e21bdbc478..8e37fa120cc8 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -28,6 +28,7 @@
28#include "disk-io.h" 28#include "disk-io.h"
29#include "transaction.h" 29#include "transaction.h"
30#include "btrfs_inode.h" 30#include "btrfs_inode.h"
31#include "volumes.h"
31#include "print-tree.h" 32#include "print-tree.h"
32 33
33#if 0 34#if 0
@@ -234,6 +235,19 @@ static int btree_writepage_io_hook(struct page *page, u64 start, u64 end)
234 return 0; 235 return 0;
235} 236}
236 237
238static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio)
239{
240 struct btrfs_root *root = BTRFS_I(inode)->root;
241 u64 offset;
242 offset = bio->bi_sector << 9;
243 if (offset == BTRFS_SUPER_INFO_OFFSET) {
244 bio->bi_bdev = root->fs_info->sb->s_bdev;
245 submit_bio(rw, bio);
246 return 0;
247 }
248 return btrfs_map_bio(BTRFS_I(inode)->root, rw, bio);
249}
250
237static int btree_writepage(struct page *page, struct writeback_control *wbc) 251static int btree_writepage(struct page *page, struct writeback_control *wbc)
238{ 252{
239 struct extent_io_tree *tree; 253 struct extent_io_tree *tree;
@@ -345,6 +359,23 @@ int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize)
345 return ret; 359 return ret;
346} 360}
347 361
362static int close_all_devices(struct btrfs_fs_info *fs_info)
363{
364 struct list_head *list;
365 struct list_head *next;
366 struct btrfs_device *device;
367
368 list = &fs_info->devices;
369 while(!list_empty(list)) {
370 next = list->next;
371 list_del(next);
372 device = list_entry(next, struct btrfs_device, dev_list);
373 kfree(device->name);
374 kfree(device);
375 }
376 return 0;
377}
378
348struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr, 379struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
349 u32 blocksize) 380 u32 blocksize)
350{ 381{
@@ -420,6 +451,8 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
420 root->leafsize = leafsize; 451 root->leafsize = leafsize;
421 root->stripesize = stripesize; 452 root->stripesize = stripesize;
422 root->ref_cows = 0; 453 root->ref_cows = 0;
454 root->track_dirty = 0;
455
423 root->fs_info = fs_info; 456 root->fs_info = fs_info;
424 root->objectid = objectid; 457 root->objectid = objectid;
425 root->last_trans = 0; 458 root->last_trans = 0;
@@ -427,6 +460,8 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
427 root->last_inode_alloc = 0; 460 root->last_inode_alloc = 0;
428 root->name = NULL; 461 root->name = NULL;
429 root->in_sysfs = 0; 462 root->in_sysfs = 0;
463
464 INIT_LIST_HEAD(&root->dirty_list);
430 memset(&root->root_key, 0, sizeof(root->root_key)); 465 memset(&root->root_key, 0, sizeof(root->root_key));
431 memset(&root->root_item, 0, sizeof(root->root_item)); 466 memset(&root->root_item, 0, sizeof(root->root_item));
432 memset(&root->defrag_progress, 0, sizeof(root->defrag_progress)); 467 memset(&root->defrag_progress, 0, sizeof(root->defrag_progress));
@@ -634,6 +669,10 @@ struct btrfs_root *open_ctree(struct super_block *sb)
634 GFP_NOFS); 669 GFP_NOFS);
635 struct btrfs_fs_info *fs_info = kmalloc(sizeof(*fs_info), 670 struct btrfs_fs_info *fs_info = kmalloc(sizeof(*fs_info),
636 GFP_NOFS); 671 GFP_NOFS);
672 struct btrfs_root *chunk_root = kmalloc(sizeof(struct btrfs_root),
673 GFP_NOFS);
674 struct btrfs_root *dev_root = kmalloc(sizeof(struct btrfs_root),
675 GFP_NOFS);
637 int ret; 676 int ret;
638 int err = -EIO; 677 int err = -EIO;
639 struct btrfs_super_block *disk_super; 678 struct btrfs_super_block *disk_super;
@@ -657,6 +696,12 @@ struct btrfs_root *open_ctree(struct super_block *sb)
657 fs_info->last_trans_committed = 0; 696 fs_info->last_trans_committed = 0;
658 fs_info->tree_root = tree_root; 697 fs_info->tree_root = tree_root;
659 fs_info->extent_root = extent_root; 698 fs_info->extent_root = extent_root;
699 fs_info->chunk_root = chunk_root;
700 fs_info->dev_root = dev_root;
701 INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots);
702 INIT_LIST_HEAD(&fs_info->devices);
703 btrfs_mapping_init(&fs_info->mapping_tree);
704 fs_info->last_device = &fs_info->devices;
660 fs_info->sb = sb; 705 fs_info->sb = sb;
661 fs_info->throttles = 0; 706 fs_info->throttles = 0;
662 fs_info->mount_opt = 0; 707 fs_info->mount_opt = 0;
@@ -714,12 +759,12 @@ struct btrfs_root *open_ctree(struct super_block *sb)
714 goto fail_iput; 759 goto fail_iput;
715 } 760 }
716#endif 761#endif
717 __setup_root(512, 512, 512, 512, tree_root, 762 __setup_root(4096, 4096, 4096, 4096, tree_root,
718 fs_info, BTRFS_ROOT_TREE_OBJECTID); 763 fs_info, BTRFS_ROOT_TREE_OBJECTID);
719 764
720 fs_info->sb_buffer = read_tree_block(tree_root, 765 fs_info->sb_buffer = read_tree_block(tree_root,
721 BTRFS_SUPER_INFO_OFFSET, 766 BTRFS_SUPER_INFO_OFFSET,
722 512); 767 4096);
723 768
724 if (!fs_info->sb_buffer) 769 if (!fs_info->sb_buffer)
725 goto fail_iput; 770 goto fail_iput;
@@ -730,6 +775,7 @@ struct btrfs_root *open_ctree(struct super_block *sb)
730 read_extent_buffer(fs_info->sb_buffer, fs_info->fsid, 775 read_extent_buffer(fs_info->sb_buffer, fs_info->fsid,
731 (unsigned long)btrfs_super_fsid(fs_info->sb_buffer), 776 (unsigned long)btrfs_super_fsid(fs_info->sb_buffer),
732 BTRFS_FSID_SIZE); 777 BTRFS_FSID_SIZE);
778
733 disk_super = &fs_info->super_copy; 779 disk_super = &fs_info->super_copy;
734 if (!btrfs_super_root(disk_super)) 780 if (!btrfs_super_root(disk_super))
735 goto fail_sb_buffer; 781 goto fail_sb_buffer;
@@ -753,23 +799,47 @@ struct btrfs_root *open_ctree(struct super_block *sb)
753 goto fail_sb_buffer; 799 goto fail_sb_buffer;
754 } 800 }
755 801
802 mutex_lock(&fs_info->fs_mutex);
803 ret = btrfs_read_sys_array(tree_root);
804 BUG_ON(ret);
805
806 blocksize = btrfs_level_size(tree_root,
807 btrfs_super_chunk_root_level(disk_super));
808
809 __setup_root(nodesize, leafsize, sectorsize, stripesize,
810 chunk_root, fs_info, BTRFS_CHUNK_TREE_OBJECTID);
811
812 chunk_root->node = read_tree_block(chunk_root,
813 btrfs_super_chunk_root(disk_super),
814 blocksize);
815 BUG_ON(!chunk_root->node);
816
817 ret = btrfs_read_chunk_tree(chunk_root);
818 BUG_ON(ret);
819
756 blocksize = btrfs_level_size(tree_root, 820 blocksize = btrfs_level_size(tree_root,
757 btrfs_super_root_level(disk_super)); 821 btrfs_super_root_level(disk_super));
758 822
823
759 tree_root->node = read_tree_block(tree_root, 824 tree_root->node = read_tree_block(tree_root,
760 btrfs_super_root(disk_super), 825 btrfs_super_root(disk_super),
761 blocksize); 826 blocksize);
762 if (!tree_root->node) 827 if (!tree_root->node)
763 goto fail_sb_buffer; 828 goto fail_sb_buffer;
764 829
765 mutex_lock(&fs_info->fs_mutex);
766 830
767 ret = find_and_setup_root(tree_root, fs_info, 831 ret = find_and_setup_root(tree_root, fs_info,
768 BTRFS_EXTENT_TREE_OBJECTID, extent_root); 832 BTRFS_EXTENT_TREE_OBJECTID, extent_root);
769 if (ret) { 833 if (ret)
770 mutex_unlock(&fs_info->fs_mutex);
771 goto fail_tree_root; 834 goto fail_tree_root;
772 } 835 extent_root->track_dirty = 1;
836
837 ret = find_and_setup_root(tree_root, fs_info,
838 BTRFS_DEV_TREE_OBJECTID, dev_root);
839 dev_root->track_dirty = 1;
840
841 if (ret)
842 goto fail_extent_root;
773 843
774 btrfs_read_block_groups(extent_root); 844 btrfs_read_block_groups(extent_root);
775 845
@@ -777,7 +847,10 @@ struct btrfs_root *open_ctree(struct super_block *sb)
777 mutex_unlock(&fs_info->fs_mutex); 847 mutex_unlock(&fs_info->fs_mutex);
778 return tree_root; 848 return tree_root;
779 849
850fail_extent_root:
851 free_extent_buffer(extent_root->node);
780fail_tree_root: 852fail_tree_root:
853 mutex_unlock(&fs_info->fs_mutex);
781 free_extent_buffer(tree_root->node); 854 free_extent_buffer(tree_root->node);
782fail_sb_buffer: 855fail_sb_buffer:
783 free_extent_buffer(fs_info->sb_buffer); 856 free_extent_buffer(fs_info->sb_buffer);
@@ -874,6 +947,12 @@ int close_ctree(struct btrfs_root *root)
874 if (fs_info->tree_root->node) 947 if (fs_info->tree_root->node)
875 free_extent_buffer(fs_info->tree_root->node); 948 free_extent_buffer(fs_info->tree_root->node);
876 949
950 if (root->fs_info->chunk_root->node);
951 free_extent_buffer(root->fs_info->chunk_root->node);
952
953 if (root->fs_info->dev_root->node);
954 free_extent_buffer(root->fs_info->dev_root->node);
955
877 free_extent_buffer(fs_info->sb_buffer); 956 free_extent_buffer(fs_info->sb_buffer);
878 957
879 btrfs_free_block_groups(root->fs_info); 958 btrfs_free_block_groups(root->fs_info);
@@ -901,8 +980,13 @@ int close_ctree(struct btrfs_root *root)
901 kfree(hasher); 980 kfree(hasher);
902 } 981 }
903#endif 982#endif
983 close_all_devices(fs_info);
984 btrfs_mapping_tree_free(&fs_info->mapping_tree);
985
904 kfree(fs_info->extent_root); 986 kfree(fs_info->extent_root);
905 kfree(fs_info->tree_root); 987 kfree(fs_info->tree_root);
988 kfree(fs_info->chunk_root);
989 kfree(fs_info->dev_root);
906 return 0; 990 return 0;
907} 991}
908 992
@@ -1016,4 +1100,5 @@ int btrfs_read_buffer(struct extent_buffer *buf)
1016 1100
1017static struct extent_io_ops btree_extent_io_ops = { 1101static struct extent_io_ops btree_extent_io_ops = {
1018 .writepage_io_hook = btree_writepage_io_hook, 1102 .writepage_io_hook = btree_writepage_io_hook,
1103 .submit_bio_hook = btree_submit_bio_hook,
1019}; 1104};