aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-01-29 15:15:18 -0500
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:00 -0400
commit9c58309d6cf22471dacbcb6de54d00cef9ca20d4 (patch)
tree9f3ae79d2db86de12c4ee5152b3b491b1f1a88a4 /fs/btrfs/ctree.c
parent85e21bac165b4ba1f6f90431ad6fc658ffcbaf3a (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.c39
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 */
2335int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, 2335int 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;