diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-01-29 15:15:18 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:00 -0400 |
commit | 9c58309d6cf22471dacbcb6de54d00cef9ca20d4 (patch) | |
tree | 9f3ae79d2db86de12c4ee5152b3b491b1f1a88a4 /fs/btrfs/ctree.c | |
parent | 85e21bac165b4ba1f6f90431ad6fc658ffcbaf3a (diff) |
Btrfs: Add inode item and backref in one insert, reducing cpu usage
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r-- | fs/btrfs/ctree.c | 39 |
1 files changed, 25 insertions, 14 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 84ad53e06b3a..fb2e2bd506c8 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -2332,27 +2332,34 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans, | |||
2332 | * Given a key and some data, insert an item into the tree. | 2332 | * Given a key and some data, insert an item into the tree. |
2333 | * This does all the path init required, making room in the tree if needed. | 2333 | * This does all the path init required, making room in the tree if needed. |
2334 | */ | 2334 | */ |
2335 | int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, | 2335 | int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, |
2336 | struct btrfs_root *root, | 2336 | struct btrfs_root *root, |
2337 | struct btrfs_path *path, | 2337 | struct btrfs_path *path, |
2338 | struct btrfs_key *cpu_key, u32 data_size) | 2338 | struct btrfs_key *cpu_key, u32 *data_size, |
2339 | int nr) | ||
2339 | { | 2340 | { |
2340 | struct extent_buffer *leaf; | 2341 | struct extent_buffer *leaf; |
2341 | struct btrfs_item *item; | 2342 | struct btrfs_item *item; |
2342 | int ret = 0; | 2343 | int ret = 0; |
2343 | int slot; | 2344 | int slot; |
2344 | int slot_orig; | 2345 | int slot_orig; |
2346 | int i; | ||
2345 | u32 nritems; | 2347 | u32 nritems; |
2348 | u32 total_size = 0; | ||
2349 | u32 total_data = 0; | ||
2346 | unsigned int data_end; | 2350 | unsigned int data_end; |
2347 | struct btrfs_disk_key disk_key; | 2351 | struct btrfs_disk_key disk_key; |
2348 | 2352 | ||
2349 | btrfs_cpu_key_to_disk(&disk_key, cpu_key); | 2353 | for (i = 0; i < nr; i++) { |
2354 | total_data += data_size[i]; | ||
2355 | } | ||
2350 | 2356 | ||
2351 | /* create a root if there isn't one */ | 2357 | /* create a root if there isn't one */ |
2352 | if (!root->node) | 2358 | if (!root->node) |
2353 | BUG(); | 2359 | BUG(); |
2354 | 2360 | ||
2355 | ret = btrfs_search_slot(trans, root, cpu_key, path, data_size, 1); | 2361 | total_size = total_data + (nr - 1) * sizeof(struct btrfs_item); |
2362 | ret = btrfs_search_slot(trans, root, cpu_key, path, total_size, 1); | ||
2356 | if (ret == 0) { | 2363 | if (ret == 0) { |
2357 | return -EEXIST; | 2364 | return -EEXIST; |
2358 | } | 2365 | } |
@@ -2366,10 +2373,10 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, | |||
2366 | data_end = leaf_data_end(root, leaf); | 2373 | data_end = leaf_data_end(root, leaf); |
2367 | 2374 | ||
2368 | if (btrfs_leaf_free_space(root, leaf) < | 2375 | if (btrfs_leaf_free_space(root, leaf) < |
2369 | sizeof(struct btrfs_item) + data_size) { | 2376 | sizeof(struct btrfs_item) + total_size) { |
2370 | btrfs_print_leaf(root, leaf); | 2377 | btrfs_print_leaf(root, leaf); |
2371 | printk("not enough freespace need %u have %d\n", | 2378 | printk("not enough freespace need %u have %d\n", |
2372 | data_size, btrfs_leaf_free_space(root, leaf)); | 2379 | total_size, btrfs_leaf_free_space(root, leaf)); |
2373 | BUG(); | 2380 | BUG(); |
2374 | } | 2381 | } |
2375 | 2382 | ||
@@ -2404,7 +2411,7 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, | |||
2404 | } | 2411 | } |
2405 | 2412 | ||
2406 | ioff = btrfs_item_offset(leaf, item); | 2413 | ioff = btrfs_item_offset(leaf, item); |
2407 | btrfs_set_item_offset(leaf, item, ioff - data_size); | 2414 | btrfs_set_item_offset(leaf, item, ioff - total_data); |
2408 | } | 2415 | } |
2409 | if (leaf->map_token) { | 2416 | if (leaf->map_token) { |
2410 | unmap_extent_buffer(leaf, leaf->map_token, KM_USER1); | 2417 | unmap_extent_buffer(leaf, leaf->map_token, KM_USER1); |
@@ -2412,23 +2419,27 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, | |||
2412 | } | 2419 | } |
2413 | 2420 | ||
2414 | /* shift the items */ | 2421 | /* shift the items */ |
2415 | memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + 1), | 2422 | memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + nr), |
2416 | btrfs_item_nr_offset(slot), | 2423 | btrfs_item_nr_offset(slot), |
2417 | (nritems - slot) * sizeof(struct btrfs_item)); | 2424 | (nritems - slot) * sizeof(struct btrfs_item)); |
2418 | 2425 | ||
2419 | /* shift the data */ | 2426 | /* shift the data */ |
2420 | memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) + | 2427 | memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) + |
2421 | data_end - data_size, btrfs_leaf_data(leaf) + | 2428 | data_end - total_data, btrfs_leaf_data(leaf) + |
2422 | data_end, old_data - data_end); | 2429 | data_end, old_data - data_end); |
2423 | data_end = old_data; | 2430 | data_end = old_data; |
2424 | } | 2431 | } |
2425 | 2432 | ||
2426 | /* setup the item for the new data */ | 2433 | /* setup the item for the new data */ |
2427 | btrfs_set_item_key(leaf, &disk_key, slot); | 2434 | for (i = 0; i < nr; i++) { |
2428 | item = btrfs_item_nr(leaf, slot); | 2435 | btrfs_cpu_key_to_disk(&disk_key, cpu_key + i); |
2429 | btrfs_set_item_offset(leaf, item, data_end - data_size); | 2436 | btrfs_set_item_key(leaf, &disk_key, slot + i); |
2430 | btrfs_set_item_size(leaf, item, data_size); | 2437 | item = btrfs_item_nr(leaf, slot + i); |
2431 | btrfs_set_header_nritems(leaf, nritems + 1); | 2438 | btrfs_set_item_offset(leaf, item, data_end - data_size[i]); |
2439 | data_end -= data_size[i]; | ||
2440 | btrfs_set_item_size(leaf, item, data_size[i]); | ||
2441 | } | ||
2442 | btrfs_set_header_nritems(leaf, nritems + nr); | ||
2432 | btrfs_mark_buffer_dirty(leaf); | 2443 | btrfs_mark_buffer_dirty(leaf); |
2433 | 2444 | ||
2434 | ret = 0; | 2445 | ret = 0; |