diff options
author | Yan Zheng <zheng.yan@oracle.com> | 2008-12-17 10:21:48 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-12-17 10:21:48 -0500 |
commit | 87b29b208c6c38f3446d2de6ece946e2459052cf (patch) | |
tree | 43e717289e1e8446fced4093ab39667bba9ea60a /fs/btrfs | |
parent | d7f735d0bc68c411abda0a612e1421bdade649cc (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.c | 52 | ||||
-rw-r--r-- | fs/btrfs/file-item.c | 4 | ||||
-rw-r--r-- | fs/btrfs/tree-log.c | 9 |
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) { |