diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c index a2111eab614f2a..77aa763002eacf 100644 --- a/fs/btrfs/block-group.c +++ b/fs/btrfs/block-group.c @@ -2582,8 +2582,10 @@ int btrfs_start_dirty_block_groups(struct btrfs_trans_handle *trans) if (!path) { path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; + if (!path) { + ret = -ENOMEM; + goto out; + } } /* @@ -2677,16 +2679,14 @@ int btrfs_start_dirty_block_groups(struct btrfs_trans_handle *trans) btrfs_put_block_group(cache); if (drop_reserve) btrfs_delayed_refs_rsv_release(fs_info, 1); - - if (ret) - break; - /* * Avoid blocking other tasks for too long. It might even save * us from writing caches for block groups that are going to be * removed. */ mutex_unlock(&trans->transaction->cache_write_mutex); + if (ret) + goto out; mutex_lock(&trans->transaction->cache_write_mutex); } mutex_unlock(&trans->transaction->cache_write_mutex); @@ -2710,7 +2710,12 @@ int btrfs_start_dirty_block_groups(struct btrfs_trans_handle *trans) goto again; } spin_unlock(&cur_trans->dirty_bgs_lock); - } else if (ret < 0) { + } +out: + if (ret < 0) { + spin_lock(&cur_trans->dirty_bgs_lock); + list_splice_init(&dirty, &cur_trans->dirty_bgs); + spin_unlock(&cur_trans->dirty_bgs_lock); btrfs_cleanup_dirty_bgs(cur_trans, fs_info); }