Btrfs: CPU usage optimizations in push and the extent_map code
authorChris Mason <chris.mason@oracle.com>
Fri, 19 Oct 2007 13:23:27 +0000 (09:23 -0400)
committerChris Mason <chris.mason@oracle.com>
Thu, 25 Sep 2008 15:03:57 +0000 (11:03 -0400)
Signed-off-by: Chris Mason <chris.mason@oracle.com>
fs/btrfs/ctree.c
fs/btrfs/extent_map.c

index 17a322663f3b99807d82cc8ceace922b65622590..e8466940fa30cd83d831346b3959ccd829bc35e4 100644 (file)
@@ -1588,6 +1588,11 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
        if (!path->nodes[1])
                return 1;
 
+       right_nritems = btrfs_header_nritems(right);
+       if (right_nritems == 0) {
+               return 1;
+       }
+
        left = read_tree_block(root, btrfs_node_blockptr(path->nodes[1],
                               slot - 1), root->leafsize);
        free_space = btrfs_leaf_free_space(root, left);
@@ -1604,18 +1609,13 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
                free_extent_buffer(left);
                return 1;
        }
+
        free_space = btrfs_leaf_free_space(root, left);
        if (free_space < data_size + sizeof(struct btrfs_item)) {
                free_extent_buffer(left);
                return 1;
        }
 
-       right_nritems = btrfs_header_nritems(right);
-       if (right_nritems == 0) {
-               free_extent_buffer(left);
-               return 1;
-       }
-
        for (i = 0; i < right_nritems - 1; i++) {
                item = btrfs_item_nr(right, i);
                if (!right->map_token) {
@@ -1772,21 +1772,25 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
        struct btrfs_disk_key disk_key;
 
        /* first try to make some room by pushing left and right */
-       wret = push_leaf_left(trans, root, path, data_size);
-       if (wret < 0) {
-               return wret;
-       }
-       if (wret) {
+       if (ins_key->type != BTRFS_DIR_ITEM_KEY) {
                wret = push_leaf_right(trans, root, path, data_size);
-               if (wret < 0)
+               if (wret < 0) {
                        return wret;
-       }
-       l = path->nodes[0];
+               }
+               if (wret) {
+                       wret = push_leaf_left(trans, root, path, data_size);
+                       if (wret < 0)
+                               return wret;
+               }
+               l = path->nodes[0];
 
-       /* did the pushes work? */
-       if (btrfs_leaf_free_space(root, l) >=
-           sizeof(struct btrfs_item) + data_size) {
-               return 0;
+               /* did the pushes work? */
+               if (btrfs_leaf_free_space(root, l) >=
+                   sizeof(struct btrfs_item) + data_size) {
+                       return 0;
+               }
+       } else {
+               l = path->nodes[0];
        }
 
        if (!path->nodes[1]) {
@@ -2388,13 +2392,13 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
                        slot = path->slots[1];
                        extent_buffer_get(leaf);
 
-                       wret = push_leaf_left(trans, root, path, 1);
+                       wret = push_leaf_right(trans, root, path, 1);
                        if (wret < 0 && wret != -ENOSPC)
                                ret = wret;
 
                        if (path->nodes[0] == leaf &&
                            btrfs_header_nritems(leaf)) {
-                               wret = push_leaf_right(trans, root, path, 1);
+                               wret = push_leaf_left(trans, root, path, 1);
                                if (wret < 0 && wret != -ENOSPC)
                                        ret = wret;
                        }
index 3c81f5eab15565da045b16bd4784794686b329d6..caaf0bf0e05920988d07a7683d9747c5cf66f563 100644 (file)
@@ -1986,12 +1986,15 @@ static inline struct page *extent_buffer_page(struct extent_buffer *eb,
                                              unsigned long i)
 {
        struct page *p;
+       struct address_space *mapping;
 
        if (i == 0)
                return eb->first_page;
        i += eb->start >> PAGE_CACHE_SHIFT;
-       p = find_get_page(eb->first_page->mapping, i);
-       page_cache_release(p);
+       mapping = eb->first_page->mapping;
+       read_lock_irq(&mapping->tree_lock);
+       p = radix_tree_lookup(&mapping->page_tree, i);
+       read_unlock_irq(&mapping->tree_lock);
        return p;
 }
 
@@ -2365,9 +2368,7 @@ void read_extent_buffer(struct extent_buffer *eb, void *dstv,
        WARN_ON(start > eb->len);
        WARN_ON(start + len > eb->start + eb->len);
 
-       offset = start & ((unsigned long)PAGE_CACHE_SIZE - 1);
-       if (i == 0)
-               offset += start_offset;
+       offset = (start_offset + start) & ((unsigned long)PAGE_CACHE_SIZE - 1);
 
        while(len > 0) {
                page = extent_buffer_page(eb, i);
@@ -2475,9 +2476,7 @@ int memcmp_extent_buffer(struct extent_buffer *eb, const void *ptrv,
        WARN_ON(start > eb->len);
        WARN_ON(start + len > eb->start + eb->len);
 
-       offset = start & ((unsigned long)PAGE_CACHE_SIZE - 1);
-       if (i == 0)
-               offset += start_offset;
+       offset = (start_offset + start) & ((unsigned long)PAGE_CACHE_SIZE - 1);
 
        while(len > 0) {
                page = extent_buffer_page(eb, i);
@@ -2514,9 +2513,7 @@ void write_extent_buffer(struct extent_buffer *eb, const void *srcv,
        WARN_ON(start > eb->len);
        WARN_ON(start + len > eb->start + eb->len);
 
-       offset = start & ((unsigned long)PAGE_CACHE_SIZE - 1);
-       if (i == 0)
-               offset += start_offset;
+       offset = (start_offset + start) & ((unsigned long)PAGE_CACHE_SIZE - 1);
 
        while(len > 0) {
                page = extent_buffer_page(eb, i);
@@ -2548,9 +2545,7 @@ void memset_extent_buffer(struct extent_buffer *eb, char c,
        WARN_ON(start > eb->len);
        WARN_ON(start + len > eb->start + eb->len);
 
-       offset = start & ((unsigned long)PAGE_CACHE_SIZE - 1);
-       if (i == 0)
-               offset += start_offset;
+       offset = (start_offset + start) & ((unsigned long)PAGE_CACHE_SIZE - 1);
 
        while(len > 0) {
                page = extent_buffer_page(eb, i);
@@ -2582,9 +2577,8 @@ void copy_extent_buffer(struct extent_buffer *dst, struct extent_buffer *src,
 
        WARN_ON(src->len != dst_len);
 
-       offset = dst_offset & ((unsigned long)PAGE_CACHE_SIZE - 1);
-       if (i == 0)
-               offset += start_offset;
+       offset = (start_offset + dst_offset) &
+               ((unsigned long)PAGE_CACHE_SIZE - 1);
 
        while(len > 0) {
                page = extent_buffer_page(dst, i);
@@ -2664,19 +2658,14 @@ void memcpy_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset,
        }
 
        while(len > 0) {
-               dst_off_in_page = dst_offset &
+               dst_off_in_page = (start_offset + dst_offset) &
                        ((unsigned long)PAGE_CACHE_SIZE - 1);
-               src_off_in_page = src_offset &
+               src_off_in_page = (start_offset + src_offset) &
                        ((unsigned long)PAGE_CACHE_SIZE - 1);
 
                dst_i = (start_offset + dst_offset) >> PAGE_CACHE_SHIFT;
                src_i = (start_offset + src_offset) >> PAGE_CACHE_SHIFT;
 
-               if (src_i == 0)
-                       src_off_in_page += start_offset;
-               if (dst_i == 0)
-                       dst_off_in_page += start_offset;
-
                cur = min(len, (unsigned long)(PAGE_CACHE_SIZE -
                                               src_off_in_page));
                cur = min_t(unsigned long, cur,
@@ -2723,14 +2712,10 @@ void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset,
                dst_i = (start_offset + dst_end) >> PAGE_CACHE_SHIFT;
                src_i = (start_offset + src_end) >> PAGE_CACHE_SHIFT;
 
-               dst_off_in_page = dst_end &
+               dst_off_in_page = (start_offset + dst_end) &
                        ((unsigned long)PAGE_CACHE_SIZE - 1);
-               src_off_in_page = src_end &
+               src_off_in_page = (start_offset + src_end) &
                        ((unsigned long)PAGE_CACHE_SIZE - 1);
-               if (src_i == 0)
-                       src_off_in_page += start_offset;
-               if (dst_i == 0)
-                       dst_off_in_page += start_offset;
 
                cur = min_t(unsigned long, len, src_off_in_page + 1);
                cur = min(cur, dst_off_in_page + 1);