Make sure all dirty blocks are written at commit time
PATCH 1/1 Make sure all dirty blocks are written at commit time
Write dirty block groups may allocate new block, thus 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, so some dirty blocks can be left unwritten at commit time. This patch move btrfs_run_delayed_refs into the loop that writes dirty block groups, and make the code not break out of the loop until there is no dirty block group and delayed back ref.
Signed-off-by Yan Zheng <[email protected]>
---
fs/btrfs/ctree.c +0 -3
@@ -1043,9 +1043,6 @@ static noinline int balance_level(struct BTRFS_NODEPTRS_PER_BLOCK(root) / 4)return 0 ; -if (btrfs_header_nritems (mid) >2 ) -return 0 ; -if (btrfs_header_nritems (mid) <2 ) err_on_enospc =1 ;
fs/btrfs/extent-tree.c +41 -29
93 lines not on this page · raw message
fs/btrfs/transaction.c +1 -8
@@ -444,9 +444,6 @@ static int update_cowonly_root(struct btbtrfs_write_dirty_block_groups (trans, root); - ret =btrfs_run_delayed_refs (trans, root, (unsigned long )-1 ); -BUG_ON (ret); -while (1 ) { old_root_bytenr =btrfs_root_bytenr (&root->root_item);if (old_root_bytenr == root->node->start)
@@ -457,9 +454,8 @@ static int update_cowonly_root(struct bt &root->root_key, &root->root_item);BUG_ON (ret); -btrfs_write_dirty_block_groups (trans, root); - ret =btrfs_run_delayed_refs (trans, root, (unsigned long )-1 ); + ret =btrfs_write_dirty_block_groups (trans, root);BUG_ON (ret); }free_extent_buffer (root->commit_root);
@@ -495,9 +491,6 @@ static noinline int commit_cowonly_roots root = list_entry(next, struct btrfs_root, dirty_list);update_cowonly_root (trans, root); - - ret =btrfs_run_delayed_refs (trans, root, (unsigned long )-1 ); -BUG_ON (ret); }return 0 ; }