aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-05-12 12:59:19 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:03 -0400
commitca7a79ad8dbe24669a8ced01f9fc0126b872745d (patch)
tree0d53d8e6fd9ff9aece4e703581918c7817175d5d
parent188de649c51f03df3f8a601aea0110a3870815c2 (diff)
Btrfs: Pass down the expected generation number when reading tree blocks
Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/ctree.c55
-rw-r--r--fs/btrfs/disk-io.c30
-rw-r--r--fs/btrfs/disk-io.h7
-rw-r--r--fs/btrfs/extent-tree.c15
-rw-r--r--fs/btrfs/print-tree.c3
-rw-r--r--fs/btrfs/tree-defrag.c9
6 files changed, 55 insertions, 64 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 29e5674b043d..289d71d8653a 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -302,6 +302,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
302 struct extent_buffer *cur; 302 struct extent_buffer *cur;
303 struct extent_buffer *tmp; 303 struct extent_buffer *tmp;
304 u64 blocknr; 304 u64 blocknr;
305 u64 gen;
305 u64 search_start = *last_ret; 306 u64 search_start = *last_ret;
306 u64 last_block = 0; 307 u64 last_block = 0;
307 u64 other; 308 u64 other;
@@ -354,6 +355,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
354 355
355 progress_passed = 1; 356 progress_passed = 1;
356 blocknr = btrfs_node_blockptr(parent, i); 357 blocknr = btrfs_node_blockptr(parent, i);
358 gen = btrfs_node_ptr_generation(parent, i);
357 if (last_block == 0) 359 if (last_block == 0)
358 last_block = blocknr; 360 last_block = blocknr;
359 361
@@ -387,15 +389,14 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
387 } 389 }
388 if (!cur) { 390 if (!cur) {
389 cur = read_tree_block(root, blocknr, 391 cur = read_tree_block(root, blocknr,
390 blocksize); 392 blocksize, gen);
391 } else if (!uptodate) { 393 } else if (!uptodate) {
392 btrfs_read_buffer(cur); 394 btrfs_read_buffer(cur, gen);
393 } 395 }
394 } 396 }
395 if (search_start == 0) 397 if (search_start == 0)
396 search_start = last_block; 398 search_start = last_block;
397 399
398 btrfs_verify_block_csum(root, cur);
399 err = __btrfs_cow_block(trans, root, cur, parent, i, 400 err = __btrfs_cow_block(trans, root, cur, parent, i,
400 &tmp, search_start, 401 &tmp, search_start,
401 min(16 * blocksize, 402 min(16 * blocksize,
@@ -696,12 +697,17 @@ static int bin_search(struct extent_buffer *eb, struct btrfs_key *key,
696static struct extent_buffer *read_node_slot(struct btrfs_root *root, 697static struct extent_buffer *read_node_slot(struct btrfs_root *root,
697 struct extent_buffer *parent, int slot) 698 struct extent_buffer *parent, int slot)
698{ 699{
700 int level = btrfs_header_level(parent);
699 if (slot < 0) 701 if (slot < 0)
700 return NULL; 702 return NULL;
701 if (slot >= btrfs_header_nritems(parent)) 703 if (slot >= btrfs_header_nritems(parent))
702 return NULL; 704 return NULL;
705
706 BUG_ON(level == 0);
707
703 return read_tree_block(root, btrfs_node_blockptr(parent, slot), 708 return read_tree_block(root, btrfs_node_blockptr(parent, slot),
704 btrfs_level_size(root, btrfs_header_level(parent) - 1)); 709 btrfs_level_size(root, level - 1),
710 btrfs_node_ptr_generation(parent, slot));
705} 711}
706 712
707static int balance_level(struct btrfs_trans_handle *trans, 713static int balance_level(struct btrfs_trans_handle *trans,
@@ -1076,7 +1082,8 @@ static void reada_for_search(struct btrfs_root *root, struct btrfs_path *path,
1076 if ((search >= lowest_read && search <= highest_read) || 1082 if ((search >= lowest_read && search <= highest_read) ||
1077 (search < lowest_read && lowest_read - search <= 32768) || 1083 (search < lowest_read && lowest_read - search <= 32768) ||
1078 (search > highest_read && search - highest_read <= 32768)) { 1084 (search > highest_read && search - highest_read <= 32768)) {
1079 readahead_tree_block(root, search, blocksize); 1085 readahead_tree_block(root, search, blocksize,
1086 btrfs_node_ptr_generation(node, nr));
1080 nread += blocksize; 1087 nread += blocksize;
1081 } 1088 }
1082 nscan++; 1089 nscan++;
@@ -1109,8 +1116,6 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
1109 ins_len, int cow) 1116 ins_len, int cow)
1110{ 1117{
1111 struct extent_buffer *b; 1118 struct extent_buffer *b;
1112 u64 bytenr;
1113 u64 ptr_gen;
1114 int slot; 1119 int slot;
1115 int ret; 1120 int ret;
1116 int level; 1121 int level;
@@ -1174,20 +1179,12 @@ again:
1174 /* this is only true while dropping a snapshot */ 1179 /* this is only true while dropping a snapshot */
1175 if (level == lowest_level) 1180 if (level == lowest_level)
1176 break; 1181 break;
1177 bytenr = btrfs_node_blockptr(b, slot); 1182
1178 ptr_gen = btrfs_node_ptr_generation(b, slot);
1179 if (should_reada) 1183 if (should_reada)
1180 reada_for_search(root, p, level, slot, 1184 reada_for_search(root, p, level, slot,
1181 key->objectid); 1185 key->objectid);
1182 b = read_tree_block(root, bytenr, 1186
1183 btrfs_level_size(root, level - 1)); 1187 b = read_node_slot(root, b, slot);
1184 if (ptr_gen != btrfs_header_generation(b)) {
1185 printk("block %llu bad gen wanted %llu "
1186 "found %llu\n",
1187 (unsigned long long)b->start,
1188 (unsigned long long)ptr_gen,
1189 (unsigned long long)btrfs_header_generation(b));
1190 }
1191 } else { 1188 } else {
1192 p->slots[level] = slot; 1189 p->slots[level] = slot;
1193 if (ins_len > 0 && btrfs_leaf_free_space(root, b) < 1190 if (ins_len > 0 && btrfs_leaf_free_space(root, b) <
@@ -1650,8 +1647,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
1650 if (slot >= btrfs_header_nritems(upper) - 1) 1647 if (slot >= btrfs_header_nritems(upper) - 1)
1651 return 1; 1648 return 1;
1652 1649
1653 right = read_tree_block(root, btrfs_node_blockptr(upper, slot + 1), 1650 right = read_node_slot(root, upper, slot + 1);
1654 root->leafsize);
1655 free_space = btrfs_leaf_free_space(root, right); 1651 free_space = btrfs_leaf_free_space(root, right);
1656 if (free_space < data_size + sizeof(struct btrfs_item)) { 1652 if (free_space < data_size + sizeof(struct btrfs_item)) {
1657 free_extent_buffer(right); 1653 free_extent_buffer(right);
@@ -1826,8 +1822,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
1826 return 1; 1822 return 1;
1827 } 1823 }
1828 1824
1829 left = read_tree_block(root, btrfs_node_blockptr(path->nodes[1], 1825 left = read_node_slot(root, path->nodes[1], slot - 1);
1830 slot - 1), root->leafsize);
1831 free_space = btrfs_leaf_free_space(root, left); 1826 free_space = btrfs_leaf_free_space(root, left);
1832 if (free_space < data_size + sizeof(struct btrfs_item)) { 1827 if (free_space < data_size + sizeof(struct btrfs_item)) {
1833 free_extent_buffer(left); 1828 free_extent_buffer(left);
@@ -2742,7 +2737,6 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
2742 */ 2737 */
2743int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path) 2738int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path)
2744{ 2739{
2745 u64 bytenr;
2746 int slot; 2740 int slot;
2747 int level = 1; 2741 int level = 1;
2748 struct extent_buffer *c; 2742 struct extent_buffer *c;
@@ -2762,12 +2756,10 @@ int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path)
2762 } 2756 }
2763 slot--; 2757 slot--;
2764 2758
2765 bytenr = btrfs_node_blockptr(c, slot);
2766 if (next) 2759 if (next)
2767 free_extent_buffer(next); 2760 free_extent_buffer(next);
2768 2761
2769 next = read_tree_block(root, bytenr, 2762 next = read_node_slot(root, c, slot);
2770 btrfs_level_size(root, level - 1));
2771 break; 2763 break;
2772 } 2764 }
2773 path->slots[level] = slot; 2765 path->slots[level] = slot;
@@ -2782,8 +2774,7 @@ int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path)
2782 path->slots[level] = slot; 2774 path->slots[level] = slot;
2783 if (!level) 2775 if (!level)
2784 break; 2776 break;
2785 next = read_tree_block(root, btrfs_node_blockptr(next, slot), 2777 next = read_node_slot(root, next, slot);
2786 btrfs_level_size(root, level - 1));
2787 } 2778 }
2788 return 0; 2779 return 0;
2789} 2780}
@@ -2797,7 +2788,6 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
2797{ 2788{
2798 int slot; 2789 int slot;
2799 int level = 1; 2790 int level = 1;
2800 u64 bytenr;
2801 struct extent_buffer *c; 2791 struct extent_buffer *c;
2802 struct extent_buffer *next = NULL; 2792 struct extent_buffer *next = NULL;
2803 2793
@@ -2814,15 +2804,13 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
2814 continue; 2804 continue;
2815 } 2805 }
2816 2806
2817 bytenr = btrfs_node_blockptr(c, slot);
2818 if (next) 2807 if (next)
2819 free_extent_buffer(next); 2808 free_extent_buffer(next);
2820 2809
2821 if (path->reada) 2810 if (path->reada)
2822 reada_for_search(root, path, level, slot, 0); 2811 reada_for_search(root, path, level, slot, 0);
2823 2812
2824 next = read_tree_block(root, bytenr, 2813 next = read_node_slot(root, c, slot);
2825 btrfs_level_size(root, level -1));
2826 break; 2814 break;
2827 } 2815 }
2828 path->slots[level] = slot; 2816 path->slots[level] = slot;
@@ -2836,8 +2824,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
2836 break; 2824 break;
2837 if (path->reada) 2825 if (path->reada)
2838 reada_for_search(root, path, level, 0, 0); 2826 reada_for_search(root, path, level, 0, 0);
2839 next = read_tree_block(root, btrfs_node_blockptr(next, 0), 2827 next = read_node_slot(root, next, 0);
2840 btrfs_level_size(root, level - 1));
2841 } 2828 }
2842 return 0; 2829 return 0;
2843} 2830}
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index c3083165b172..edee7a44f861 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -207,7 +207,7 @@ static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf,
207 207
208static int btree_read_extent_buffer_pages(struct btrfs_root *root, 208static int btree_read_extent_buffer_pages(struct btrfs_root *root,
209 struct extent_buffer *eb, 209 struct extent_buffer *eb,
210 u64 start) 210 u64 start, u64 parent_transid)
211{ 211{
212 struct extent_io_tree *io_tree; 212 struct extent_io_tree *io_tree;
213 int ret; 213 int ret;
@@ -254,7 +254,8 @@ int csum_dirty_buffer(struct btrfs_root *root, struct page *page)
254 WARN_ON(1); 254 WARN_ON(1);
255 } 255 }
256 eb = alloc_extent_buffer(tree, start, len, page, GFP_NOFS); 256 eb = alloc_extent_buffer(tree, start, len, page, GFP_NOFS);
257 ret = btree_read_extent_buffer_pages(root, eb, start + PAGE_CACHE_SIZE); 257 ret = btree_read_extent_buffer_pages(root, eb, start + PAGE_CACHE_SIZE,
258 btrfs_header_generation(eb));
258 BUG_ON(ret); 259 BUG_ON(ret);
259 btrfs_clear_buffer_defrag(eb); 260 btrfs_clear_buffer_defrag(eb);
260 found_start = btrfs_header_bytenr(eb); 261 found_start = btrfs_header_bytenr(eb);
@@ -562,7 +563,8 @@ static struct address_space_operations btree_aops = {
562 .sync_page = block_sync_page, 563 .sync_page = block_sync_page,
563}; 564};
564 565
565int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize) 566int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize,
567 u64 parent_transid)
566{ 568{
567 struct extent_buffer *buf = NULL; 569 struct extent_buffer *buf = NULL;
568 struct inode *btree_inode = root->fs_info->btree_inode; 570 struct inode *btree_inode = root->fs_info->btree_inode;
@@ -592,12 +594,6 @@ static int close_all_devices(struct btrfs_fs_info *fs_info)
592 return 0; 594 return 0;
593} 595}
594 596
595int btrfs_verify_block_csum(struct btrfs_root *root,
596 struct extent_buffer *buf)
597{
598 return btrfs_buffer_uptodate(buf);
599}
600
601struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root, 597struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root,
602 u64 bytenr, u32 blocksize) 598 u64 bytenr, u32 blocksize)
603{ 599{
@@ -621,7 +617,7 @@ struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root,
621 617
622 618
623struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr, 619struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
624 u32 blocksize) 620 u32 blocksize, u64 parent_transid)
625{ 621{
626 struct extent_buffer *buf = NULL; 622 struct extent_buffer *buf = NULL;
627 struct inode *btree_inode = root->fs_info->btree_inode; 623 struct inode *btree_inode = root->fs_info->btree_inode;
@@ -634,7 +630,7 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
634 if (!buf) 630 if (!buf)
635 return NULL; 631 return NULL;
636 632
637 ret = btree_read_extent_buffer_pages(root, buf, 0); 633 ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid);
638 634
639 if (ret == 0) { 635 if (ret == 0) {
640 buf->flags |= EXTENT_UPTODATE; 636 buf->flags |= EXTENT_UPTODATE;
@@ -715,7 +711,7 @@ static int find_and_setup_root(struct btrfs_root *tree_root,
715 711
716 blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); 712 blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
717 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), 713 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
718 blocksize); 714 blocksize, 0);
719 BUG_ON(!root->node); 715 BUG_ON(!root->node);
720 return 0; 716 return 0;
721} 717}
@@ -771,7 +767,7 @@ out:
771 } 767 }
772 blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); 768 blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
773 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), 769 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
774 blocksize); 770 blocksize, 0);
775 BUG_ON(!root->node); 771 BUG_ON(!root->node);
776insert: 772insert:
777 root->ref_cows = 1; 773 root->ref_cows = 1;
@@ -1288,7 +1284,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1288 1284
1289 chunk_root->node = read_tree_block(chunk_root, 1285 chunk_root->node = read_tree_block(chunk_root,
1290 btrfs_super_chunk_root(disk_super), 1286 btrfs_super_chunk_root(disk_super),
1291 blocksize); 1287 blocksize, 0);
1292 BUG_ON(!chunk_root->node); 1288 BUG_ON(!chunk_root->node);
1293 1289
1294 read_extent_buffer(chunk_root->node, fs_info->chunk_tree_uuid, 1290 read_extent_buffer(chunk_root->node, fs_info->chunk_tree_uuid,
@@ -1304,7 +1300,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1304 1300
1305 tree_root->node = read_tree_block(tree_root, 1301 tree_root->node = read_tree_block(tree_root,
1306 btrfs_super_root(disk_super), 1302 btrfs_super_root(disk_super),
1307 blocksize); 1303 blocksize, 0);
1308 if (!tree_root->node) 1304 if (!tree_root->node)
1309 goto fail_sb_buffer; 1305 goto fail_sb_buffer;
1310 1306
@@ -1732,11 +1728,11 @@ int btrfs_clear_buffer_defrag(struct extent_buffer *buf)
1732 EXTENT_DEFRAG, GFP_NOFS); 1728 EXTENT_DEFRAG, GFP_NOFS);
1733} 1729}
1734 1730
1735int btrfs_read_buffer(struct extent_buffer *buf) 1731int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid)
1736{ 1732{
1737 struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root; 1733 struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root;
1738 int ret; 1734 int ret;
1739 ret = btree_read_extent_buffer_pages(root, buf, 0); 1735 ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid);
1740 if (ret == 0) { 1736 if (ret == 0) {
1741 buf->flags |= EXTENT_UPTODATE; 1737 buf->flags |= EXTENT_UPTODATE;
1742 } 1738 }
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index 5d5f6979c41c..e29c895d5230 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -25,8 +25,9 @@ struct btrfs_device;
25struct btrfs_fs_devices; 25struct btrfs_fs_devices;
26 26
27struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr, 27struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
28 u32 blocksize); 28 u32 blocksize, u64 parent_transid);
29int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize); 29int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize,
30 u64 parent_transid);
30struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root, 31struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root,
31 u64 bytenr, u32 blocksize); 32 u64 bytenr, u32 blocksize);
32int clean_tree_block(struct btrfs_trans_handle *trans, 33int clean_tree_block(struct btrfs_trans_handle *trans,
@@ -65,7 +66,7 @@ int btrfs_buffer_defrag(struct extent_buffer *buf);
65int btrfs_buffer_defrag_done(struct extent_buffer *buf); 66int btrfs_buffer_defrag_done(struct extent_buffer *buf);
66int btrfs_clear_buffer_defrag(struct extent_buffer *buf); 67int btrfs_clear_buffer_defrag(struct extent_buffer *buf);
67int btrfs_clear_buffer_defrag_done(struct extent_buffer *buf); 68int btrfs_clear_buffer_defrag_done(struct extent_buffer *buf);
68int btrfs_read_buffer(struct extent_buffer *buf); 69int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid);
69u32 btrfs_csum_data(struct btrfs_root *root, char *data, u32 seed, size_t len); 70u32 btrfs_csum_data(struct btrfs_root *root, char *data, u32 seed, size_t len);
70void btrfs_csum_final(u32 crc, char *result); 71void btrfs_csum_final(u32 crc, char *result);
71void btrfs_throttle(struct btrfs_root *root); 72void btrfs_throttle(struct btrfs_root *root);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index df95fb660d49..db07dde4a870 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -1338,7 +1338,8 @@ static int finish_current_insert(struct btrfs_trans_handle *trans,
1338 &extent_item, sizeof(extent_item)); 1338 &extent_item, sizeof(extent_item));
1339 clear_extent_bits(&info->extent_ins, start, end, EXTENT_LOCKED, 1339 clear_extent_bits(&info->extent_ins, start, end, EXTENT_LOCKED,
1340 GFP_NOFS); 1340 GFP_NOFS);
1341 eb = read_tree_block(extent_root, ins.objectid, ins.offset); 1341 eb = read_tree_block(extent_root, ins.objectid, ins.offset,
1342 trans->transid);
1342 level = btrfs_header_level(eb); 1343 level = btrfs_header_level(eb);
1343 if (level == 0) { 1344 if (level == 0) {
1344 btrfs_item_key(eb, &first, 0); 1345 btrfs_item_key(eb, &first, 0);
@@ -2076,7 +2077,8 @@ static void noinline reada_walk_down(struct btrfs_root *root,
2076 } 2077 }
2077 } 2078 }
2078 mutex_unlock(&root->fs_info->fs_mutex); 2079 mutex_unlock(&root->fs_info->fs_mutex);
2079 ret = readahead_tree_block(root, bytenr, blocksize); 2080 ret = readahead_tree_block(root, bytenr, blocksize,
2081 btrfs_node_ptr_generation(node, i));
2080 last = bytenr + blocksize; 2082 last = bytenr + blocksize;
2081 cond_resched(); 2083 cond_resched();
2082 mutex_lock(&root->fs_info->fs_mutex); 2084 mutex_lock(&root->fs_info->fs_mutex);
@@ -2096,6 +2098,7 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
2096 u64 root_owner; 2098 u64 root_owner;
2097 u64 root_gen; 2099 u64 root_gen;
2098 u64 bytenr; 2100 u64 bytenr;
2101 u64 ptr_gen;
2099 struct extent_buffer *next; 2102 struct extent_buffer *next;
2100 struct extent_buffer *cur; 2103 struct extent_buffer *cur;
2101 struct extent_buffer *parent; 2104 struct extent_buffer *parent;
@@ -2132,6 +2135,7 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
2132 break; 2135 break;
2133 } 2136 }
2134 bytenr = btrfs_node_blockptr(cur, path->slots[*level]); 2137 bytenr = btrfs_node_blockptr(cur, path->slots[*level]);
2138 ptr_gen = btrfs_node_ptr_generation(cur, path->slots[*level]);
2135 blocksize = btrfs_level_size(root, *level - 1); 2139 blocksize = btrfs_level_size(root, *level - 1);
2136 ret = lookup_extent_ref(trans, root, bytenr, blocksize, &refs); 2140 ret = lookup_extent_ref(trans, root, bytenr, blocksize, &refs);
2137 BUG_ON(ret); 2141 BUG_ON(ret);
@@ -2152,7 +2156,8 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
2152 reada_walk_down(root, cur, path->slots[*level]); 2156 reada_walk_down(root, cur, path->slots[*level]);
2153 2157
2154 mutex_unlock(&root->fs_info->fs_mutex); 2158 mutex_unlock(&root->fs_info->fs_mutex);
2155 next = read_tree_block(root, bytenr, blocksize); 2159 next = read_tree_block(root, bytenr, blocksize,
2160 ptr_gen);
2156 mutex_lock(&root->fs_info->fs_mutex); 2161 mutex_lock(&root->fs_info->fs_mutex);
2157 2162
2158 /* we've dropped the lock, double check */ 2163 /* we've dropped the lock, double check */
@@ -2173,8 +2178,6 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
2173 BUG_ON(ret); 2178 BUG_ON(ret);
2174 continue; 2179 continue;
2175 } 2180 }
2176 } else if (next) {
2177 btrfs_verify_block_csum(root, next);
2178 } 2181 }
2179 WARN_ON(*level <= 0); 2182 WARN_ON(*level <= 0);
2180 if (path->nodes[*level-1]) 2183 if (path->nodes[*level-1])
@@ -2609,7 +2612,7 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
2609 int i; 2612 int i;
2610 2613
2611 eb = read_tree_block(found_root, extent_key->objectid, 2614 eb = read_tree_block(found_root, extent_key->objectid,
2612 extent_key->offset); 2615 extent_key->offset, 0);
2613 level = btrfs_header_level(eb); 2616 level = btrfs_header_level(eb);
2614 2617
2615 if (level == 0) 2618 if (level == 0)
diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c
index e99f3249d05a..14d863720302 100644
--- a/fs/btrfs/print-tree.c
+++ b/fs/btrfs/print-tree.c
@@ -186,7 +186,8 @@ void btrfs_print_tree(struct btrfs_root *root, struct extent_buffer *c)
186 for (i = 0; i < nr; i++) { 186 for (i = 0; i < nr; i++) {
187 struct extent_buffer *next = read_tree_block(root, 187 struct extent_buffer *next = read_tree_block(root,
188 btrfs_node_blockptr(c, i), 188 btrfs_node_blockptr(c, i),
189 btrfs_level_size(root, level - 1)); 189 btrfs_level_size(root, level - 1),
190 btrfs_node_ptr_generation(c, i));
190 if (btrfs_is_leaf(next) && 191 if (btrfs_is_leaf(next) &&
191 btrfs_header_level(c) != 1) 192 btrfs_header_level(c) != 1)
192 BUG(); 193 BUG();
diff --git a/fs/btrfs/tree-defrag.c b/fs/btrfs/tree-defrag.c
index 256af1870eef..5085e9e693b9 100644
--- a/fs/btrfs/tree-defrag.c
+++ b/fs/btrfs/tree-defrag.c
@@ -28,6 +28,7 @@ static void reada_defrag(struct btrfs_root *root,
28 int i; 28 int i;
29 u32 nritems; 29 u32 nritems;
30 u64 bytenr; 30 u64 bytenr;
31 u64 gen;
31 u32 blocksize; 32 u32 blocksize;
32 int ret; 33 int ret;
33 34
@@ -35,7 +36,8 @@ static void reada_defrag(struct btrfs_root *root,
35 nritems = btrfs_header_nritems(node); 36 nritems = btrfs_header_nritems(node);
36 for (i = 0; i < nritems; i++) { 37 for (i = 0; i < nritems; i++) {
37 bytenr = btrfs_node_blockptr(node, i); 38 bytenr = btrfs_node_blockptr(node, i);
38 ret = readahead_tree_block(root, bytenr, blocksize); 39 gen = btrfs_node_ptr_generation(node, i);
40 ret = readahead_tree_block(root, bytenr, blocksize, gen);
39 if (ret) 41 if (ret)
40 break; 42 break;
41 } 43 }
@@ -101,10 +103,11 @@ static int defrag_walk_down(struct btrfs_trans_handle *trans,
101 path->slots[*level]++; 103 path->slots[*level]++;
102 continue; 104 continue;
103 } 105 }
104 btrfs_verify_block_csum(root, next);
105 } else { 106 } else {
106 next = read_tree_block(root, bytenr, 107 next = read_tree_block(root, bytenr,
107 btrfs_level_size(root, *level - 1)); 108 btrfs_level_size(root, *level - 1),
109 btrfs_node_ptr_generation(cur,
110 path->slots[*level]));
108 } 111 }
109 ret = btrfs_cow_block(trans, root, next, path->nodes[*level], 112 ret = btrfs_cow_block(trans, root, next, path->nodes[*level],
110 path->slots[*level], &next); 113 path->slots[*level], &next);