diff options
author | Chris Mason <clm@fb.com> | 2016-01-11 08:39:28 -0800 |
---|---|---|
committer | Chris Mason <clm@fb.com> | 2016-01-11 08:39:28 -0800 |
commit | 988f1f576d4f7531cb2175ee1b7cb7afd6d95d22 (patch) | |
tree | bd7d676abc4b13b749d3ad6cb41e7872a6fdfb2f /fs/btrfs/extent-tree.c | |
parent | b28cf57246d5b797ba725bb033110c247f2c301f (diff) | |
parent | 8cdc7c5b00d945a3c823fc4277af304abb9cb43d (diff) |
Merge branch 'for-chris-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/fdmanana/linux into for-linus-4.5
Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 03d29ead2a0f..60cc1399c64f 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, } if (!ret) { ret = write_one_cache_group(trans, root, path, cache); + /* + * One of the free space endio workers might have + * created a new block group while updating a free space + * cache's inode (at inode.c:btrfs_finish_ordered_io()) + * and hasn't released its transaction handle yet, in + * which case the new block group is still attached to + * its transaction handle and its creation has not + * finished yet (no block group item in the extent tree + * yet, etc). If this is the case, wait for all free + * space endio workers to finish and retry. This is a + * a very rare case so no need for a more efficient and + * complex approach. + */ + if (ret == -ENOENT) { + wait_event(cur_trans->writer_wait, + atomic_read(&cur_trans->num_writers) == 1); + ret = write_one_cache_group(trans, root, path, + cache); + } if (ret) btrfs_abort_transaction(trans, root, ret); } |