diff options
Diffstat (limited to 'fs/btrfs/disk-io.c')
| -rw-r--r-- | fs/btrfs/disk-io.c | 166 |
1 files changed, 132 insertions, 34 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 81a313874ae5..adda739a0215 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> |
| @@ -76,6 +75,40 @@ struct async_submit_bio { | |||
| 76 | struct btrfs_work work; | 75 | struct btrfs_work work; |
| 77 | }; | 76 | }; |
| 78 | 77 | ||
| 78 | /* These are used to set the lockdep class on the extent buffer locks. | ||
| 79 | * The class is set by the readpage_end_io_hook after the buffer has | ||
| 80 | * passed csum validation but before the pages are unlocked. | ||
| 81 | * | ||
| 82 | * The lockdep class is also set by btrfs_init_new_buffer on freshly | ||
| 83 | * allocated blocks. | ||
| 84 | * | ||
| 85 | * The class is based on the level in the tree block, which allows lockdep | ||
| 86 | * to know that lower nodes nest inside the locks of higher nodes. | ||
| 87 | * | ||
| 88 | * We also add a check to make sure the highest level of the tree is | ||
| 89 | * the same as our lockdep setup here. If BTRFS_MAX_LEVEL changes, this | ||
| 90 | * code needs update as well. | ||
| 91 | */ | ||
| 92 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
| 93 | # if BTRFS_MAX_LEVEL != 8 | ||
| 94 | # error | ||
| 95 | # endif | ||
| 96 | static struct lock_class_key btrfs_eb_class[BTRFS_MAX_LEVEL + 1]; | ||
| 97 | static const char *btrfs_eb_name[BTRFS_MAX_LEVEL + 1] = { | ||
| 98 | /* leaf */ | ||
| 99 | "btrfs-extent-00", | ||
| 100 | "btrfs-extent-01", | ||
| 101 | "btrfs-extent-02", | ||
| 102 | "btrfs-extent-03", | ||
| 103 | "btrfs-extent-04", | ||
| 104 | "btrfs-extent-05", | ||
| 105 | "btrfs-extent-06", | ||
| 106 | "btrfs-extent-07", | ||
| 107 | /* highest possible level */ | ||
| 108 | "btrfs-extent-08", | ||
| 109 | }; | ||
| 110 | #endif | ||
| 111 | |||
| 79 | /* | 112 | /* |
| 80 | * extents on the btree inode are pretty simple, there's one extent | 113 | * extents on the btree inode are pretty simple, there's one extent |
| 81 | * that covers the entire device | 114 | * that covers the entire device |
| @@ -348,6 +381,15 @@ static int check_tree_block_fsid(struct btrfs_root *root, | |||
| 348 | return ret; | 381 | return ret; |
| 349 | } | 382 | } |
| 350 | 383 | ||
| 384 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
| 385 | void btrfs_set_buffer_lockdep_class(struct extent_buffer *eb, int level) | ||
| 386 | { | ||
| 387 | lockdep_set_class_and_name(&eb->lock, | ||
| 388 | &btrfs_eb_class[level], | ||
| 389 | btrfs_eb_name[level]); | ||
| 390 | } | ||
| 391 | #endif | ||
| 392 | |||
| 351 | static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, | 393 | static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, |
| 352 | struct extent_state *state) | 394 | struct extent_state *state) |
| 353 | { | 395 | { |
| @@ -393,6 +435,8 @@ static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, | |||
| 393 | } | 435 | } |
| 394 | found_level = btrfs_header_level(eb); | 436 | found_level = btrfs_header_level(eb); |
| 395 | 437 | ||
| 438 | btrfs_set_buffer_lockdep_class(eb, found_level); | ||
| 439 | |||
| 396 | ret = csum_tree_block(root, eb, 1); | 440 | ret = csum_tree_block(root, eb, 1); |
| 397 | if (ret) | 441 | if (ret) |
| 398 | ret = -EIO; | 442 | ret = -EIO; |
| @@ -800,7 +844,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); | 844 | ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid); |
| 801 | 845 | ||
| 802 | if (ret == 0) | 846 | if (ret == 0) |
| 803 | buf->flags |= EXTENT_UPTODATE; | 847 | set_bit(EXTENT_BUFFER_UPTODATE, &buf->bflags); |
| 804 | else | 848 | else |
| 805 | WARN_ON(1); | 849 | WARN_ON(1); |
| 806 | return buf; | 850 | return buf; |
| @@ -814,6 +858,10 @@ int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
| 814 | if (btrfs_header_generation(buf) == | 858 | if (btrfs_header_generation(buf) == |
| 815 | root->fs_info->running_transaction->transid) { | 859 | root->fs_info->running_transaction->transid) { |
| 816 | WARN_ON(!btrfs_tree_locked(buf)); | 860 | WARN_ON(!btrfs_tree_locked(buf)); |
| 861 | |||
| 862 | /* ugh, clear_extent_buffer_dirty can be expensive */ | ||
| 863 | btrfs_set_lock_blocking(buf); | ||
| 864 | |||
| 817 | clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->io_tree, | 865 | clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->io_tree, |
| 818 | buf); | 866 | buf); |
| 819 | } | 867 | } |
| @@ -850,6 +898,14 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, | |||
| 850 | spin_lock_init(&root->list_lock); | 898 | spin_lock_init(&root->list_lock); |
| 851 | mutex_init(&root->objectid_mutex); | 899 | mutex_init(&root->objectid_mutex); |
| 852 | mutex_init(&root->log_mutex); | 900 | mutex_init(&root->log_mutex); |
| 901 | init_waitqueue_head(&root->log_writer_wait); | ||
| 902 | init_waitqueue_head(&root->log_commit_wait[0]); | ||
| 903 | init_waitqueue_head(&root->log_commit_wait[1]); | ||
| 904 | atomic_set(&root->log_commit[0], 0); | ||
| 905 | atomic_set(&root->log_commit[1], 0); | ||
| 906 | atomic_set(&root->log_writers, 0); | ||
| 907 | root->log_batch = 0; | ||
| 908 | root->log_transid = 0; | ||
| 853 | extent_io_tree_init(&root->dirty_log_pages, | 909 | extent_io_tree_init(&root->dirty_log_pages, |
| 854 | fs_info->btree_inode->i_mapping, GFP_NOFS); | 910 | fs_info->btree_inode->i_mapping, GFP_NOFS); |
| 855 | 911 | ||
| @@ -934,15 +990,16 @@ int btrfs_free_log_root_tree(struct btrfs_trans_handle *trans, | |||
| 934 | return 0; | 990 | return 0; |
| 935 | } | 991 | } |
| 936 | 992 | ||
| 937 | int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, | 993 | static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans, |
| 938 | struct btrfs_fs_info *fs_info) | 994 | struct btrfs_fs_info *fs_info) |
| 939 | { | 995 | { |
| 940 | struct btrfs_root *root; | 996 | struct btrfs_root *root; |
| 941 | struct btrfs_root *tree_root = fs_info->tree_root; | 997 | struct btrfs_root *tree_root = fs_info->tree_root; |
| 998 | struct extent_buffer *leaf; | ||
| 942 | 999 | ||
| 943 | root = kzalloc(sizeof(*root), GFP_NOFS); | 1000 | root = kzalloc(sizeof(*root), GFP_NOFS); |
| 944 | if (!root) | 1001 | if (!root) |
| 945 | return -ENOMEM; | 1002 | return ERR_PTR(-ENOMEM); |
| 946 | 1003 | ||
| 947 | __setup_root(tree_root->nodesize, tree_root->leafsize, | 1004 | __setup_root(tree_root->nodesize, tree_root->leafsize, |
| 948 | tree_root->sectorsize, tree_root->stripesize, | 1005 | tree_root->sectorsize, tree_root->stripesize, |
| @@ -951,12 +1008,23 @@ int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, | |||
| 951 | root->root_key.objectid = BTRFS_TREE_LOG_OBJECTID; | 1008 | root->root_key.objectid = BTRFS_TREE_LOG_OBJECTID; |
| 952 | root->root_key.type = BTRFS_ROOT_ITEM_KEY; | 1009 | root->root_key.type = BTRFS_ROOT_ITEM_KEY; |
| 953 | root->root_key.offset = BTRFS_TREE_LOG_OBJECTID; | 1010 | root->root_key.offset = BTRFS_TREE_LOG_OBJECTID; |
| 1011 | /* | ||
| 1012 | * log trees do not get reference counted because they go away | ||
| 1013 | * before a real commit is actually done. They do store pointers | ||
| 1014 | * to file data extents, and those reference counts still get | ||
| 1015 | * updated (along with back refs to the log tree). | ||
| 1016 | */ | ||
| 954 | root->ref_cows = 0; | 1017 | root->ref_cows = 0; |
| 955 | 1018 | ||
| 956 | root->node = btrfs_alloc_free_block(trans, root, root->leafsize, | 1019 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, |
| 957 | 0, BTRFS_TREE_LOG_OBJECTID, | 1020 | 0, BTRFS_TREE_LOG_OBJECTID, |
| 958 | trans->transid, 0, 0, 0); | 1021 | trans->transid, 0, 0, 0); |
| 1022 | if (IS_ERR(leaf)) { | ||
| 1023 | kfree(root); | ||
| 1024 | return ERR_CAST(leaf); | ||
| 1025 | } | ||
| 959 | 1026 | ||
| 1027 | root->node = leaf; | ||
| 960 | btrfs_set_header_nritems(root->node, 0); | 1028 | btrfs_set_header_nritems(root->node, 0); |
| 961 | btrfs_set_header_level(root->node, 0); | 1029 | btrfs_set_header_level(root->node, 0); |
| 962 | btrfs_set_header_bytenr(root->node, root->node->start); | 1030 | btrfs_set_header_bytenr(root->node, root->node->start); |
| @@ -968,7 +1036,48 @@ int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, | |||
| 968 | BTRFS_FSID_SIZE); | 1036 | BTRFS_FSID_SIZE); |
| 969 | btrfs_mark_buffer_dirty(root->node); | 1037 | btrfs_mark_buffer_dirty(root->node); |
| 970 | btrfs_tree_unlock(root->node); | 1038 | btrfs_tree_unlock(root->node); |
| 971 | fs_info->log_root_tree = root; | 1039 | return root; |
| 1040 | } | ||
| 1041 | |||
| 1042 | int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, | ||
| 1043 | struct btrfs_fs_info *fs_info) | ||
| 1044 | { | ||
| 1045 | struct btrfs_root *log_root; | ||
| 1046 | |||
| 1047 | log_root = alloc_log_tree(trans, fs_info); | ||
| 1048 | if (IS_ERR(log_root)) | ||
| 1049 | return PTR_ERR(log_root); | ||
| 1050 | WARN_ON(fs_info->log_root_tree); | ||
| 1051 | fs_info->log_root_tree = log_root; | ||
| 1052 | return 0; | ||
| 1053 | } | ||
| 1054 | |||
| 1055 | int btrfs_add_log_tree(struct btrfs_trans_handle *trans, | ||
| 1056 | struct btrfs_root *root) | ||
| 1057 | { | ||
| 1058 | struct btrfs_root *log_root; | ||
| 1059 | struct btrfs_inode_item *inode_item; | ||
| 1060 | |||
| 1061 | log_root = alloc_log_tree(trans, root->fs_info); | ||
| 1062 | if (IS_ERR(log_root)) | ||
| 1063 | return PTR_ERR(log_root); | ||
| 1064 | |||
| 1065 | log_root->last_trans = trans->transid; | ||
| 1066 | log_root->root_key.offset = root->root_key.objectid; | ||
| 1067 | |||
| 1068 | inode_item = &log_root->root_item.inode; | ||
| 1069 | inode_item->generation = cpu_to_le64(1); | ||
| 1070 | inode_item->size = cpu_to_le64(3); | ||
| 1071 | inode_item->nlink = cpu_to_le32(1); | ||
| 1072 | inode_item->nbytes = cpu_to_le64(root->leafsize); | ||
| 1073 | inode_item->mode = cpu_to_le32(S_IFDIR | 0755); | ||
| 1074 | |||
| 1075 | btrfs_set_root_bytenr(&log_root->root_item, log_root->node->start); | ||
| 1076 | btrfs_set_root_generation(&log_root->root_item, trans->transid); | ||
| 1077 | |||
| 1078 | WARN_ON(root->log_root); | ||
| 1079 | root->log_root = log_root; | ||
| 1080 | root->log_transid = 0; | ||
| 972 | return 0; | 1081 | return 0; |
| 973 | } | 1082 | } |
| 974 | 1083 | ||
| @@ -1136,7 +1245,6 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits) | |||
| 1136 | { | 1245 | { |
| 1137 | struct btrfs_fs_info *info = (struct btrfs_fs_info *)congested_data; | 1246 | struct btrfs_fs_info *info = (struct btrfs_fs_info *)congested_data; |
| 1138 | int ret = 0; | 1247 | int ret = 0; |
| 1139 | struct list_head *cur; | ||
| 1140 | struct btrfs_device *device; | 1248 | struct btrfs_device *device; |
| 1141 | struct backing_dev_info *bdi; | 1249 | struct backing_dev_info *bdi; |
| 1142 | #if 0 | 1250 | #if 0 |
| @@ -1144,8 +1252,7 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits) | |||
| 1144 | btrfs_congested_async(info, 0)) | 1252 | btrfs_congested_async(info, 0)) |
| 1145 | return 1; | 1253 | return 1; |
| 1146 | #endif | 1254 | #endif |
| 1147 | list_for_each(cur, &info->fs_devices->devices) { | 1255 | 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) | 1256 | if (!device->bdev) |
| 1150 | continue; | 1257 | continue; |
| 1151 | bdi = blk_get_backing_dev_info(device->bdev); | 1258 | bdi = blk_get_backing_dev_info(device->bdev); |
| @@ -1163,13 +1270,11 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits) | |||
| 1163 | */ | 1270 | */ |
| 1164 | static void __unplug_io_fn(struct backing_dev_info *bdi, struct page *page) | 1271 | static void __unplug_io_fn(struct backing_dev_info *bdi, struct page *page) |
| 1165 | { | 1272 | { |
| 1166 | struct list_head *cur; | ||
| 1167 | struct btrfs_device *device; | 1273 | struct btrfs_device *device; |
| 1168 | struct btrfs_fs_info *info; | 1274 | struct btrfs_fs_info *info; |
| 1169 | 1275 | ||
| 1170 | info = (struct btrfs_fs_info *)bdi->unplug_io_data; | 1276 | info = (struct btrfs_fs_info *)bdi->unplug_io_data; |
| 1171 | list_for_each(cur, &info->fs_devices->devices) { | 1277 | 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) | 1278 | if (!device->bdev) |
| 1174 | continue; | 1279 | continue; |
| 1175 | 1280 | ||
| @@ -1447,7 +1552,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1447 | INIT_LIST_HEAD(&fs_info->dead_roots); | 1552 | INIT_LIST_HEAD(&fs_info->dead_roots); |
| 1448 | INIT_LIST_HEAD(&fs_info->hashers); | 1553 | INIT_LIST_HEAD(&fs_info->hashers); |
| 1449 | INIT_LIST_HEAD(&fs_info->delalloc_inodes); | 1554 | INIT_LIST_HEAD(&fs_info->delalloc_inodes); |
| 1450 | spin_lock_init(&fs_info->hash_lock); | ||
| 1451 | spin_lock_init(&fs_info->delalloc_lock); | 1555 | spin_lock_init(&fs_info->delalloc_lock); |
| 1452 | spin_lock_init(&fs_info->new_trans_lock); | 1556 | spin_lock_init(&fs_info->new_trans_lock); |
| 1453 | spin_lock_init(&fs_info->ref_cache_lock); | 1557 | spin_lock_init(&fs_info->ref_cache_lock); |
| @@ -1535,10 +1639,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1535 | init_waitqueue_head(&fs_info->transaction_throttle); | 1639 | init_waitqueue_head(&fs_info->transaction_throttle); |
| 1536 | init_waitqueue_head(&fs_info->transaction_wait); | 1640 | init_waitqueue_head(&fs_info->transaction_wait); |
| 1537 | init_waitqueue_head(&fs_info->async_submit_wait); | 1641 | 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 | 1642 | ||
| 1543 | __setup_root(4096, 4096, 4096, 4096, tree_root, | 1643 | __setup_root(4096, 4096, 4096, 4096, tree_root, |
| 1544 | fs_info, BTRFS_ROOT_TREE_OBJECTID); | 1644 | fs_info, BTRFS_ROOT_TREE_OBJECTID); |
| @@ -1627,6 +1727,8 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1627 | * low idle thresh | 1727 | * low idle thresh |
| 1628 | */ | 1728 | */ |
| 1629 | fs_info->endio_workers.idle_thresh = 4; | 1729 | fs_info->endio_workers.idle_thresh = 4; |
| 1730 | fs_info->endio_meta_workers.idle_thresh = 4; | ||
| 1731 | |||
| 1630 | fs_info->endio_write_workers.idle_thresh = 64; | 1732 | fs_info->endio_write_workers.idle_thresh = 64; |
| 1631 | fs_info->endio_meta_write_workers.idle_thresh = 64; | 1733 | fs_info->endio_meta_write_workers.idle_thresh = 64; |
| 1632 | 1734 | ||
| @@ -1720,7 +1822,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1720 | ret = find_and_setup_root(tree_root, fs_info, | 1822 | ret = find_and_setup_root(tree_root, fs_info, |
| 1721 | BTRFS_DEV_TREE_OBJECTID, dev_root); | 1823 | BTRFS_DEV_TREE_OBJECTID, dev_root); |
| 1722 | dev_root->track_dirty = 1; | 1824 | dev_root->track_dirty = 1; |
| 1723 | |||
| 1724 | if (ret) | 1825 | if (ret) |
| 1725 | goto fail_extent_root; | 1826 | goto fail_extent_root; |
| 1726 | 1827 | ||
| @@ -1740,13 +1841,13 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1740 | fs_info->system_alloc_profile = fs_info->metadata_alloc_profile; | 1841 | fs_info->system_alloc_profile = fs_info->metadata_alloc_profile; |
| 1741 | fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root, | 1842 | fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root, |
| 1742 | "btrfs-cleaner"); | 1843 | "btrfs-cleaner"); |
| 1743 | if (!fs_info->cleaner_kthread) | 1844 | if (IS_ERR(fs_info->cleaner_kthread)) |
| 1744 | goto fail_csum_root; | 1845 | goto fail_csum_root; |
| 1745 | 1846 | ||
| 1746 | fs_info->transaction_kthread = kthread_run(transaction_kthread, | 1847 | fs_info->transaction_kthread = kthread_run(transaction_kthread, |
| 1747 | tree_root, | 1848 | tree_root, |
| 1748 | "btrfs-transaction"); | 1849 | "btrfs-transaction"); |
| 1749 | if (!fs_info->transaction_kthread) | 1850 | if (IS_ERR(fs_info->transaction_kthread)) |
| 1750 | goto fail_cleaner; | 1851 | goto fail_cleaner; |
| 1751 | 1852 | ||
| 1752 | if (btrfs_super_log_root(disk_super) != 0) { | 1853 | if (btrfs_super_log_root(disk_super) != 0) { |
| @@ -1828,13 +1929,14 @@ fail_sb_buffer: | |||
| 1828 | fail_iput: | 1929 | fail_iput: |
| 1829 | invalidate_inode_pages2(fs_info->btree_inode->i_mapping); | 1930 | invalidate_inode_pages2(fs_info->btree_inode->i_mapping); |
| 1830 | iput(fs_info->btree_inode); | 1931 | iput(fs_info->btree_inode); |
| 1831 | fail: | 1932 | |
| 1832 | btrfs_close_devices(fs_info->fs_devices); | 1933 | btrfs_close_devices(fs_info->fs_devices); |
| 1833 | btrfs_mapping_tree_free(&fs_info->mapping_tree); | 1934 | btrfs_mapping_tree_free(&fs_info->mapping_tree); |
| 1935 | bdi_destroy(&fs_info->bdi); | ||
| 1834 | 1936 | ||
| 1937 | fail: | ||
| 1835 | kfree(extent_root); | 1938 | kfree(extent_root); |
| 1836 | kfree(tree_root); | 1939 | kfree(tree_root); |
| 1837 | bdi_destroy(&fs_info->bdi); | ||
| 1838 | kfree(fs_info); | 1940 | kfree(fs_info); |
| 1839 | kfree(chunk_root); | 1941 | kfree(chunk_root); |
| 1840 | kfree(dev_root); | 1942 | kfree(dev_root); |
| @@ -1995,7 +2097,6 @@ static int write_dev_supers(struct btrfs_device *device, | |||
| 1995 | 2097 | ||
| 1996 | int write_all_supers(struct btrfs_root *root, int max_mirrors) | 2098 | int write_all_supers(struct btrfs_root *root, int max_mirrors) |
| 1997 | { | 2099 | { |
| 1998 | struct list_head *cur; | ||
| 1999 | struct list_head *head = &root->fs_info->fs_devices->devices; | 2100 | struct list_head *head = &root->fs_info->fs_devices->devices; |
| 2000 | struct btrfs_device *dev; | 2101 | struct btrfs_device *dev; |
| 2001 | struct btrfs_super_block *sb; | 2102 | struct btrfs_super_block *sb; |
| @@ -2011,8 +2112,7 @@ int write_all_supers(struct btrfs_root *root, int max_mirrors) | |||
| 2011 | 2112 | ||
| 2012 | sb = &root->fs_info->super_for_commit; | 2113 | sb = &root->fs_info->super_for_commit; |
| 2013 | dev_item = &sb->dev_item; | 2114 | dev_item = &sb->dev_item; |
| 2014 | list_for_each(cur, head) { | 2115 | list_for_each_entry(dev, head, dev_list) { |
| 2015 | dev = list_entry(cur, struct btrfs_device, dev_list); | ||
| 2016 | if (!dev->bdev) { | 2116 | if (!dev->bdev) { |
| 2017 | total_errors++; | 2117 | total_errors++; |
| 2018 | continue; | 2118 | continue; |
| @@ -2045,8 +2145,7 @@ int write_all_supers(struct btrfs_root *root, int max_mirrors) | |||
| 2045 | } | 2145 | } |
| 2046 | 2146 | ||
| 2047 | total_errors = 0; | 2147 | total_errors = 0; |
| 2048 | list_for_each(cur, head) { | 2148 | list_for_each_entry(dev, head, dev_list) { |
| 2049 | dev = list_entry(cur, struct btrfs_device, dev_list); | ||
| 2050 | if (!dev->bdev) | 2149 | if (!dev->bdev) |
| 2051 | continue; | 2150 | continue; |
| 2052 | if (!dev->in_fs_metadata || !dev->writeable) | 2151 | if (!dev->in_fs_metadata || !dev->writeable) |
| @@ -2260,6 +2359,8 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf) | |||
| 2260 | u64 transid = btrfs_header_generation(buf); | 2359 | u64 transid = btrfs_header_generation(buf); |
| 2261 | struct inode *btree_inode = root->fs_info->btree_inode; | 2360 | struct inode *btree_inode = root->fs_info->btree_inode; |
| 2262 | 2361 | ||
| 2362 | btrfs_set_lock_blocking(buf); | ||
| 2363 | |||
| 2263 | WARN_ON(!btrfs_tree_locked(buf)); | 2364 | WARN_ON(!btrfs_tree_locked(buf)); |
| 2264 | if (transid != root->fs_info->generation) { | 2365 | if (transid != root->fs_info->generation) { |
| 2265 | printk(KERN_CRIT "btrfs transid mismatch buffer %llu, " | 2366 | printk(KERN_CRIT "btrfs transid mismatch buffer %llu, " |
| @@ -2302,14 +2403,13 @@ int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid) | |||
| 2302 | int ret; | 2403 | int ret; |
| 2303 | ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid); | 2404 | ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid); |
| 2304 | if (ret == 0) | 2405 | if (ret == 0) |
| 2305 | buf->flags |= EXTENT_UPTODATE; | 2406 | set_bit(EXTENT_BUFFER_UPTODATE, &buf->bflags); |
| 2306 | return ret; | 2407 | return ret; |
| 2307 | } | 2408 | } |
| 2308 | 2409 | ||
| 2309 | int btree_lock_page_hook(struct page *page) | 2410 | int btree_lock_page_hook(struct page *page) |
| 2310 | { | 2411 | { |
| 2311 | struct inode *inode = page->mapping->host; | 2412 | 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; | 2413 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
| 2314 | struct extent_buffer *eb; | 2414 | struct extent_buffer *eb; |
| 2315 | unsigned long len; | 2415 | unsigned long len; |
| @@ -2324,9 +2424,7 @@ int btree_lock_page_hook(struct page *page) | |||
| 2324 | goto out; | 2424 | goto out; |
| 2325 | 2425 | ||
| 2326 | btrfs_tree_lock(eb); | 2426 | btrfs_tree_lock(eb); |
| 2327 | spin_lock(&root->fs_info->hash_lock); | ||
| 2328 | btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN); | 2427 | btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN); |
| 2329 | spin_unlock(&root->fs_info->hash_lock); | ||
| 2330 | btrfs_tree_unlock(eb); | 2428 | btrfs_tree_unlock(eb); |
| 2331 | free_extent_buffer(eb); | 2429 | free_extent_buffer(eb); |
| 2332 | out: | 2430 | out: |
