]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
btrfs: move can_cow_file_range_inline() outside of the extent lock
authorJosef Bacik <josef@toxicpanda.com>
Wed, 3 Apr 2024 17:57:30 +0000 (13:57 -0400)
committerDavid Sterba <dsterba@suse.com>
Tue, 7 May 2024 19:31:10 +0000 (21:31 +0200)
These checks aren't reliant on the extent lock.  Move this up into
cow_file_range_inline(), and then update encoded writes to call this
check before calling __cow_file_range_inline().  This will allow us to
skip the extent lock if we're not able to inline the given extent.

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 d6bad01c0cdfab2baf167134e64a39e0ee65d016..4b728f30da5d68b9e3059843ddf66b85201fb47b 100644 (file)
@@ -661,6 +661,9 @@ static bool can_cow_file_range_inline(struct btrfs_inode *inode,
  * conditionally insert an inline extent into the file.  This
  * does the checks required to make sure the data is small enough
  * to fit as an inline extent.
+ *
+ * If being used directly, you must have already checked we're allowed to cow
+ * the range by getting true from can_cow_file_range_inline().
  */
 static noinline int __cow_file_range_inline(struct btrfs_inode *inode, u64 offset,
                                            u64 size, size_t compressed_size,
@@ -676,9 +679,6 @@ static noinline int __cow_file_range_inline(struct btrfs_inode *inode, u64 offse
        int ret;
        struct btrfs_path *path;
 
-       if (!can_cow_file_range_inline(inode, offset, size, compressed_size))
-               return 1;
-
        path = btrfs_alloc_path();
        if (!path)
                return -ENOMEM;
@@ -750,6 +750,9 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 offset,
        u64 size = min_t(u64, i_size_read(&inode->vfs_inode), end + 1);
        int ret;
 
+       if (!can_cow_file_range_inline(inode, offset, size, compressed_size))
+               return 1;
+
        lock_extent(&inode->io_tree, offset, end, &cached);
        ret = __cow_file_range_inline(inode, offset, size, compressed_size,
                                      compress_type, compressed_folio,
@@ -10287,7 +10290,8 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from,
 
        /* Try an inline extent first. */
        if (encoded->unencoded_len == encoded->len &&
-           encoded->unencoded_offset == 0) {
+           encoded->unencoded_offset == 0 &&
+           can_cow_file_range_inline(inode, start, encoded->len, orig_count)) {
                ret = __cow_file_range_inline(inode, start, encoded->len,
                                              orig_count, compression, folios[0],
                                              true);