Commit ca7a79ad8dbe24669a8ced01f9fc0126b872745d

Authored by Chris Mason
1 parent 188de649c5

Btrfs: Pass down the expected generation number when reading tree blocks

Signed-off-by: Chris Mason <chris.mason@oracle.com>

Showing 6 changed files with 55 additions and 64 deletions Side-by-side Diff

... ... @@ -302,6 +302,7 @@
302 302 struct extent_buffer *cur;
303 303 struct extent_buffer *tmp;
304 304 u64 blocknr;
  305 + u64 gen;
305 306 u64 search_start = *last_ret;
306 307 u64 last_block = 0;
307 308 u64 other;
... ... @@ -354,6 +355,7 @@
354 355  
355 356 progress_passed = 1;
356 357 blocknr = btrfs_node_blockptr(parent, i);
  358 + gen = btrfs_node_ptr_generation(parent, i);
357 359 if (last_block == 0)
358 360 last_block = blocknr;
359 361  
360 362  
361 363  
... ... @@ -387,15 +389,14 @@
387 389 }
388 390 if (!cur) {
389 391 cur = read_tree_block(root, blocknr,
390   - blocksize);
  392 + blocksize, gen);
391 393 } else if (!uptodate) {
392   - btrfs_read_buffer(cur);
  394 + btrfs_read_buffer(cur, gen);
393 395 }
394 396 }
395 397 if (search_start == 0)
396 398 search_start = last_block;
397 399  
398   - btrfs_verify_block_csum(root, cur);
399 400 err = __btrfs_cow_block(trans, root, cur, parent, i,
400 401 &tmp, search_start,
401 402 min(16 * blocksize,
402 403  
403 404  
... ... @@ -696,12 +697,17 @@
696 697 static struct extent_buffer *read_node_slot(struct btrfs_root *root,
697 698 struct extent_buffer *parent, int slot)
698 699 {
  700 + int level = btrfs_header_level(parent);
699 701 if (slot < 0)
700 702 return NULL;
701 703 if (slot >= btrfs_header_nritems(parent))
702 704 return NULL;
  705 +
  706 + BUG_ON(level == 0);
  707 +
703 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  
707 713 static int balance_level(struct btrfs_trans_handle *trans,
... ... @@ -1076,7 +1082,8 @@
1076 1082 if ((search >= lowest_read && search <= highest_read) ||
1077 1083 (search < lowest_read && lowest_read - search <= 32768) ||
1078 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 1087 nread += blocksize;
1081 1088 }
1082 1089 nscan++;
... ... @@ -1109,8 +1116,6 @@
1109 1116 ins_len, int cow)
1110 1117 {
1111 1118 struct extent_buffer *b;
1112   - u64 bytenr;
1113   - u64 ptr_gen;
1114 1119 int slot;
1115 1120 int ret;
1116 1121 int level;
1117 1122  
... ... @@ -1174,20 +1179,12 @@
1174 1179 /* this is only true while dropping a snapshot */
1175 1180 if (level == lowest_level)
1176 1181 break;
1177   - bytenr = btrfs_node_blockptr(b, slot);
1178   - ptr_gen = btrfs_node_ptr_generation(b, slot);
  1182 +
1179 1183 if (should_reada)
1180 1184 reada_for_search(root, p, level, slot,
1181 1185 key->objectid);
1182   - b = read_tree_block(root, bytenr,
1183   - btrfs_level_size(root, level - 1));
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   - }
  1186 +
  1187 + b = read_node_slot(root, b, slot);
1191 1188 } else {
1192 1189 p->slots[level] = slot;
1193 1190 if (ins_len > 0 && btrfs_leaf_free_space(root, b) <
... ... @@ -1650,8 +1647,7 @@
1650 1647 if (slot >= btrfs_header_nritems(upper) - 1)
1651 1648 return 1;
1652 1649  
1653   - right = read_tree_block(root, btrfs_node_blockptr(upper, slot + 1),
1654   - root->leafsize);
  1650 + right = read_node_slot(root, upper, slot + 1);
1655 1651 free_space = btrfs_leaf_free_space(root, right);
1656 1652 if (free_space < data_size + sizeof(struct btrfs_item)) {
1657 1653 free_extent_buffer(right);
... ... @@ -1826,8 +1822,7 @@
1826 1822 return 1;
1827 1823 }
1828 1824  
1829   - left = read_tree_block(root, btrfs_node_blockptr(path->nodes[1],
1830   - slot - 1), root->leafsize);
  1825 + left = read_node_slot(root, path->nodes[1], slot - 1);
1831 1826 free_space = btrfs_leaf_free_space(root, left);
1832 1827 if (free_space < data_size + sizeof(struct btrfs_item)) {
1833 1828 free_extent_buffer(left);
... ... @@ -2742,7 +2737,6 @@
2742 2737 */
2743 2738 int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path)
2744 2739 {
2745   - u64 bytenr;
2746 2740 int slot;
2747 2741 int level = 1;
2748 2742 struct extent_buffer *c;
2749 2743  
... ... @@ -2762,12 +2756,10 @@
2762 2756 }
2763 2757 slot--;
2764 2758  
2765   - bytenr = btrfs_node_blockptr(c, slot);
2766 2759 if (next)
2767 2760 free_extent_buffer(next);
2768 2761  
2769   - next = read_tree_block(root, bytenr,
2770   - btrfs_level_size(root, level - 1));
  2762 + next = read_node_slot(root, c, slot);
2771 2763 break;
2772 2764 }
2773 2765 path->slots[level] = slot;
... ... @@ -2782,8 +2774,7 @@
2782 2774 path->slots[level] = slot;
2783 2775 if (!level)
2784 2776 break;
2785   - next = read_tree_block(root, btrfs_node_blockptr(next, slot),
2786   - btrfs_level_size(root, level - 1));
  2777 + next = read_node_slot(root, next, slot);
2787 2778 }
2788 2779 return 0;
2789 2780 }
... ... @@ -2797,7 +2788,6 @@
2797 2788 {
2798 2789 int slot;
2799 2790 int level = 1;
2800   - u64 bytenr;
2801 2791 struct extent_buffer *c;
2802 2792 struct extent_buffer *next = NULL;
2803 2793  
2804 2794  
... ... @@ -2814,15 +2804,13 @@
2814 2804 continue;
2815 2805 }
2816 2806  
2817   - bytenr = btrfs_node_blockptr(c, slot);
2818 2807 if (next)
2819 2808 free_extent_buffer(next);
2820 2809  
2821 2810 if (path->reada)
2822 2811 reada_for_search(root, path, level, slot, 0);
2823 2812  
2824   - next = read_tree_block(root, bytenr,
2825   - btrfs_level_size(root, level -1));
  2813 + next = read_node_slot(root, c, slot);
2826 2814 break;
2827 2815 }
2828 2816 path->slots[level] = slot;
... ... @@ -2836,8 +2824,7 @@
2836 2824 break;
2837 2825 if (path->reada)
2838 2826 reada_for_search(root, path, level, 0, 0);
2839   - next = read_tree_block(root, btrfs_node_blockptr(next, 0),
2840   - btrfs_level_size(root, level - 1));
  2827 + next = read_node_slot(root, next, 0);
2841 2828 }
2842 2829 return 0;
2843 2830 }
... ... @@ -207,7 +207,7 @@
207 207  
208 208 static int btree_read_extent_buffer_pages(struct btrfs_root *root,
209 209 struct extent_buffer *eb,
210   - u64 start)
  210 + u64 start, u64 parent_transid)
211 211 {
212 212 struct extent_io_tree *io_tree;
213 213 int ret;
... ... @@ -254,7 +254,8 @@
254 254 WARN_ON(1);
255 255 }
256 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 259 BUG_ON(ret);
259 260 btrfs_clear_buffer_defrag(eb);
260 261 found_start = btrfs_header_bytenr(eb);
... ... @@ -562,7 +563,8 @@
562 563 .sync_page = block_sync_page,
563 564 };
564 565  
565   -int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize)
  566 +int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize,
  567 + u64 parent_transid)
566 568 {
567 569 struct extent_buffer *buf = NULL;
568 570 struct inode *btree_inode = root->fs_info->btree_inode;
... ... @@ -592,12 +594,6 @@
592 594 return 0;
593 595 }
594 596  
595   -int btrfs_verify_block_csum(struct btrfs_root *root,
596   - struct extent_buffer *buf)
597   -{
598   - return btrfs_buffer_uptodate(buf);
599   -}
600   -
601 597 struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root,
602 598 u64 bytenr, u32 blocksize)
603 599 {
... ... @@ -621,7 +617,7 @@
621 617  
622 618  
623 619 struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
624   - u32 blocksize)
  620 + u32 blocksize, u64 parent_transid)
625 621 {
626 622 struct extent_buffer *buf = NULL;
627 623 struct inode *btree_inode = root->fs_info->btree_inode;
... ... @@ -634,7 +630,7 @@
634 630 if (!buf)
635 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 635 if (ret == 0) {
640 636 buf->flags |= EXTENT_UPTODATE;
... ... @@ -715,7 +711,7 @@
715 711  
716 712 blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
717 713 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
718   - blocksize);
  714 + blocksize, 0);
719 715 BUG_ON(!root->node);
720 716 return 0;
721 717 }
... ... @@ -771,7 +767,7 @@
771 767 }
772 768 blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
773 769 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
774   - blocksize);
  770 + blocksize, 0);
775 771 BUG_ON(!root->node);
776 772 insert:
777 773 root->ref_cows = 1;
... ... @@ -1288,7 +1284,7 @@
1288 1284  
1289 1285 chunk_root->node = read_tree_block(chunk_root,
1290 1286 btrfs_super_chunk_root(disk_super),
1291   - blocksize);
  1287 + blocksize, 0);
1292 1288 BUG_ON(!chunk_root->node);
1293 1289  
1294 1290 read_extent_buffer(chunk_root->node, fs_info->chunk_tree_uuid,
... ... @@ -1304,7 +1300,7 @@
1304 1300  
1305 1301 tree_root->node = read_tree_block(tree_root,
1306 1302 btrfs_super_root(disk_super),
1307   - blocksize);
  1303 + blocksize, 0);
1308 1304 if (!tree_root->node)
1309 1305 goto fail_sb_buffer;
1310 1306  
1311 1307  
... ... @@ -1732,11 +1728,11 @@
1732 1728 EXTENT_DEFRAG, GFP_NOFS);
1733 1729 }
1734 1730  
1735   -int btrfs_read_buffer(struct extent_buffer *buf)
  1731 +int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid)
1736 1732 {
1737 1733 struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root;
1738 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 1736 if (ret == 0) {
1741 1737 buf->flags |= EXTENT_UPTODATE;
1742 1738 }
... ... @@ -25,8 +25,9 @@
25 25 struct btrfs_fs_devices;
26 26  
27 27 struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
28   - u32 blocksize);
29   -int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize);
  28 + u32 blocksize, u64 parent_transid);
  29 +int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize,
  30 + u64 parent_transid);
30 31 struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root,
31 32 u64 bytenr, u32 blocksize);
32 33 int clean_tree_block(struct btrfs_trans_handle *trans,
... ... @@ -65,7 +66,7 @@
65 66 int btrfs_buffer_defrag_done(struct extent_buffer *buf);
66 67 int btrfs_clear_buffer_defrag(struct extent_buffer *buf);
67 68 int btrfs_clear_buffer_defrag_done(struct extent_buffer *buf);
68   -int btrfs_read_buffer(struct extent_buffer *buf);
  69 +int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid);
69 70 u32 btrfs_csum_data(struct btrfs_root *root, char *data, u32 seed, size_t len);
70 71 void btrfs_csum_final(u32 crc, char *result);
71 72 void btrfs_throttle(struct btrfs_root *root);
fs/btrfs/extent-tree.c
... ... @@ -1338,7 +1338,8 @@
1338 1338 &extent_item, sizeof(extent_item));
1339 1339 clear_extent_bits(&info->extent_ins, start, end, EXTENT_LOCKED,
1340 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 1343 level = btrfs_header_level(eb);
1343 1344 if (level == 0) {
1344 1345 btrfs_item_key(eb, &first, 0);
... ... @@ -2076,7 +2077,8 @@
2076 2077 }
2077 2078 }
2078 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 2082 last = bytenr + blocksize;
2081 2083 cond_resched();
2082 2084 mutex_lock(&root->fs_info->fs_mutex);
... ... @@ -2096,6 +2098,7 @@
2096 2098 u64 root_owner;
2097 2099 u64 root_gen;
2098 2100 u64 bytenr;
  2101 + u64 ptr_gen;
2099 2102 struct extent_buffer *next;
2100 2103 struct extent_buffer *cur;
2101 2104 struct extent_buffer *parent;
... ... @@ -2132,6 +2135,7 @@
2132 2135 break;
2133 2136 }
2134 2137 bytenr = btrfs_node_blockptr(cur, path->slots[*level]);
  2138 + ptr_gen = btrfs_node_ptr_generation(cur, path->slots[*level]);
2135 2139 blocksize = btrfs_level_size(root, *level - 1);
2136 2140 ret = lookup_extent_ref(trans, root, bytenr, blocksize, &refs);
2137 2141 BUG_ON(ret);
... ... @@ -2152,7 +2156,8 @@
2152 2156 reada_walk_down(root, cur, path->slots[*level]);
2153 2157  
2154 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 2161 mutex_lock(&root->fs_info->fs_mutex);
2157 2162  
2158 2163 /* we've dropped the lock, double check */
... ... @@ -2173,8 +2178,6 @@
2173 2178 BUG_ON(ret);
2174 2179 continue;
2175 2180 }
2176   - } else if (next) {
2177   - btrfs_verify_block_csum(root, next);
2178 2181 }
2179 2182 WARN_ON(*level <= 0);
2180 2183 if (path->nodes[*level-1])
... ... @@ -2609,7 +2612,7 @@
2609 2612 int i;
2610 2613  
2611 2614 eb = read_tree_block(found_root, extent_key->objectid,
2612   - extent_key->offset);
  2615 + extent_key->offset, 0);
2613 2616 level = btrfs_header_level(eb);
2614 2617  
2615 2618 if (level == 0)
fs/btrfs/print-tree.c
... ... @@ -186,7 +186,8 @@
186 186 for (i = 0; i < nr; i++) {
187 187 struct extent_buffer *next = read_tree_block(root,
188 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 191 if (btrfs_is_leaf(next) &&
191 192 btrfs_header_level(c) != 1)
192 193 BUG();
fs/btrfs/tree-defrag.c
... ... @@ -28,6 +28,7 @@
28 28 int i;
29 29 u32 nritems;
30 30 u64 bytenr;
  31 + u64 gen;
31 32 u32 blocksize;
32 33 int ret;
33 34  
... ... @@ -35,7 +36,8 @@
35 36 nritems = btrfs_header_nritems(node);
36 37 for (i = 0; i < nritems; i++) {
37 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 41 if (ret)
40 42 break;
41 43 }
42 44  
... ... @@ -101,10 +103,11 @@
101 103 path->slots[*level]++;
102 104 continue;
103 105 }
104   - btrfs_verify_block_csum(root, next);
105 106 } else {
106 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 112 ret = btrfs_cow_block(trans, root, next, path->nodes[*level],
110 113 path->slots[*level], &next);