Btrfs: extent_map and data=ordered fixes for space balancing
* Add an EXTENT_BOUNDARY state bit to keep the writepage code from merging data extents that are in the process of being relocated. This allows us to do accounting for them properly. * The balancing code relocates data extents indepdent of the underlying inode. The extent_map code was modified to properly account for things moving around (invalidating extent_map caches in the inode). * Don't take the drop_mutex in the create_subvol ioctl. It isn't required. * Fix walking of the ordered extent list to avoid races with sys_unlink * Change the lock ordering rules. Transaction start goes outside the drop_mutex. This allows btrfs_commit_transaction to directly drop the relocation trees. Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
@@ -292,7 +292,7 @@ static int merge_state(struct extent_io_tree *tree,
|
||||
struct extent_state *other;
|
||||
struct rb_node *other_node;
|
||||
|
||||
if (state->state & EXTENT_IOBITS)
|
||||
if (state->state & (EXTENT_IOBITS | EXTENT_BOUNDARY))
|
||||
return 0;
|
||||
|
||||
other_node = rb_prev(&state->rb_node);
|
||||
@@ -1070,7 +1070,8 @@ search_again:
|
||||
|
||||
while(1) {
|
||||
state = rb_entry(node, struct extent_state, rb_node);
|
||||
if (found && state->start != cur_start) {
|
||||
if (found && (state->start != cur_start ||
|
||||
(state->state & EXTENT_BOUNDARY))) {
|
||||
goto out;
|
||||
}
|
||||
if (!(state->state & EXTENT_DELALLOC)) {
|
||||
@@ -1078,7 +1079,7 @@ search_again:
|
||||
*end = state->end;
|
||||
goto out;
|
||||
}
|
||||
if (!found) {
|
||||
if (!found && !(state->state & EXTENT_BOUNDARY)) {
|
||||
struct extent_state *prev_state;
|
||||
struct rb_node *prev_node = node;
|
||||
while(1) {
|
||||
@@ -1088,7 +1089,11 @@ search_again:
|
||||
prev_state = rb_entry(prev_node,
|
||||
struct extent_state,
|
||||
rb_node);
|
||||
if (!(prev_state->state & EXTENT_DELALLOC))
|
||||
if ((prev_state->end + 1 != state->start) ||
|
||||
!(prev_state->state & EXTENT_DELALLOC))
|
||||
break;
|
||||
if ((cur_start - prev_state->start) * 2 >
|
||||
max_bytes)
|
||||
break;
|
||||
state = prev_state;
|
||||
node = prev_node;
|
||||
|
Reference in New Issue
Block a user