aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorYan Zheng <zheng.yan@oracle.com>2008-12-17 10:21:48 -0500
committerChris Mason <chris.mason@oracle.com>2008-12-17 10:21:48 -0500
commit87b29b208c6c38f3446d2de6ece946e2459052cf (patch)
tree43e717289e1e8446fced4093ab39667bba9ea60a /fs/btrfs
parentd7f735d0bc68c411abda0a612e1421bdade649cc (diff)
Btrfs: properly check free space for tree balancing
btrfs_insert_empty_items takes the space needed by the btrfs_item structure into account when calculating the required free space. So the tree balancing code shouldn't add sizeof(struct btrfs_item) to the size when checking the free space. This patch removes these superfluous additions. Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ctree.c52
-rw-r--r--fs/btrfs/file-item.c4
-rw-r--r--fs/btrfs/tree-log.c9
3 files changed, 32 insertions, 33 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index f6f7a6af0357..7fad2e3ad6ff 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -1587,8 +1587,8 @@ cow_done:
1587 btrfs_tree_lock(b); 1587 btrfs_tree_lock(b);
1588 } else { 1588 } else {
1589 p->slots[level] = slot; 1589 p->slots[level] = slot;
1590 if (ins_len > 0 && btrfs_leaf_free_space(root, b) < 1590 if (ins_len > 0 &&
1591 sizeof(struct btrfs_item) + ins_len) { 1591 btrfs_leaf_free_space(root, b) < ins_len) {
1592 int sret = split_leaf(trans, root, key, 1592 int sret = split_leaf(trans, root, key,
1593 p, ins_len, ret == 0); 1593 p, ins_len, ret == 0);
1594 BUG_ON(sret > 0); 1594 BUG_ON(sret > 0);
@@ -2231,7 +2231,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
2231 right = read_node_slot(root, upper, slot + 1); 2231 right = read_node_slot(root, upper, slot + 1);
2232 btrfs_tree_lock(right); 2232 btrfs_tree_lock(right);
2233 free_space = btrfs_leaf_free_space(root, right); 2233 free_space = btrfs_leaf_free_space(root, right);
2234 if (free_space < data_size + sizeof(struct btrfs_item)) 2234 if (free_space < data_size)
2235 goto out_unlock; 2235 goto out_unlock;
2236 2236
2237 /* cow and double check */ 2237 /* cow and double check */
@@ -2241,7 +2241,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
2241 goto out_unlock; 2241 goto out_unlock;
2242 2242
2243 free_space = btrfs_leaf_free_space(root, right); 2243 free_space = btrfs_leaf_free_space(root, right);
2244 if (free_space < data_size + sizeof(struct btrfs_item)) 2244 if (free_space < data_size)
2245 goto out_unlock; 2245 goto out_unlock;
2246 2246
2247 left_nritems = btrfs_header_nritems(left); 2247 left_nritems = btrfs_header_nritems(left);
@@ -2254,7 +2254,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
2254 nr = 1; 2254 nr = 1;
2255 2255
2256 if (path->slots[0] >= left_nritems) 2256 if (path->slots[0] >= left_nritems)
2257 push_space += data_size + sizeof(*item); 2257 push_space += data_size;
2258 2258
2259 i = left_nritems - 1; 2259 i = left_nritems - 1;
2260 while (i >= nr) { 2260 while (i >= nr) {
@@ -2271,7 +2271,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
2271 } 2271 }
2272 2272
2273 if (path->slots[0] == i) 2273 if (path->slots[0] == i)
2274 push_space += data_size + sizeof(*item); 2274 push_space += data_size;
2275 2275
2276 if (!left->map_token) { 2276 if (!left->map_token) {
2277 map_extent_buffer(left, (unsigned long)item, 2277 map_extent_buffer(left, (unsigned long)item,
@@ -2427,7 +2427,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
2427 left = read_node_slot(root, path->nodes[1], slot - 1); 2427 left = read_node_slot(root, path->nodes[1], slot - 1);
2428 btrfs_tree_lock(left); 2428 btrfs_tree_lock(left);
2429 free_space = btrfs_leaf_free_space(root, left); 2429 free_space = btrfs_leaf_free_space(root, left);
2430 if (free_space < data_size + sizeof(struct btrfs_item)) { 2430 if (free_space < data_size) {
2431 ret = 1; 2431 ret = 1;
2432 goto out; 2432 goto out;
2433 } 2433 }
@@ -2442,7 +2442,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
2442 } 2442 }
2443 2443
2444 free_space = btrfs_leaf_free_space(root, left); 2444 free_space = btrfs_leaf_free_space(root, left);
2445 if (free_space < data_size + sizeof(struct btrfs_item)) { 2445 if (free_space < data_size) {
2446 ret = 1; 2446 ret = 1;
2447 goto out; 2447 goto out;
2448 } 2448 }
@@ -2473,7 +2473,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
2473 } 2473 }
2474 2474
2475 if (path->slots[0] == i) 2475 if (path->slots[0] == i)
2476 push_space += data_size + sizeof(*item); 2476 push_space += data_size;
2477 2477
2478 this_item_size = btrfs_item_size(right, item); 2478 this_item_size = btrfs_item_size(right, item);
2479 if (this_item_size + sizeof(*item) + push_space > free_space) 2479 if (this_item_size + sizeof(*item) + push_space > free_space)
@@ -2510,7 +2510,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
2510 btrfs_item_offset_nr(right, push_items - 1), 2510 btrfs_item_offset_nr(right, push_items - 1),
2511 push_space); 2511 push_space);
2512 old_left_nritems = btrfs_header_nritems(left); 2512 old_left_nritems = btrfs_header_nritems(left);
2513 BUG_ON(old_left_nritems < 0); 2513 BUG_ON(old_left_nritems <= 0);
2514 2514
2515 old_left_item_size = btrfs_item_offset_nr(left, old_left_nritems - 1); 2515 old_left_item_size = btrfs_item_offset_nr(left, old_left_nritems - 1);
2516 for (i = old_left_nritems; i < old_left_nritems + push_items; i++) { 2516 for (i = old_left_nritems; i < old_left_nritems + push_items; i++) {
@@ -2628,7 +2628,6 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans,
2628 int mid; 2628 int mid;
2629 int slot; 2629 int slot;
2630 struct extent_buffer *right; 2630 struct extent_buffer *right;
2631 int space_needed = data_size + sizeof(struct btrfs_item);
2632 int data_copy_size; 2631 int data_copy_size;
2633 int rt_data_off; 2632 int rt_data_off;
2634 int i; 2633 int i;
@@ -2638,9 +2637,6 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans,
2638 int num_doubles = 0; 2637 int num_doubles = 0;
2639 struct btrfs_disk_key disk_key; 2638 struct btrfs_disk_key disk_key;
2640 2639
2641 if (extend && data_size)
2642 space_needed = data_size;
2643
2644 /* first try to make some room by pushing left and right */ 2640 /* first try to make some room by pushing left and right */
2645 if (data_size && ins_key->type != BTRFS_DIR_ITEM_KEY) { 2641 if (data_size && ins_key->type != BTRFS_DIR_ITEM_KEY) {
2646 wret = push_leaf_right(trans, root, path, data_size, 0); 2642 wret = push_leaf_right(trans, root, path, data_size, 0);
@@ -2655,7 +2651,7 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans,
2655 l = path->nodes[0]; 2651 l = path->nodes[0];
2656 2652
2657 /* did the pushes work? */ 2653 /* did the pushes work? */
2658 if (btrfs_leaf_free_space(root, l) >= space_needed) 2654 if (btrfs_leaf_free_space(root, l) >= data_size)
2659 return 0; 2655 return 0;
2660 } 2656 }
2661 2657
@@ -2694,7 +2690,7 @@ again:
2694 BTRFS_UUID_SIZE); 2690 BTRFS_UUID_SIZE);
2695 if (mid <= slot) { 2691 if (mid <= slot) {
2696 if (nritems == 1 || 2692 if (nritems == 1 ||
2697 leaf_space_used(l, mid, nritems - mid) + space_needed > 2693 leaf_space_used(l, mid, nritems - mid) + data_size >
2698 BTRFS_LEAF_DATA_SIZE(root)) { 2694 BTRFS_LEAF_DATA_SIZE(root)) {
2699 if (slot >= nritems) { 2695 if (slot >= nritems) {
2700 btrfs_cpu_key_to_disk(&disk_key, ins_key); 2696 btrfs_cpu_key_to_disk(&disk_key, ins_key);
@@ -2716,12 +2712,12 @@ again:
2716 mid = slot; 2712 mid = slot;
2717 if (mid != nritems && 2713 if (mid != nritems &&
2718 leaf_space_used(l, mid, nritems - mid) + 2714 leaf_space_used(l, mid, nritems - mid) +
2719 space_needed > BTRFS_LEAF_DATA_SIZE(root)) { 2715 data_size > BTRFS_LEAF_DATA_SIZE(root)) {
2720 double_split = 1; 2716 double_split = 1;
2721 } 2717 }
2722 } 2718 }
2723 } else { 2719 } else {
2724 if (leaf_space_used(l, 0, mid + 1) + space_needed > 2720 if (leaf_space_used(l, 0, mid) + data_size >
2725 BTRFS_LEAF_DATA_SIZE(root)) { 2721 BTRFS_LEAF_DATA_SIZE(root)) {
2726 if (!extend && data_size && slot == 0) { 2722 if (!extend && data_size && slot == 0) {
2727 btrfs_cpu_key_to_disk(&disk_key, ins_key); 2723 btrfs_cpu_key_to_disk(&disk_key, ins_key);
@@ -2750,7 +2746,7 @@ again:
2750 mid = slot; 2746 mid = slot;
2751 if (mid != nritems && 2747 if (mid != nritems &&
2752 leaf_space_used(l, mid, nritems - mid) + 2748 leaf_space_used(l, mid, nritems - mid) +
2753 space_needed > BTRFS_LEAF_DATA_SIZE(root)) { 2749 data_size > BTRFS_LEAF_DATA_SIZE(root)) {
2754 double_split = 1; 2750 double_split = 1;
2755 } 2751 }
2756 } 2752 }
@@ -2883,7 +2879,8 @@ int btrfs_split_item(struct btrfs_trans_handle *trans,
2883 return -EAGAIN; 2879 return -EAGAIN;
2884 } 2880 }
2885 2881
2886 ret = split_leaf(trans, root, &orig_key, path, 0, 0); 2882 ret = split_leaf(trans, root, &orig_key, path,
2883 sizeof(struct btrfs_item), 1);
2887 path->keep_locks = 0; 2884 path->keep_locks = 0;
2888 BUG_ON(ret); 2885 BUG_ON(ret);
2889 2886
@@ -3169,14 +3166,17 @@ int btrfs_insert_some_items(struct btrfs_trans_handle *trans,
3169 struct btrfs_disk_key disk_key; 3166 struct btrfs_disk_key disk_key;
3170 struct btrfs_key found_key; 3167 struct btrfs_key found_key;
3171 3168
3172 found_key.objectid = 0; 3169 for (i = 0; i < nr; i++) {
3173 nr = min_t(int, nr, BTRFS_NODEPTRS_PER_BLOCK(root)); 3170 if (total_size + data_size[i] + sizeof(struct btrfs_item) >
3174 3171 BTRFS_LEAF_DATA_SIZE(root)) {
3175 for (i = 0; i < nr; i++) 3172 break;
3173 nr = i;
3174 }
3176 total_data += data_size[i]; 3175 total_data += data_size[i];
3176 total_size += data_size[i] + sizeof(struct btrfs_item);
3177 }
3178 BUG_ON(nr == 0);
3177 3179
3178 total_data = min_t(u32, total_data, BTRFS_LEAF_DATA_SIZE(root));
3179 total_size = total_data + (nr * sizeof(struct btrfs_item));
3180 ret = btrfs_search_slot(trans, root, cpu_key, path, total_size, 1); 3180 ret = btrfs_search_slot(trans, root, cpu_key, path, total_size, 1);
3181 if (ret == 0) 3181 if (ret == 0)
3182 return -EEXIST; 3182 return -EEXIST;
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index 7acadf3b742a..cc6e0b6de949 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -300,6 +300,10 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
300 300
301 size = btrfs_item_size_nr(leaf, path->slots[0]); 301 size = btrfs_item_size_nr(leaf, path->slots[0]);
302 csum_end = key.offset + (size / csum_size) * root->sectorsize; 302 csum_end = key.offset + (size / csum_size) * root->sectorsize;
303 if (csum_end <= start) {
304 path->slots[0]++;
305 continue;
306 }
303 307
304 size = min(csum_end, end + 1) - start; 308 size = min(csum_end, end + 1) - start;
305 sums = kzalloc(btrfs_ordered_sum_size(root, size), GFP_NOFS); 309 sums = kzalloc(btrfs_ordered_sum_size(root, size), GFP_NOFS);
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 6ac1b7f72e2a..33eee256ee81 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -374,13 +374,8 @@ insert:
374 if (found_size > item_size) { 374 if (found_size > item_size) {
375 btrfs_truncate_item(trans, root, path, item_size, 1); 375 btrfs_truncate_item(trans, root, path, item_size, 1);
376 } else if (found_size < item_size) { 376 } else if (found_size < item_size) {
377 ret = btrfs_del_item(trans, root, 377 ret = btrfs_extend_item(trans, root, path,
378 path); 378 item_size - found_size);
379 BUG_ON(ret);
380
381 btrfs_release_path(root, path);
382 ret = btrfs_insert_empty_item(trans,
383 root, path, key, item_size);
384 BUG_ON(ret); 379 BUG_ON(ret);
385 } 380 }
386 } else if (ret) { 381 } else if (ret) {