aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.c
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 /fs/btrfs/ctree.c
parent188de649c51f03df3f8a601aea0110a3870815c2 (diff)
Btrfs: Pass down the expected generation number when reading tree blocks
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r--fs/btrfs/ctree.c55
1 files changed, 21 insertions, 34 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}