From: Alexandre Oliva btrfs: consume force_alloc in the first thread to chunk_alloc Even if multiple threads in do_chunk_alloc look at force_alloc and see a force flag, it suffices that one of them consumes the flag. Arrange for an incoming force argument to make to force_alloc in case of concurrent calls, so that it is used only by the first thread to get to allocation after the initial request. Signed-off-by: Alexandre Oliva --- fs/btrfs/extent-tree.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 6ee89d5..66283f7 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -3574,8 +3574,12 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, again: spin_lock(&space_info->lock); + + /* Bring force_alloc to force and tentatively consume it. */ if (force < space_info->force_alloc) force = space_info->force_alloc; + space_info->force_alloc = CHUNK_ALLOC_NO_FORCE; + if (space_info->full) { spin_unlock(&space_info->lock); return 0; @@ -3586,6 +3590,10 @@ again: return 0; } else if (space_info->chunk_alloc) { wait_for_alloc = 1; + /* Reset force_alloc so that it's consumed by the + first thread that completes the allocation. */ + space_info->force_alloc = force; + force = CHUNK_ALLOC_NO_FORCE; } else { space_info->chunk_alloc = 1; }