From cd241a8f554c258e92a694f6aa07e90b89ddebe6 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Wed, 3 Apr 2024 13:57:30 -0400 Subject: [PATCH] btrfs: move can_cow_file_range_inline() outside of the extent lock 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 Signed-off-by: Josef Bacik Signed-off-by: David Sterba --- fs/btrfs/inode.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index d6bad01c0cdf..4b728f30da5d 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -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);