diff options
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 120 |
1 files changed, 87 insertions, 33 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 81a313874ae..5aebddd7119 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -16,7 +16,6 @@ | |||
16 | * Boston, MA 021110-1307, USA. | 16 | * Boston, MA 021110-1307, USA. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/version.h> | ||
20 | #include <linux/fs.h> | 19 | #include <linux/fs.h> |
21 | #include <linux/blkdev.h> | 20 | #include <linux/blkdev.h> |
22 | #include <linux/scatterlist.h> | 21 | #include <linux/scatterlist.h> |
@@ -800,7 +799,7 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr, | |||
800 | ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid); | 799 | ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid); |
801 | 800 | ||
802 | if (ret == 0) | 801 | if (ret == 0) |
803 | buf->flags |= EXTENT_UPTODATE; | 802 | set_bit(EXTENT_BUFFER_UPTODATE, &buf->bflags); |
804 | else | 803 | else |
805 | WARN_ON(1); | 804 | WARN_ON(1); |
806 | return buf; | 805 | return buf; |
@@ -814,6 +813,10 @@ int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
814 | if (btrfs_header_generation(buf) == | 813 | if (btrfs_header_generation(buf) == |
815 | root->fs_info->running_transaction->transid) { | 814 | root->fs_info->running_transaction->transid) { |
816 | WARN_ON(!btrfs_tree_locked(buf)); | 815 | WARN_ON(!btrfs_tree_locked(buf)); |
816 | |||
817 | /* ugh, clear_extent_buffer_dirty can be expensive */ | ||
818 | btrfs_set_lock_blocking(buf); | ||
819 | |||
817 | clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->io_tree, | 820 | clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->io_tree, |
818 | buf); | 821 | buf); |
819 | } | 822 | } |
@@ -850,6 +853,14 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, | |||
850 | spin_lock_init(&root->list_lock); | 853 | spin_lock_init(&root->list_lock); |
851 | mutex_init(&root->objectid_mutex); | 854 | mutex_init(&root->objectid_mutex); |
852 | mutex_init(&root->log_mutex); | 855 | mutex_init(&root->log_mutex); |
856 | init_waitqueue_head(&root->log_writer_wait); | ||
857 | init_waitqueue_head(&root->log_commit_wait[0]); | ||
858 | init_waitqueue_head(&root->log_commit_wait[1]); | ||
859 | atomic_set(&root->log_commit[0], 0); | ||
860 | atomic_set(&root->log_commit[1], 0); | ||
861 | atomic_set(&root->log_writers, 0); | ||
862 | root->log_batch = 0; | ||
863 | root->log_transid = 0; | ||
853 | extent_io_tree_init(&root->dirty_log_pages, | 864 | extent_io_tree_init(&root->dirty_log_pages, |
854 | fs_info->btree_inode->i_mapping, GFP_NOFS); | 865 | fs_info->btree_inode->i_mapping, GFP_NOFS); |
855 | 866 | ||
@@ -934,15 +945,16 @@ int btrfs_free_log_root_tree(struct btrfs_trans_handle *trans, | |||
934 | return 0; | 945 | return 0; |
935 | } | 946 | } |
936 | 947 | ||
937 | int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, | 948 | static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans, |
938 | struct btrfs_fs_info *fs_info) | 949 | struct btrfs_fs_info *fs_info) |
939 | { | 950 | { |
940 | struct btrfs_root *root; | 951 | struct btrfs_root *root; |
941 | struct btrfs_root *tree_root = fs_info->tree_root; | 952 | struct btrfs_root *tree_root = fs_info->tree_root; |
953 | struct extent_buffer *leaf; | ||
942 | 954 | ||
943 | root = kzalloc(sizeof(*root), GFP_NOFS); | 955 | root = kzalloc(sizeof(*root), GFP_NOFS); |
944 | if (!root) | 956 | if (!root) |
945 | return -ENOMEM; | 957 | return ERR_PTR(-ENOMEM); |
946 | 958 | ||
947 | __setup_root(tree_root->nodesize, tree_root->leafsize, | 959 | __setup_root(tree_root->nodesize, tree_root->leafsize, |
948 | tree_root->sectorsize, tree_root->stripesize, | 960 | tree_root->sectorsize, tree_root->stripesize, |
@@ -951,12 +963,23 @@ int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, | |||
951 | root->root_key.objectid = BTRFS_TREE_LOG_OBJECTID; | 963 | root->root_key.objectid = BTRFS_TREE_LOG_OBJECTID; |
952 | root->root_key.type = BTRFS_ROOT_ITEM_KEY; | 964 | root->root_key.type = BTRFS_ROOT_ITEM_KEY; |
953 | root->root_key.offset = BTRFS_TREE_LOG_OBJECTID; | 965 | root->root_key.offset = BTRFS_TREE_LOG_OBJECTID; |
966 | /* | ||
967 | * log trees do not get reference counted because they go away | ||
968 | * before a real commit is actually done. They do store pointers | ||
969 | * to file data extents, and those reference counts still get | ||
970 | * updated (along with back refs to the log tree). | ||
971 | */ | ||
954 | root->ref_cows = 0; | 972 | root->ref_cows = 0; |
955 | 973 | ||
956 | root->node = btrfs_alloc_free_block(trans, root, root->leafsize, | 974 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, |
957 | 0, BTRFS_TREE_LOG_OBJECTID, | 975 | 0, BTRFS_TREE_LOG_OBJECTID, |
958 | trans->transid, 0, 0, 0); | 976 | trans->transid, 0, 0, 0); |
977 | if (IS_ERR(leaf)) { | ||
978 | kfree(root); | ||
979 | return ERR_CAST(leaf); | ||
980 | } | ||
959 | 981 | ||
982 | root->node = leaf; | ||
960 | btrfs_set_header_nritems(root->node, 0); | 983 | btrfs_set_header_nritems(root->node, 0); |
961 | btrfs_set_header_level(root->node, 0); | 984 | btrfs_set_header_level(root->node, 0); |
962 | btrfs_set_header_bytenr(root->node, root->node->start); | 985 | btrfs_set_header_bytenr(root->node, root->node->start); |
@@ -968,7 +991,48 @@ int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, | |||
968 | BTRFS_FSID_SIZE); | 991 | BTRFS_FSID_SIZE); |
969 | btrfs_mark_buffer_dirty(root->node); | 992 | btrfs_mark_buffer_dirty(root->node); |
970 | btrfs_tree_unlock(root->node); | 993 | btrfs_tree_unlock(root->node); |
971 | fs_info->log_root_tree = root; | 994 | return root; |
995 | } | ||
996 | |||
997 | int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, | ||
998 | struct btrfs_fs_info *fs_info) | ||
999 | { | ||
1000 | struct btrfs_root *log_root; | ||
1001 | |||
1002 | log_root = alloc_log_tree(trans, fs_info); | ||
1003 | if (IS_ERR(log_root)) | ||
1004 | return PTR_ERR(log_root); | ||
1005 | WARN_ON(fs_info->log_root_tree); | ||
1006 | fs_info->log_root_tree = log_root; | ||
1007 | return 0; | ||
1008 | } | ||
1009 | |||
1010 | int btrfs_add_log_tree(struct btrfs_trans_handle *trans, | ||
1011 | struct btrfs_root *root) | ||
1012 | { | ||
1013 | struct btrfs_root *log_root; | ||
1014 | struct btrfs_inode_item *inode_item; | ||
1015 | |||
1016 | log_root = alloc_log_tree(trans, root->fs_info); | ||
1017 | if (IS_ERR(log_root)) | ||
1018 | return PTR_ERR(log_root); | ||
1019 | |||
1020 | log_root->last_trans = trans->transid; | ||
1021 | log_root->root_key.offset = root->root_key.objectid; | ||
1022 | |||
1023 | inode_item = &log_root->root_item.inode; | ||
1024 | inode_item->generation = cpu_to_le64(1); | ||
1025 | inode_item->size = cpu_to_le64(3); | ||
1026 | inode_item->nlink = cpu_to_le32(1); | ||
1027 | inode_item->nbytes = cpu_to_le64(root->leafsize); | ||
1028 | inode_item->mode = cpu_to_le32(S_IFDIR | 0755); | ||
1029 | |||
1030 | btrfs_set_root_bytenr(&log_root->root_item, log_root->node->start); | ||
1031 | btrfs_set_root_generation(&log_root->root_item, trans->transid); | ||
1032 | |||
1033 | WARN_ON(root->log_root); | ||
1034 | root->log_root = log_root; | ||
1035 | root->log_transid = 0; | ||
972 | return 0; | 1036 | return 0; |
973 | } | 1037 | } |
974 | 1038 | ||
@@ -1136,7 +1200,6 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits) | |||
1136 | { | 1200 | { |
1137 | struct btrfs_fs_info *info = (struct btrfs_fs_info *)congested_data; | 1201 | struct btrfs_fs_info *info = (struct btrfs_fs_info *)congested_data; |
1138 | int ret = 0; | 1202 | int ret = 0; |
1139 | struct list_head *cur; | ||
1140 | struct btrfs_device *device; | 1203 | struct btrfs_device *device; |
1141 | struct backing_dev_info *bdi; | 1204 | struct backing_dev_info *bdi; |
1142 | #if 0 | 1205 | #if 0 |
@@ -1144,8 +1207,7 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits) | |||
1144 | btrfs_congested_async(info, 0)) | 1207 | btrfs_congested_async(info, 0)) |
1145 | return 1; | 1208 | return 1; |
1146 | #endif | 1209 | #endif |
1147 | list_for_each(cur, &info->fs_devices->devices) { | 1210 | list_for_each_entry(device, &info->fs_devices->devices, dev_list) { |
1148 | device = list_entry(cur, struct btrfs_device, dev_list); | ||
1149 | if (!device->bdev) | 1211 | if (!device->bdev) |
1150 | continue; | 1212 | continue; |
1151 | bdi = blk_get_backing_dev_info(device->bdev); | 1213 | bdi = blk_get_backing_dev_info(device->bdev); |
@@ -1163,13 +1225,11 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits) | |||
1163 | */ | 1225 | */ |
1164 | static void __unplug_io_fn(struct backing_dev_info *bdi, struct page *page) | 1226 | static void __unplug_io_fn(struct backing_dev_info *bdi, struct page *page) |
1165 | { | 1227 | { |
1166 | struct list_head *cur; | ||
1167 | struct btrfs_device *device; | 1228 | struct btrfs_device *device; |
1168 | struct btrfs_fs_info *info; | 1229 | struct btrfs_fs_info *info; |
1169 | 1230 | ||
1170 | info = (struct btrfs_fs_info *)bdi->unplug_io_data; | 1231 | info = (struct btrfs_fs_info *)bdi->unplug_io_data; |
1171 | list_for_each(cur, &info->fs_devices->devices) { | 1232 | list_for_each_entry(device, &info->fs_devices->devices, dev_list) { |
1172 | device = list_entry(cur, struct btrfs_device, dev_list); | ||
1173 | if (!device->bdev) | 1233 | if (!device->bdev) |
1174 | continue; | 1234 | continue; |
1175 | 1235 | ||
@@ -1447,7 +1507,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1447 | INIT_LIST_HEAD(&fs_info->dead_roots); | 1507 | INIT_LIST_HEAD(&fs_info->dead_roots); |
1448 | INIT_LIST_HEAD(&fs_info->hashers); | 1508 | INIT_LIST_HEAD(&fs_info->hashers); |
1449 | INIT_LIST_HEAD(&fs_info->delalloc_inodes); | 1509 | INIT_LIST_HEAD(&fs_info->delalloc_inodes); |
1450 | spin_lock_init(&fs_info->hash_lock); | ||
1451 | spin_lock_init(&fs_info->delalloc_lock); | 1510 | spin_lock_init(&fs_info->delalloc_lock); |
1452 | spin_lock_init(&fs_info->new_trans_lock); | 1511 | spin_lock_init(&fs_info->new_trans_lock); |
1453 | spin_lock_init(&fs_info->ref_cache_lock); | 1512 | spin_lock_init(&fs_info->ref_cache_lock); |
@@ -1535,10 +1594,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1535 | init_waitqueue_head(&fs_info->transaction_throttle); | 1594 | init_waitqueue_head(&fs_info->transaction_throttle); |
1536 | init_waitqueue_head(&fs_info->transaction_wait); | 1595 | init_waitqueue_head(&fs_info->transaction_wait); |
1537 | init_waitqueue_head(&fs_info->async_submit_wait); | 1596 | init_waitqueue_head(&fs_info->async_submit_wait); |
1538 | init_waitqueue_head(&fs_info->tree_log_wait); | ||
1539 | atomic_set(&fs_info->tree_log_commit, 0); | ||
1540 | atomic_set(&fs_info->tree_log_writers, 0); | ||
1541 | fs_info->tree_log_transid = 0; | ||
1542 | 1597 | ||
1543 | __setup_root(4096, 4096, 4096, 4096, tree_root, | 1598 | __setup_root(4096, 4096, 4096, 4096, tree_root, |
1544 | fs_info, BTRFS_ROOT_TREE_OBJECTID); | 1599 | fs_info, BTRFS_ROOT_TREE_OBJECTID); |
@@ -1627,6 +1682,8 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1627 | * low idle thresh | 1682 | * low idle thresh |
1628 | */ | 1683 | */ |
1629 | fs_info->endio_workers.idle_thresh = 4; | 1684 | fs_info->endio_workers.idle_thresh = 4; |
1685 | fs_info->endio_meta_workers.idle_thresh = 4; | ||
1686 | |||
1630 | fs_info->endio_write_workers.idle_thresh = 64; | 1687 | fs_info->endio_write_workers.idle_thresh = 64; |
1631 | fs_info->endio_meta_write_workers.idle_thresh = 64; | 1688 | fs_info->endio_meta_write_workers.idle_thresh = 64; |
1632 | 1689 | ||
@@ -1740,13 +1797,13 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1740 | fs_info->system_alloc_profile = fs_info->metadata_alloc_profile; | 1797 | fs_info->system_alloc_profile = fs_info->metadata_alloc_profile; |
1741 | fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root, | 1798 | fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root, |
1742 | "btrfs-cleaner"); | 1799 | "btrfs-cleaner"); |
1743 | if (!fs_info->cleaner_kthread) | 1800 | if (IS_ERR(fs_info->cleaner_kthread)) |
1744 | goto fail_csum_root; | 1801 | goto fail_csum_root; |
1745 | 1802 | ||
1746 | fs_info->transaction_kthread = kthread_run(transaction_kthread, | 1803 | fs_info->transaction_kthread = kthread_run(transaction_kthread, |
1747 | tree_root, | 1804 | tree_root, |
1748 | "btrfs-transaction"); | 1805 | "btrfs-transaction"); |
1749 | if (!fs_info->transaction_kthread) | 1806 | if (IS_ERR(fs_info->transaction_kthread)) |
1750 | goto fail_cleaner; | 1807 | goto fail_cleaner; |
1751 | 1808 | ||
1752 | if (btrfs_super_log_root(disk_super) != 0) { | 1809 | if (btrfs_super_log_root(disk_super) != 0) { |
@@ -1828,13 +1885,14 @@ fail_sb_buffer: | |||
1828 | fail_iput: | 1885 | fail_iput: |
1829 | invalidate_inode_pages2(fs_info->btree_inode->i_mapping); | 1886 | invalidate_inode_pages2(fs_info->btree_inode->i_mapping); |
1830 | iput(fs_info->btree_inode); | 1887 | iput(fs_info->btree_inode); |
1831 | fail: | 1888 | |
1832 | btrfs_close_devices(fs_info->fs_devices); | 1889 | btrfs_close_devices(fs_info->fs_devices); |
1833 | btrfs_mapping_tree_free(&fs_info->mapping_tree); | 1890 | btrfs_mapping_tree_free(&fs_info->mapping_tree); |
1891 | bdi_destroy(&fs_info->bdi); | ||
1834 | 1892 | ||
1893 | fail: | ||
1835 | kfree(extent_root); | 1894 | kfree(extent_root); |
1836 | kfree(tree_root); | 1895 | kfree(tree_root); |
1837 | bdi_destroy(&fs_info->bdi); | ||
1838 | kfree(fs_info); | 1896 | kfree(fs_info); |
1839 | kfree(chunk_root); | 1897 | kfree(chunk_root); |
1840 | kfree(dev_root); | 1898 | kfree(dev_root); |
@@ -1995,7 +2053,6 @@ static int write_dev_supers(struct btrfs_device *device, | |||
1995 | 2053 | ||
1996 | int write_all_supers(struct btrfs_root *root, int max_mirrors) | 2054 | int write_all_supers(struct btrfs_root *root, int max_mirrors) |
1997 | { | 2055 | { |
1998 | struct list_head *cur; | ||
1999 | struct list_head *head = &root->fs_info->fs_devices->devices; | 2056 | struct list_head *head = &root->fs_info->fs_devices->devices; |
2000 | struct btrfs_device *dev; | 2057 | struct btrfs_device *dev; |
2001 | struct btrfs_super_block *sb; | 2058 | struct btrfs_super_block *sb; |
@@ -2011,8 +2068,7 @@ int write_all_supers(struct btrfs_root *root, int max_mirrors) | |||
2011 | 2068 | ||
2012 | sb = &root->fs_info->super_for_commit; | 2069 | sb = &root->fs_info->super_for_commit; |
2013 | dev_item = &sb->dev_item; | 2070 | dev_item = &sb->dev_item; |
2014 | list_for_each(cur, head) { | 2071 | list_for_each_entry(dev, head, dev_list) { |
2015 | dev = list_entry(cur, struct btrfs_device, dev_list); | ||
2016 | if (!dev->bdev) { | 2072 | if (!dev->bdev) { |
2017 | total_errors++; | 2073 | total_errors++; |
2018 | continue; | 2074 | continue; |
@@ -2045,8 +2101,7 @@ int write_all_supers(struct btrfs_root *root, int max_mirrors) | |||
2045 | } | 2101 | } |
2046 | 2102 | ||
2047 | total_errors = 0; | 2103 | total_errors = 0; |
2048 | list_for_each(cur, head) { | 2104 | list_for_each_entry(dev, head, dev_list) { |
2049 | dev = list_entry(cur, struct btrfs_device, dev_list); | ||
2050 | if (!dev->bdev) | 2105 | if (!dev->bdev) |
2051 | continue; | 2106 | continue; |
2052 | if (!dev->in_fs_metadata || !dev->writeable) | 2107 | if (!dev->in_fs_metadata || !dev->writeable) |
@@ -2260,6 +2315,8 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf) | |||
2260 | u64 transid = btrfs_header_generation(buf); | 2315 | u64 transid = btrfs_header_generation(buf); |
2261 | struct inode *btree_inode = root->fs_info->btree_inode; | 2316 | struct inode *btree_inode = root->fs_info->btree_inode; |
2262 | 2317 | ||
2318 | btrfs_set_lock_blocking(buf); | ||
2319 | |||
2263 | WARN_ON(!btrfs_tree_locked(buf)); | 2320 | WARN_ON(!btrfs_tree_locked(buf)); |
2264 | if (transid != root->fs_info->generation) { | 2321 | if (transid != root->fs_info->generation) { |
2265 | printk(KERN_CRIT "btrfs transid mismatch buffer %llu, " | 2322 | printk(KERN_CRIT "btrfs transid mismatch buffer %llu, " |
@@ -2302,14 +2359,13 @@ int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid) | |||
2302 | int ret; | 2359 | int ret; |
2303 | ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid); | 2360 | ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid); |
2304 | if (ret == 0) | 2361 | if (ret == 0) |
2305 | buf->flags |= EXTENT_UPTODATE; | 2362 | set_bit(EXTENT_BUFFER_UPTODATE, &buf->bflags); |
2306 | return ret; | 2363 | return ret; |
2307 | } | 2364 | } |
2308 | 2365 | ||
2309 | int btree_lock_page_hook(struct page *page) | 2366 | int btree_lock_page_hook(struct page *page) |
2310 | { | 2367 | { |
2311 | struct inode *inode = page->mapping->host; | 2368 | struct inode *inode = page->mapping->host; |
2312 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
2313 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | 2369 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
2314 | struct extent_buffer *eb; | 2370 | struct extent_buffer *eb; |
2315 | unsigned long len; | 2371 | unsigned long len; |
@@ -2324,9 +2380,7 @@ int btree_lock_page_hook(struct page *page) | |||
2324 | goto out; | 2380 | goto out; |
2325 | 2381 | ||
2326 | btrfs_tree_lock(eb); | 2382 | btrfs_tree_lock(eb); |
2327 | spin_lock(&root->fs_info->hash_lock); | ||
2328 | btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN); | 2383 | btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN); |
2329 | spin_unlock(&root->fs_info->hash_lock); | ||
2330 | btrfs_tree_unlock(eb); | 2384 | btrfs_tree_unlock(eb); |
2331 | free_extent_buffer(eb); | 2385 | free_extent_buffer(eb); |
2332 | out: | 2386 | out: |