]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
btrfs: lock extent when doing inline extent in compression
authorJosef Bacik <josef@toxicpanda.com>
Wed, 3 Apr 2024 17:42:45 +0000 (13:42 -0400)
committerDavid Sterba <dsterba@suse.com>
Tue, 7 May 2024 19:31:09 +0000 (21:31 +0200)
We currently don't lock the extent when we're doing a
cow_file_range_inline() for a compressed extent.  This isn't a problem
necessarily, but it's inconsistent with the rest of our usage of
cow_file_range_inline().  This also leads to some extra weird logic
around whether the extent is locked or not.  Fix this to lock the extent
before calling cow_file_range_inline() in compression to make it
consistent with the rest of the inline users.  In future patches this
will be pushed down into the cow_file_range_inline() helper, so we're
fine with the quick and dirty locking here.  This patch exists to make
the behavior change obvious.

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

index be079e4971e5b1730b8646a8c54ad8ef704f8391..d82c453ae9d7cbd08c71ec5214c3fc56989017ca 100644 (file)
@@ -742,10 +742,10 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 offset,
                                          size_t compressed_size,
                                          int compress_type,
                                          struct folio *compressed_folio,
-                                         bool update_i_size, bool locked)
+                                         bool update_i_size)
 {
        unsigned long clear_flags = EXTENT_DELALLOC | EXTENT_DELALLOC_NEW |
-               EXTENT_DEFRAG | EXTENT_DO_ACCOUNTING;
+               EXTENT_DEFRAG | EXTENT_DO_ACCOUNTING | EXTENT_LOCKED;
        u64 size = min_t(u64, i_size_read(&inode->vfs_inode), end + 1);
        int ret;
 
@@ -755,9 +755,6 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 offset,
        if (ret > 0)
                return ret;
 
-       if (locked)
-               clear_flags |= EXTENT_LOCKED;
-
        extent_clear_unlock_delalloc(inode, offset, end, NULL, clear_flags,
                                     PAGE_UNLOCK | PAGE_START_WRITEBACK |
                                     PAGE_END_WRITEBACK);
@@ -1031,18 +1028,19 @@ again:
         * Check cow_file_range() for why we don't even try to create inline
         * extent for the subpage case.
         */
+       lock_extent(&inode->io_tree, start, end, NULL);
        if (total_in < actual_end)
                ret = cow_file_range_inline(inode, start, end, 0,
-                                           BTRFS_COMPRESS_NONE, NULL, false,
-                                           false);
+                                           BTRFS_COMPRESS_NONE, NULL, false);
        else
                ret = cow_file_range_inline(inode, start, end, total_compressed,
-                                           compress_type, folios[0], false, false);
+                                           compress_type, folios[0], false);
        if (ret <= 0) {
                if (ret < 0)
                        mapping_set_error(mapping, -EIO);
                goto free_pages;
        }
+       unlock_extent(&inode->io_tree, start, end, NULL);
 
        /*
         * We aren't doing an inline extent. Round the compressed size up to a
@@ -1352,8 +1350,7 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
        if (!no_inline) {
                /* lets try to make an inline extent */
                ret = cow_file_range_inline(inode, start, end, 0,
-                                           BTRFS_COMPRESS_NONE, NULL, false,
-                                           true);
+                                           BTRFS_COMPRESS_NONE, NULL, false);
                if (ret <= 0) {
                        /*
                         * We succeeded, return 1 so the caller knows we're done