Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 128437
b: refs/heads/master
c: 2cc58cf
h: refs/heads/master
i:
  128435: 8883d68
v: v3
  • Loading branch information
Chris Mason authored and David Woodhouse committed Aug 27, 2007
1 parent deef9be commit ea37d2b
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 17 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 320206112895c72f98e57570ae194689dcd7fe56
refs/heads/master: 2cc58cf24f69be8632a3b29d653c318bf3bd8c84
62 changes: 49 additions & 13 deletions trunk/fs/btrfs/ctree.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ struct btrfs_path *btrfs_alloc_path(void)
{
struct btrfs_path *path;
path = kmem_cache_alloc(btrfs_path_cachep, GFP_NOFS);
if (path)
if (path) {
btrfs_init_path(path);
path->reada = 1;
}
return path;
}

Expand Down Expand Up @@ -159,6 +161,34 @@ static int close_blocks(u64 blocknr, u64 other)
return 0;
}

static int should_defrag_leaf(struct buffer_head *bh)
{
struct btrfs_leaf *leaf = btrfs_buffer_leaf(bh);
struct btrfs_disk_key *key;
u32 nritems;

if (buffer_defrag(bh))
return 1;

nritems = btrfs_header_nritems(&leaf->header);
if (nritems == 0)
return 0;

key = &leaf->items[0].key;
if (btrfs_disk_key_type(key) == BTRFS_DIR_ITEM_KEY)
return 1;

key = &leaf->items[nritems-1].key;
if (btrfs_disk_key_type(key) == BTRFS_DIR_ITEM_KEY)
return 1;
if (nritems > 4) {
key = &leaf->items[nritems/2].key;
if (btrfs_disk_key_type(key) == BTRFS_DIR_ITEM_KEY)
return 1;
}
return 0;
}

int btrfs_realloc_node(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct buffer_head *parent,
int cache_only, u64 *last_ret)
Expand Down Expand Up @@ -217,7 +247,9 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,

cur_bh = btrfs_find_tree_block(root, blocknr);
if (!cur_bh || !buffer_uptodate(cur_bh) ||
buffer_locked(cur_bh) || !buffer_defrag(cur_bh)) {
buffer_locked(cur_bh) ||
(parent_level != 1 && !buffer_defrag(cur_bh)) ||
(parent_level == 1 && !should_defrag_leaf(cur_bh))) {
if (cache_only) {
brelse(cur_bh);
continue;
Expand Down Expand Up @@ -297,6 +329,7 @@ static int check_node(struct btrfs_root *root, struct btrfs_path *path,
parent = btrfs_buffer_node(path->nodes[level + 1]);

slot = path->slots[level];
BUG_ON(!buffer_uptodate(path->nodes[level]));
BUG_ON(nritems == 0);
if (parent) {
struct btrfs_disk_key *parent_key;
Expand Down Expand Up @@ -511,16 +544,26 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
err_on_enospc = 1;

left_buf = read_node_slot(root, parent_buf, pslot - 1);
right_buf = read_node_slot(root, parent_buf, pslot + 1);

/* first, try to make some room in the middle buffer */
if (left_buf) {
wret = btrfs_cow_block(trans, root, left_buf,
parent_buf, pslot - 1, &left_buf);
if (wret) {
ret = wret;
goto enospc;
}
}
right_buf = read_node_slot(root, parent_buf, pslot + 1);
if (right_buf) {
wret = btrfs_cow_block(trans, root, right_buf,
parent_buf, pslot + 1, &right_buf);
if (wret) {
ret = wret;
goto enospc;
}
}

/* first, try to make some room in the middle buffer */
if (left_buf) {
left = btrfs_buffer_node(left_buf);
orig_slot += btrfs_header_nritems(&left->header);
wret = push_node_left(trans, root, left_buf, mid_buf);
Expand All @@ -534,13 +577,6 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
* then try to empty the right most buffer into the middle
*/
if (right_buf) {
wret = btrfs_cow_block(trans, root, right_buf,
parent_buf, pslot + 1, &right_buf);
if (wret) {
ret = wret;
goto enospc;
}

right = btrfs_buffer_node(right_buf);
wret = push_node_left(trans, root, mid_buf, right_buf);
if (wret < 0 && wret != -ENOSPC)
Expand Down Expand Up @@ -817,7 +853,7 @@ static void reada_for_search(struct btrfs_root *root, struct btrfs_path *path,
for (i = 0; i < ret; i++) {
blocknr = gang[i];
clear_radix_bit(&found, blocknr);
if (nread > 32)
if (path->reada == 1 && nread > 16)
continue;
if (close_blocks(cluster_start, blocknr)) {
readahead_tree_block(root, blocknr);
Expand Down
4 changes: 2 additions & 2 deletions trunk/fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ static int cache_block_group(struct btrfs_root *root,
path = btrfs_alloc_path();
if (!path)
return -ENOMEM;
path->reada = 1;
path->reada = 2;
key.objectid = block_group->key.objectid;
key.flags = 0;
key.offset = 0;
Expand Down Expand Up @@ -1015,7 +1015,7 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
ins->objectid = search_start;
ins->offset = 0;
start_found = 0;
path->reada = 1;
path->reada = 2;

ret = btrfs_search_slot(trans, root, ins, path, 0, 0);
if (ret < 0)
Expand Down
2 changes: 1 addition & 1 deletion trunk/fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
btrfs_set_key_type(&key, key_type);
key.offset = filp->f_pos;
path = btrfs_alloc_path();
path->reada = 1;
path->reada = 2;
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
if (ret < 0)
goto err;
Expand Down

0 comments on commit ea37d2b

Please sign in to comment.