Skip to content

Commit

Permalink
Btrfs: Add btree locking to the tree defragmentation code
Browse files Browse the repository at this point in the history
The online btree defragger is simplified and rewritten to use
standard btree searches instead of a walk up / down mechanism.

Signed-off-by: Chris Mason <chris.mason@oracle.com>
  • Loading branch information
Chris Mason committed Sep 25, 2008
1 parent a74a4b9 commit e7a8456
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 201 deletions.
46 changes: 37 additions & 9 deletions fs/btrfs/ctree.c
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,6 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
struct btrfs_key *progress)
{
struct extent_buffer *cur;
struct extent_buffer *tmp;
u64 blocknr;
u64 gen;
u64 search_start = *last_ret;
Expand All @@ -370,9 +369,6 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
int progress_passed = 0;
struct btrfs_disk_key disk_key;

/* FIXME this code needs locking */
return 0;

parent_level = btrfs_header_level(parent);
if (cache_only && parent_level != 1)
return 0;
Expand Down Expand Up @@ -454,20 +450,23 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
if (search_start == 0)
search_start = last_block;

btrfs_tree_lock(cur);
err = __btrfs_cow_block(trans, root, cur, parent, i,
&tmp, search_start,
&cur, search_start,
min(16 * blocksize,
(end_slot - i) * blocksize));
if (err) {
btrfs_tree_unlock(cur);
free_extent_buffer(cur);
break;
}
search_start = tmp->start;
last_block = tmp->start;
search_start = cur->start;
last_block = cur->start;
*last_ret = search_start;
if (parent_level == 1)
btrfs_clear_buffer_defrag(tmp);
free_extent_buffer(tmp);
btrfs_clear_buffer_defrag(cur);
btrfs_tree_unlock(cur);
free_extent_buffer(cur);
}
if (parent->map_token) {
unmap_extent_buffer(parent, parent->map_token,
Expand Down Expand Up @@ -2970,6 +2969,35 @@ int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path)
return 1;
}

int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path,
struct btrfs_key *key, int lowest_level)
{
int level = lowest_level;
int slot;
struct extent_buffer *c;

while(level < BTRFS_MAX_LEVEL) {
if (!path->nodes[level])
return 1;

slot = path->slots[level] + 1;
c = path->nodes[level];
if (slot >= btrfs_header_nritems(c)) {
level++;
if (level == BTRFS_MAX_LEVEL) {
return 1;
}
continue;
}
if (level == 0)
btrfs_item_key_to_cpu(c, key, slot);
else
btrfs_node_key_to_cpu(c, key, slot);
return 0;
}
return 1;
}

/*
* search the tree again to find a leaf with greater keys
* returns 0 if it found something or 1 if there are no greater leaves.
Expand Down
2 changes: 2 additions & 0 deletions fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -1411,6 +1411,8 @@ int btrfs_previous_item(struct btrfs_root *root,

struct extent_buffer *btrfs_root_node(struct btrfs_root *root);
struct extent_buffer *btrfs_lock_root_node(struct btrfs_root *root);
int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path,
struct btrfs_key *key, int lowest_level);

int btrfs_cow_block(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct extent_buffer *buf,
Expand Down
7 changes: 7 additions & 0 deletions fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -2201,6 +2201,7 @@ int drop_snap_lookup_refcount(struct btrfs_root *root, u64 start, u64 len,
{
mutex_unlock(&root->fs_info->alloc_mutex);
lookup_extent_ref(NULL, root, start, len, refs);
cond_resched();
mutex_lock(&root->fs_info->alloc_mutex);
return lookup_extent_ref(NULL, root, start, len, refs);
}
Expand Down Expand Up @@ -2280,6 +2281,7 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,

next = read_tree_block(root, bytenr, blocksize,
ptr_gen);
cond_resched();
mutex_lock(&root->fs_info->alloc_mutex);

/* we've dropped the lock, double check */
Expand Down Expand Up @@ -2329,6 +2331,7 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
*level += 1;
BUG_ON(ret);
mutex_unlock(&root->fs_info->alloc_mutex);
cond_resched();
return 0;
}

Expand Down Expand Up @@ -2448,6 +2451,10 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
break;
if (wret < 0)
ret = wret;
if (trans->transaction->in_commit) {
ret = -EAGAIN;
break;
}
}
for (i = 0; i <= orig_level; i++) {
if (path->nodes[i]) {
Expand Down
Loading

0 comments on commit e7a8456

Please sign in to comment.