aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2009-03-13 10:04:31 -0400
committerChris Mason <chris.mason@oracle.com>2009-03-24 16:14:25 -0400
commit44871b1b24b593996db43495cf4484cc580bdc10 (patch)
treeb1b56f48e76006662798508f20c2b2d1378fd04f /fs/btrfs
parent56bec294dea971335d4466b30f2d959f28f6e36d (diff)
Btrfs: reduce stack usage in some crucial tree balancing functions
Many of the tree balancing functions follow the same pattern. 1) cow a block 2) do something to the result This commit breaks them up into two functions so the variables and code required for part two don't suck down stack during part one. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ctree.c458
1 files changed, 278 insertions, 180 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index bebc9fd16665..3764248bdc05 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -2266,66 +2266,27 @@ noinline int btrfs_leaf_free_space(struct btrfs_root *root,
2266 return ret; 2266 return ret;
2267} 2267}
2268 2268
2269/* 2269static noinline int __push_leaf_right(struct btrfs_trans_handle *trans,
2270 * push some data in the path leaf to the right, trying to free up at 2270 struct btrfs_root *root,
2271 * least data_size bytes. returns zero if the push worked, nonzero otherwise 2271 struct btrfs_path *path,
2272 * 2272 int data_size, int empty,
2273 * returns 1 if the push failed because the other node didn't have enough 2273 struct extent_buffer *right,
2274 * room, 0 if everything worked out and < 0 if there were major errors. 2274 int free_space, u32 left_nritems)
2275 */
2276static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
2277 *root, struct btrfs_path *path, int data_size,
2278 int empty)
2279{ 2275{
2280 struct extent_buffer *left = path->nodes[0]; 2276 struct extent_buffer *left = path->nodes[0];
2281 struct extent_buffer *right; 2277 struct extent_buffer *upper = path->nodes[1];
2282 struct extent_buffer *upper;
2283 struct btrfs_disk_key disk_key; 2278 struct btrfs_disk_key disk_key;
2284 int slot; 2279 int slot;
2285 u32 i; 2280 u32 i;
2286 int free_space;
2287 int push_space = 0; 2281 int push_space = 0;
2288 int push_items = 0; 2282 int push_items = 0;
2289 struct btrfs_item *item; 2283 struct btrfs_item *item;
2290 u32 left_nritems;
2291 u32 nr; 2284 u32 nr;
2292 u32 right_nritems; 2285 u32 right_nritems;
2293 u32 data_end; 2286 u32 data_end;
2294 u32 this_item_size; 2287 u32 this_item_size;
2295 int ret; 2288 int ret;
2296 2289
2297 slot = path->slots[1];
2298 if (!path->nodes[1])
2299 return 1;
2300
2301 upper = path->nodes[1];
2302 if (slot >= btrfs_header_nritems(upper) - 1)
2303 return 1;
2304
2305 btrfs_assert_tree_locked(path->nodes[1]);
2306
2307 right = read_node_slot(root, upper, slot + 1);
2308 btrfs_tree_lock(right);
2309 btrfs_set_lock_blocking(right);
2310
2311 free_space = btrfs_leaf_free_space(root, right);
2312 if (free_space < data_size)
2313 goto out_unlock;
2314
2315 /* cow and double check */
2316 ret = btrfs_cow_block(trans, root, right, upper,
2317 slot + 1, &right);
2318 if (ret)
2319 goto out_unlock;
2320
2321 free_space = btrfs_leaf_free_space(root, right);
2322 if (free_space < data_size)
2323 goto out_unlock;
2324
2325 left_nritems = btrfs_header_nritems(left);
2326 if (left_nritems == 0)
2327 goto out_unlock;
2328
2329 if (empty) 2290 if (empty)
2330 nr = 0; 2291 nr = 0;
2331 else 2292 else
@@ -2334,6 +2295,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
2334 if (path->slots[0] >= left_nritems) 2295 if (path->slots[0] >= left_nritems)
2335 push_space += data_size; 2296 push_space += data_size;
2336 2297
2298 slot = path->slots[1];
2337 i = left_nritems - 1; 2299 i = left_nritems - 1;
2338 while (i >= nr) { 2300 while (i >= nr) {
2339 item = btrfs_item_nr(left, i); 2301 item = btrfs_item_nr(left, i);
@@ -2465,24 +2427,82 @@ out_unlock:
2465} 2427}
2466 2428
2467/* 2429/*
2430 * push some data in the path leaf to the right, trying to free up at
2431 * least data_size bytes. returns zero if the push worked, nonzero otherwise
2432 *
2433 * returns 1 if the push failed because the other node didn't have enough
2434 * room, 0 if everything worked out and < 0 if there were major errors.
2435 */
2436static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
2437 *root, struct btrfs_path *path, int data_size,
2438 int empty)
2439{
2440 struct extent_buffer *left = path->nodes[0];
2441 struct extent_buffer *right;
2442 struct extent_buffer *upper;
2443 int slot;
2444 int free_space;
2445 u32 left_nritems;
2446 int ret;
2447
2448 if (!path->nodes[1])
2449 return 1;
2450
2451 slot = path->slots[1];
2452 upper = path->nodes[1];
2453 if (slot >= btrfs_header_nritems(upper) - 1)
2454 return 1;
2455
2456 btrfs_assert_tree_locked(path->nodes[1]);
2457
2458 right = read_node_slot(root, upper, slot + 1);
2459 btrfs_tree_lock(right);
2460 btrfs_set_lock_blocking(right);
2461
2462 free_space = btrfs_leaf_free_space(root, right);
2463 if (free_space < data_size)
2464 goto out_unlock;
2465
2466 /* cow and double check */
2467 ret = btrfs_cow_block(trans, root, right, upper,
2468 slot + 1, &right);
2469 if (ret)
2470 goto out_unlock;
2471
2472 free_space = btrfs_leaf_free_space(root, right);
2473 if (free_space < data_size)
2474 goto out_unlock;
2475
2476 left_nritems = btrfs_header_nritems(left);
2477 if (left_nritems == 0)
2478 goto out_unlock;
2479
2480 return __push_leaf_right(trans, root, path, data_size, empty,
2481 right, free_space, left_nritems);
2482out_unlock:
2483 btrfs_tree_unlock(right);
2484 free_extent_buffer(right);
2485 return 1;
2486}
2487
2488/*
2468 * push some data in the path leaf to the left, trying to free up at 2489 * push some data in the path leaf to the left, trying to free up at
2469 * least data_size bytes. returns zero if the push worked, nonzero otherwise 2490 * least data_size bytes. returns zero if the push worked, nonzero otherwise
2470 */ 2491 */
2471static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root 2492static noinline int __push_leaf_left(struct btrfs_trans_handle *trans,
2472 *root, struct btrfs_path *path, int data_size, 2493 struct btrfs_root *root,
2473 int empty) 2494 struct btrfs_path *path, int data_size,
2495 int empty, struct extent_buffer *left,
2496 int free_space, int right_nritems)
2474{ 2497{
2475 struct btrfs_disk_key disk_key; 2498 struct btrfs_disk_key disk_key;
2476 struct extent_buffer *right = path->nodes[0]; 2499 struct extent_buffer *right = path->nodes[0];
2477 struct extent_buffer *left;
2478 int slot; 2500 int slot;
2479 int i; 2501 int i;
2480 int free_space;
2481 int push_space = 0; 2502 int push_space = 0;
2482 int push_items = 0; 2503 int push_items = 0;
2483 struct btrfs_item *item; 2504 struct btrfs_item *item;
2484 u32 old_left_nritems; 2505 u32 old_left_nritems;
2485 u32 right_nritems;
2486 u32 nr; 2506 u32 nr;
2487 int ret = 0; 2507 int ret = 0;
2488 int wret; 2508 int wret;
@@ -2490,41 +2510,6 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
2490 u32 old_left_item_size; 2510 u32 old_left_item_size;
2491 2511
2492 slot = path->slots[1]; 2512 slot = path->slots[1];
2493 if (slot == 0)
2494 return 1;
2495 if (!path->nodes[1])
2496 return 1;
2497
2498 right_nritems = btrfs_header_nritems(right);
2499 if (right_nritems == 0)
2500 return 1;
2501
2502 btrfs_assert_tree_locked(path->nodes[1]);
2503
2504 left = read_node_slot(root, path->nodes[1], slot - 1);
2505 btrfs_tree_lock(left);
2506 btrfs_set_lock_blocking(left);
2507
2508 free_space = btrfs_leaf_free_space(root, left);
2509 if (free_space < data_size) {
2510 ret = 1;
2511 goto out;
2512 }
2513
2514 /* cow and double check */
2515 ret = btrfs_cow_block(trans, root, left,
2516 path->nodes[1], slot - 1, &left);
2517 if (ret) {
2518 /* we hit -ENOSPC, but it isn't fatal here */
2519 ret = 1;
2520 goto out;
2521 }
2522
2523 free_space = btrfs_leaf_free_space(root, left);
2524 if (free_space < data_size) {
2525 ret = 1;
2526 goto out;
2527 }
2528 2513
2529 if (empty) 2514 if (empty)
2530 nr = right_nritems; 2515 nr = right_nritems;
@@ -2692,6 +2677,154 @@ out:
2692} 2677}
2693 2678
2694/* 2679/*
2680 * push some data in the path leaf to the left, trying to free up at
2681 * least data_size bytes. returns zero if the push worked, nonzero otherwise
2682 */
2683static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
2684 *root, struct btrfs_path *path, int data_size,
2685 int empty)
2686{
2687 struct extent_buffer *right = path->nodes[0];
2688 struct extent_buffer *left;
2689 int slot;
2690 int free_space;
2691 u32 right_nritems;
2692 int ret = 0;
2693
2694 slot = path->slots[1];
2695 if (slot == 0)
2696 return 1;
2697 if (!path->nodes[1])
2698 return 1;
2699
2700 right_nritems = btrfs_header_nritems(right);
2701 if (right_nritems == 0)
2702 return 1;
2703
2704 btrfs_assert_tree_locked(path->nodes[1]);
2705
2706 left = read_node_slot(root, path->nodes[1], slot - 1);
2707 btrfs_tree_lock(left);
2708 btrfs_set_lock_blocking(left);
2709
2710 free_space = btrfs_leaf_free_space(root, left);
2711 if (free_space < data_size) {
2712 ret = 1;
2713 goto out;
2714 }
2715
2716 /* cow and double check */
2717 ret = btrfs_cow_block(trans, root, left,
2718 path->nodes[1], slot - 1, &left);
2719 if (ret) {
2720 /* we hit -ENOSPC, but it isn't fatal here */
2721 ret = 1;
2722 goto out;
2723 }
2724
2725 free_space = btrfs_leaf_free_space(root, left);
2726 if (free_space < data_size) {
2727 ret = 1;
2728 goto out;
2729 }
2730
2731 return __push_leaf_left(trans, root, path, data_size,
2732 empty, left, free_space, right_nritems);
2733out:
2734 btrfs_tree_unlock(left);
2735 free_extent_buffer(left);
2736 return ret;
2737}
2738
2739/*
2740 * split the path's leaf in two, making sure there is at least data_size
2741 * available for the resulting leaf level of the path.
2742 *
2743 * returns 0 if all went well and < 0 on failure.
2744 */
2745static noinline int copy_for_split(struct btrfs_trans_handle *trans,
2746 struct btrfs_root *root,
2747 struct btrfs_path *path,
2748 struct extent_buffer *l,
2749 struct extent_buffer *right,
2750 int slot, int mid, int nritems)
2751{
2752 int data_copy_size;
2753 int rt_data_off;
2754 int i;
2755 int ret = 0;
2756 int wret;
2757 struct btrfs_disk_key disk_key;
2758
2759 nritems = nritems - mid;
2760 btrfs_set_header_nritems(right, nritems);
2761 data_copy_size = btrfs_item_end_nr(l, mid) - leaf_data_end(root, l);
2762
2763 copy_extent_buffer(right, l, btrfs_item_nr_offset(0),
2764 btrfs_item_nr_offset(mid),
2765 nritems * sizeof(struct btrfs_item));
2766
2767 copy_extent_buffer(right, l,
2768 btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) -
2769 data_copy_size, btrfs_leaf_data(l) +
2770 leaf_data_end(root, l), data_copy_size);
2771
2772 rt_data_off = BTRFS_LEAF_DATA_SIZE(root) -
2773 btrfs_item_end_nr(l, mid);
2774
2775 for (i = 0; i < nritems; i++) {
2776 struct btrfs_item *item = btrfs_item_nr(right, i);
2777 u32 ioff;
2778
2779 if (!right->map_token) {
2780 map_extent_buffer(right, (unsigned long)item,
2781 sizeof(struct btrfs_item),
2782 &right->map_token, &right->kaddr,
2783 &right->map_start, &right->map_len,
2784 KM_USER1);
2785 }
2786
2787 ioff = btrfs_item_offset(right, item);
2788 btrfs_set_item_offset(right, item, ioff + rt_data_off);
2789 }
2790
2791 if (right->map_token) {
2792 unmap_extent_buffer(right, right->map_token, KM_USER1);
2793 right->map_token = NULL;
2794 }
2795
2796 btrfs_set_header_nritems(l, mid);
2797 ret = 0;
2798 btrfs_item_key(right, &disk_key, 0);
2799 wret = insert_ptr(trans, root, path, &disk_key, right->start,
2800 path->slots[1] + 1, 1);
2801 if (wret)
2802 ret = wret;
2803
2804 btrfs_mark_buffer_dirty(right);
2805 btrfs_mark_buffer_dirty(l);
2806 BUG_ON(path->slots[0] != slot);
2807
2808 ret = btrfs_update_ref(trans, root, l, right, 0, nritems);
2809 BUG_ON(ret);
2810
2811 if (mid <= slot) {
2812 btrfs_tree_unlock(path->nodes[0]);
2813 free_extent_buffer(path->nodes[0]);
2814 path->nodes[0] = right;
2815 path->slots[0] -= mid;
2816 path->slots[1] += 1;
2817 } else {
2818 btrfs_tree_unlock(right);
2819 free_extent_buffer(right);
2820 }
2821
2822 BUG_ON(path->slots[0] < 0);
2823
2824 return ret;
2825}
2826
2827/*
2695 * split the path's leaf in two, making sure there is at least data_size 2828 * split the path's leaf in two, making sure there is at least data_size
2696 * available for the resulting leaf level of the path. 2829 * available for the resulting leaf level of the path.
2697 * 2830 *
@@ -2708,14 +2841,10 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans,
2708 int mid; 2841 int mid;
2709 int slot; 2842 int slot;
2710 struct extent_buffer *right; 2843 struct extent_buffer *right;
2711 int data_copy_size;
2712 int rt_data_off;
2713 int i;
2714 int ret = 0; 2844 int ret = 0;
2715 int wret; 2845 int wret;
2716 int double_split; 2846 int double_split;
2717 int num_doubles = 0; 2847 int num_doubles = 0;
2718 struct btrfs_disk_key disk_key;
2719 2848
2720 /* first try to make some room by pushing left and right */ 2849 /* first try to make some room by pushing left and right */
2721 if (data_size && ins_key->type != BTRFS_DIR_ITEM_KEY) { 2850 if (data_size && ins_key->type != BTRFS_DIR_ITEM_KEY) {
@@ -2767,11 +2896,14 @@ again:
2767 write_extent_buffer(right, root->fs_info->chunk_tree_uuid, 2896 write_extent_buffer(right, root->fs_info->chunk_tree_uuid,
2768 (unsigned long)btrfs_header_chunk_tree_uuid(right), 2897 (unsigned long)btrfs_header_chunk_tree_uuid(right),
2769 BTRFS_UUID_SIZE); 2898 BTRFS_UUID_SIZE);
2899
2770 if (mid <= slot) { 2900 if (mid <= slot) {
2771 if (nritems == 1 || 2901 if (nritems == 1 ||
2772 leaf_space_used(l, mid, nritems - mid) + data_size > 2902 leaf_space_used(l, mid, nritems - mid) + data_size >
2773 BTRFS_LEAF_DATA_SIZE(root)) { 2903 BTRFS_LEAF_DATA_SIZE(root)) {
2774 if (slot >= nritems) { 2904 if (slot >= nritems) {
2905 struct btrfs_disk_key disk_key;
2906
2775 btrfs_cpu_key_to_disk(&disk_key, ins_key); 2907 btrfs_cpu_key_to_disk(&disk_key, ins_key);
2776 btrfs_set_header_nritems(right, 0); 2908 btrfs_set_header_nritems(right, 0);
2777 wret = insert_ptr(trans, root, path, 2909 wret = insert_ptr(trans, root, path,
@@ -2799,6 +2931,8 @@ again:
2799 if (leaf_space_used(l, 0, mid) + data_size > 2931 if (leaf_space_used(l, 0, mid) + data_size >
2800 BTRFS_LEAF_DATA_SIZE(root)) { 2932 BTRFS_LEAF_DATA_SIZE(root)) {
2801 if (!extend && data_size && slot == 0) { 2933 if (!extend && data_size && slot == 0) {
2934 struct btrfs_disk_key disk_key;
2935
2802 btrfs_cpu_key_to_disk(&disk_key, ins_key); 2936 btrfs_cpu_key_to_disk(&disk_key, ins_key);
2803 btrfs_set_header_nritems(right, 0); 2937 btrfs_set_header_nritems(right, 0);
2804 wret = insert_ptr(trans, root, path, 2938 wret = insert_ptr(trans, root, path,
@@ -2831,76 +2965,16 @@ again:
2831 } 2965 }
2832 } 2966 }
2833 } 2967 }
2834 nritems = nritems - mid;
2835 btrfs_set_header_nritems(right, nritems);
2836 data_copy_size = btrfs_item_end_nr(l, mid) - leaf_data_end(root, l);
2837
2838 copy_extent_buffer(right, l, btrfs_item_nr_offset(0),
2839 btrfs_item_nr_offset(mid),
2840 nritems * sizeof(struct btrfs_item));
2841
2842 copy_extent_buffer(right, l,
2843 btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) -
2844 data_copy_size, btrfs_leaf_data(l) +
2845 leaf_data_end(root, l), data_copy_size);
2846
2847 rt_data_off = BTRFS_LEAF_DATA_SIZE(root) -
2848 btrfs_item_end_nr(l, mid);
2849 2968
2850 for (i = 0; i < nritems; i++) { 2969 ret = copy_for_split(trans, root, path, l, right, slot, mid, nritems);
2851 struct btrfs_item *item = btrfs_item_nr(right, i);
2852 u32 ioff;
2853
2854 if (!right->map_token) {
2855 map_extent_buffer(right, (unsigned long)item,
2856 sizeof(struct btrfs_item),
2857 &right->map_token, &right->kaddr,
2858 &right->map_start, &right->map_len,
2859 KM_USER1);
2860 }
2861
2862 ioff = btrfs_item_offset(right, item);
2863 btrfs_set_item_offset(right, item, ioff + rt_data_off);
2864 }
2865
2866 if (right->map_token) {
2867 unmap_extent_buffer(right, right->map_token, KM_USER1);
2868 right->map_token = NULL;
2869 }
2870
2871 btrfs_set_header_nritems(l, mid);
2872 ret = 0;
2873 btrfs_item_key(right, &disk_key, 0);
2874 wret = insert_ptr(trans, root, path, &disk_key, right->start,
2875 path->slots[1] + 1, 1);
2876 if (wret)
2877 ret = wret;
2878
2879 btrfs_mark_buffer_dirty(right);
2880 btrfs_mark_buffer_dirty(l);
2881 BUG_ON(path->slots[0] != slot);
2882
2883 ret = btrfs_update_ref(trans, root, l, right, 0, nritems);
2884 BUG_ON(ret); 2970 BUG_ON(ret);
2885 2971
2886 if (mid <= slot) {
2887 btrfs_tree_unlock(path->nodes[0]);
2888 free_extent_buffer(path->nodes[0]);
2889 path->nodes[0] = right;
2890 path->slots[0] -= mid;
2891 path->slots[1] += 1;
2892 } else {
2893 btrfs_tree_unlock(right);
2894 free_extent_buffer(right);
2895 }
2896
2897 BUG_ON(path->slots[0] < 0);
2898
2899 if (double_split) { 2972 if (double_split) {
2900 BUG_ON(num_doubles != 0); 2973 BUG_ON(num_doubles != 0);
2901 num_doubles++; 2974 num_doubles++;
2902 goto again; 2975 goto again;
2903 } 2976 }
2977
2904 return ret; 2978 return ret;
2905} 2979}
2906 2980
@@ -3382,39 +3456,27 @@ out:
3382} 3456}
3383 3457
3384/* 3458/*
3385 * Given a key and some data, insert items into the tree. 3459 * this is a helper for btrfs_insert_empty_items, the main goal here is
3386 * This does all the path init required, making room in the tree if needed. 3460 * to save stack depth by doing the bulk of the work in a function
3461 * that doesn't call btrfs_search_slot
3387 */ 3462 */
3388int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, 3463static noinline_for_stack int
3389 struct btrfs_root *root, 3464setup_items_for_insert(struct btrfs_trans_handle *trans,
3390 struct btrfs_path *path, 3465 struct btrfs_root *root, struct btrfs_path *path,
3391 struct btrfs_key *cpu_key, u32 *data_size, 3466 struct btrfs_key *cpu_key, u32 *data_size,
3392 int nr) 3467 u32 total_data, u32 total_size, int nr)
3393{ 3468{
3394 struct extent_buffer *leaf;
3395 struct btrfs_item *item; 3469 struct btrfs_item *item;
3396 int ret = 0;
3397 int slot;
3398 int slot_orig;
3399 int i; 3470 int i;
3400 u32 nritems; 3471 u32 nritems;
3401 u32 total_size = 0;
3402 u32 total_data = 0;
3403 unsigned int data_end; 3472 unsigned int data_end;
3404 struct btrfs_disk_key disk_key; 3473 struct btrfs_disk_key disk_key;
3474 int ret;
3475 struct extent_buffer *leaf;
3476 int slot;
3405 3477
3406 for (i = 0; i < nr; i++)
3407 total_data += data_size[i];
3408
3409 total_size = total_data + (nr * sizeof(struct btrfs_item));
3410 ret = btrfs_search_slot(trans, root, cpu_key, path, total_size, 1);
3411 if (ret == 0)
3412 return -EEXIST;
3413 if (ret < 0)
3414 goto out;
3415
3416 slot_orig = path->slots[0];
3417 leaf = path->nodes[0]; 3478 leaf = path->nodes[0];
3479 slot = path->slots[0];
3418 3480
3419 nritems = btrfs_header_nritems(leaf); 3481 nritems = btrfs_header_nritems(leaf);
3420 data_end = leaf_data_end(root, leaf); 3482 data_end = leaf_data_end(root, leaf);
@@ -3426,9 +3488,6 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
3426 BUG(); 3488 BUG();
3427 } 3489 }
3428 3490
3429 slot = path->slots[0];
3430 BUG_ON(slot < 0);
3431
3432 if (slot != nritems) { 3491 if (slot != nritems) {
3433 unsigned int old_data = btrfs_item_end_nr(leaf, slot); 3492 unsigned int old_data = btrfs_item_end_nr(leaf, slot);
3434 3493
@@ -3484,11 +3543,13 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
3484 data_end -= data_size[i]; 3543 data_end -= data_size[i];
3485 btrfs_set_item_size(leaf, item, data_size[i]); 3544 btrfs_set_item_size(leaf, item, data_size[i]);
3486 } 3545 }
3546
3487 btrfs_set_header_nritems(leaf, nritems + nr); 3547 btrfs_set_header_nritems(leaf, nritems + nr);
3488 btrfs_mark_buffer_dirty(leaf); 3548 btrfs_mark_buffer_dirty(leaf);
3489 3549
3490 ret = 0; 3550 ret = 0;
3491 if (slot == 0) { 3551 if (slot == 0) {
3552 struct btrfs_disk_key disk_key;
3492 btrfs_cpu_key_to_disk(&disk_key, cpu_key); 3553 btrfs_cpu_key_to_disk(&disk_key, cpu_key);
3493 ret = fixup_low_keys(trans, root, path, &disk_key, 1); 3554 ret = fixup_low_keys(trans, root, path, &disk_key, 1);
3494 } 3555 }
@@ -3497,6 +3558,43 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
3497 btrfs_print_leaf(root, leaf); 3558 btrfs_print_leaf(root, leaf);
3498 BUG(); 3559 BUG();
3499 } 3560 }
3561 return ret;
3562}
3563
3564/*
3565 * Given a key and some data, insert items into the tree.
3566 * This does all the path init required, making room in the tree if needed.
3567 */
3568int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
3569 struct btrfs_root *root,
3570 struct btrfs_path *path,
3571 struct btrfs_key *cpu_key, u32 *data_size,
3572 int nr)
3573{
3574 struct extent_buffer *leaf;
3575 int ret = 0;
3576 int slot;
3577 int i;
3578 u32 total_size = 0;
3579 u32 total_data = 0;
3580
3581 for (i = 0; i < nr; i++)
3582 total_data += data_size[i];
3583
3584 total_size = total_data + (nr * sizeof(struct btrfs_item));
3585 ret = btrfs_search_slot(trans, root, cpu_key, path, total_size, 1);
3586 if (ret == 0)
3587 return -EEXIST;
3588 if (ret < 0)
3589 goto out;
3590
3591 leaf = path->nodes[0];
3592 slot = path->slots[0];
3593 BUG_ON(slot < 0);
3594
3595 ret = setup_items_for_insert(trans, root, path, cpu_key, data_size,
3596 total_data, total_size, nr);
3597
3500out: 3598out:
3501 btrfs_unlock_up_safe(path, 1); 3599 btrfs_unlock_up_safe(path, 1);
3502 return ret; 3600 return ret;