btrfs: push extent lock into run_delalloc_cow
authorJosef Bacik <josef@toxicpanda.com>
Wed, 3 Apr 2024 19:31:17 +0000 (15:31 -0400)
committerDavid Sterba <dsterba@suse.com>
Tue, 7 May 2024 19:31:09 +0000 (21:31 +0200)
This is used by zoned but also as the fallback for uncompressed extents
when we fail to compress the ranges.  Push the extent lock into
run_dealloc_cow(), and adjust the compression case to take the extent
lock after calling run_delalloc_cow().

Reviewed-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/inode.c

index 5337b54148e336c6af81e95da01d4bf66b95a84f..fea5a44e2719fa115133ec518c496fc8ec0d7086 100644 (file)
@@ -1167,13 +1167,13 @@ static void submit_one_async_extent(struct async_chunk *async_chunk,
                if (!(start >= locked_page_end || end <= locked_page_start))
                        locked_page = async_chunk->locked_page;
        }
-       lock_extent(io_tree, start, end, NULL);
 
        if (async_extent->compress_type == BTRFS_COMPRESS_NONE) {
                submit_uncompressed_range(inode, async_extent, locked_page);
                goto done;
        }
 
+       lock_extent(io_tree, start, end, NULL);
        ret = btrfs_reserve_extent(root, async_extent->ram_size,
                                   async_extent->compressed_size,
                                   async_extent->compressed_size,
@@ -1722,6 +1722,8 @@ static noinline int run_delalloc_cow(struct btrfs_inode *inode,
        u64 done_offset = end;
        int ret;
 
+       lock_extent(&inode->io_tree, start, end, NULL);
+
        while (start <= end) {
                ret = cow_file_range(inode, locked_page, start, end, &done_offset,
                                     true, false);
@@ -2280,17 +2282,14 @@ int btrfs_run_delalloc_range(struct btrfs_inode *inode, struct page *locked_page
            run_delalloc_compressed(inode, locked_page, start, end, wbc))
                return 1;
 
-       /*
-        * We're unlocked by the different fill functions below.
-        */
-       lock_extent(&inode->io_tree, start, end, NULL);
-
-       if (zoned)
+       if (zoned) {
                ret = run_delalloc_cow(inode, locked_page, start, end, wbc,
                                       true);
-       else
+       } else {
+               lock_extent(&inode->io_tree, start, end, NULL);
                ret = cow_file_range(inode, locked_page, start, end, NULL,
                                     false, false);
+       }
 
 out:
        if (ret < 0)