aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/extent-tree.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index add4af641cfa..cf8983e4a2eb 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3768,6 +3768,25 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
3768 } 3768 }
3769 if (!ret) { 3769 if (!ret) {
3770 ret = write_one_cache_group(trans, root, path, cache); 3770 ret = write_one_cache_group(trans, root, path, cache);
3771 /*
3772 * One of the free space endio workers might have
3773 * created a new block group while updating a free space
3774 * cache's inode (at inode.c:btrfs_finish_ordered_io())
3775 * and hasn't released its transaction handle yet, in
3776 * which case the new block group is still attached to
3777 * its transaction handle and its creation has not
3778 * finished yet (no block group item in the extent tree
3779 * yet, etc). If this is the case, wait for all free
3780 * space endio workers to finish and retry. This is a
3781 * a very rare case so no need for a more efficient and
3782 * complex approach.
3783 */
3784 if (ret == -ENOENT) {
3785 wait_event(cur_trans->writer_wait,
3786 atomic_read(&cur_trans->num_writers) == 1);
3787 ret = write_one_cache_group(trans, root, path,
3788 cache);
3789 }
3771 if (ret) 3790 if (ret)
3772 btrfs_abort_transaction(trans, root, ret); 3791 btrfs_abort_transaction(trans, root, ret);
3773 } 3792 }