aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/transaction.c
diff options
context:
space:
mode:
authorYan Zheng <zheng.yan@oracle.com>2009-07-22 10:07:05 -0400
committerChris Mason <chris.mason@oracle.com>2009-07-22 10:07:05 -0400
commit4a8c9a62d7f7f058eed4b8a6f2c890a887778093 (patch)
treed3d099197e5ddc94f737dbad273810b902b05307 /fs/btrfs/transaction.c
parent33c66f430bfa3a033e70470e4c93f967156b696d (diff)
Btrfs: make sure all dirty blocks are written at commit time
Write dirty block groups may allocate new block, and so may add new delayed back ref. btrfs_run_delayed_refs may make some block groups dirty. commit_cowonly_roots does not handle the recursion properly, and some dirty blocks can be left unwritten at commit time. This patch moves btrfs_run_delayed_refs into the loop that writes dirty block groups, and makes the code not break out of the loop until there are no dirty block groups or delayed back refs. 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.c9
1 files changed, 1 insertions, 8 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 2dbf1c1f56ee..81f7124c3051 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -444,9 +444,6 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans,
444 444
445 btrfs_write_dirty_block_groups(trans, root); 445 btrfs_write_dirty_block_groups(trans, root);
446 446
447 ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1);
448 BUG_ON(ret);
449
450 while (1) { 447 while (1) {
451 old_root_bytenr = btrfs_root_bytenr(&root->root_item); 448 old_root_bytenr = btrfs_root_bytenr(&root->root_item);
452 if (old_root_bytenr == root->node->start) 449 if (old_root_bytenr == root->node->start)
@@ -457,9 +454,8 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans,
457 &root->root_key, 454 &root->root_key,
458 &root->root_item); 455 &root->root_item);
459 BUG_ON(ret); 456 BUG_ON(ret);
460 btrfs_write_dirty_block_groups(trans, root);
461 457
462 ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); 458 ret = btrfs_write_dirty_block_groups(trans, root);
463 BUG_ON(ret); 459 BUG_ON(ret);
464 } 460 }
465 free_extent_buffer(root->commit_root); 461 free_extent_buffer(root->commit_root);
@@ -495,9 +491,6 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans,
495 root = list_entry(next, struct btrfs_root, dirty_list); 491 root = list_entry(next, struct btrfs_root, dirty_list);
496 492
497 update_cowonly_root(trans, root); 493 update_cowonly_root(trans, root);
498
499 ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1);
500 BUG_ON(ret);
501 } 494 }
502 return 0; 495 return 0;
503} 496}