diff options
author | Yan Zheng <zheng.yan@oracle.com> | 2009-07-30 09:40:40 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2009-07-30 09:40:40 -0400 |
commit | 276e680d192a67d222fcea51af37b056feffb665 (patch) | |
tree | 137bae016c30f24e7fafcbc8073e3411b732eb31 /fs/btrfs/transaction.c | |
parent | f25784b35f590c81d5fb8245a8cd45e1afb6f1b2 (diff) |
Btrfs: preserve commit_root for async caching
The async block group caching code uses the commit_root pointer
to get a stable version of the extent allocation tree for scanning.
This copy of the tree root isn't going to change and it significantly
reduces the complexity of the scanning code.
During a commit, we have a loop where we update the extent allocation
tree root. We need to loop because updating the root pointer in
the tree of tree roots may allocate blocks which may change the
extent allocation tree.
Right now the commit_root pointer is changed inside this loop. It
is more correct to change the commit_root pointer only after all the
looping is done.
Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r-- | fs/btrfs/transaction.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index e51d2bc532f8..de48e4ec808c 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -42,10 +42,8 @@ static noinline void put_transaction(struct btrfs_transaction *transaction) | |||
42 | 42 | ||
43 | static noinline void switch_commit_root(struct btrfs_root *root) | 43 | static noinline void switch_commit_root(struct btrfs_root *root) |
44 | { | 44 | { |
45 | down_write(&root->commit_root_sem); | ||
46 | free_extent_buffer(root->commit_root); | 45 | free_extent_buffer(root->commit_root); |
47 | root->commit_root = btrfs_root_node(root); | 46 | root->commit_root = btrfs_root_node(root); |
48 | up_write(&root->commit_root_sem); | ||
49 | } | 47 | } |
50 | 48 | ||
51 | /* | 49 | /* |
@@ -466,7 +464,10 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans, | |||
466 | ret = btrfs_write_dirty_block_groups(trans, root); | 464 | ret = btrfs_write_dirty_block_groups(trans, root); |
467 | BUG_ON(ret); | 465 | BUG_ON(ret); |
468 | } | 466 | } |
469 | switch_commit_root(root); | 467 | |
468 | if (root != root->fs_info->extent_root) | ||
469 | switch_commit_root(root); | ||
470 | |||
470 | return 0; | 471 | return 0; |
471 | } | 472 | } |
472 | 473 | ||
@@ -499,6 +500,11 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, | |||
499 | 500 | ||
500 | update_cowonly_root(trans, root); | 501 | update_cowonly_root(trans, root); |
501 | } | 502 | } |
503 | |||
504 | down_write(&fs_info->extent_commit_sem); | ||
505 | switch_commit_root(fs_info->extent_root); | ||
506 | up_write(&fs_info->extent_commit_sem); | ||
507 | |||
502 | return 0; | 508 | return 0; |
503 | } | 509 | } |
504 | 510 | ||