summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorQu Wenruo <wqu@suse.com>2024-01-29 20:16:08 +1030
committerDavid Sterba <dsterba@suse.com>2024-05-07 21:31:02 +0200
commiteb1fa9ab470285d39bee268bc2a90d1786610711 (patch)
tree6dedd2286796c8f3fc83a66707125b6f5773f356 /fs/btrfs/inode.c
parent98fe01af7ebe44bcc11afe4b4d681e27b959adb4 (diff)
downloadlinux-eb1fa9ab470285d39bee268bc2a90d1786610711.tar.gz
linux-eb1fa9ab470285d39bee268bc2a90d1786610711.tar.bz2
linux-eb1fa9ab470285d39bee268bc2a90d1786610711.zip
btrfs: make insert_inline_extent() accept one page directly
Since our inline extent cannot accept anything larger than a sector, there is really no need to pass all the compressed pages to insert_inline_extent(). And just in case, expand the ASSERT()s to make sure we only try inline with compressed size no larger than sectorsize. Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c47
1 files changed, 25 insertions, 22 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 2deb662f171c..9096f8a34be9 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -512,12 +512,13 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
struct btrfs_inode *inode, bool extent_inserted,
size_t size, size_t compressed_size,
int compress_type,
- struct page **compressed_pages,
+ struct page *compressed_page,
bool update_i_size)
{
struct btrfs_root *root = inode->root;
struct extent_buffer *leaf;
struct page *page = NULL;
+ const u32 sectorsize = trans->fs_info->sectorsize;
char *kaddr;
unsigned long ptr;
struct btrfs_file_extent_item *ei;
@@ -525,10 +526,23 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
size_t cur_size = size;
u64 i_size;
- ASSERT((compressed_size > 0 && compressed_pages) ||
- (compressed_size == 0 && !compressed_pages));
+ /*
+ * The decompressed size must still be no larger than a sector. Under
+ * heavy race, we can have size == 0 passed in, but that shouldn't be a
+ * big deal and we can continue the insertion.
+ */
+ ASSERT(size <= sectorsize);
- if (compressed_size && compressed_pages)
+ /*
+ * The compressed size also needs to be no larger than a sector.
+ * That's also why we only need one page as the parameter.
+ */
+ if (compressed_page)
+ ASSERT(compressed_size <= sectorsize);
+ else
+ ASSERT(compressed_size == 0);
+
+ if (compressed_size && compressed_page)
cur_size = compressed_size;
if (!extent_inserted) {
@@ -556,21 +570,10 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
ptr = btrfs_file_extent_inline_start(ei);
if (compress_type != BTRFS_COMPRESS_NONE) {
- struct page *cpage;
- int i = 0;
- while (compressed_size > 0) {
- cpage = compressed_pages[i];
- cur_size = min_t(unsigned long, compressed_size,
- PAGE_SIZE);
-
- kaddr = kmap_local_page(cpage);
- write_extent_buffer(leaf, kaddr, ptr, cur_size);
- kunmap_local(kaddr);
+ kaddr = kmap_local_page(compressed_page);
+ write_extent_buffer(leaf, kaddr, ptr, compressed_size);
+ kunmap_local(kaddr);
- i++;
- ptr += cur_size;
- compressed_size -= cur_size;
- }
btrfs_set_file_extent_compression(leaf, ei,
compress_type);
} else {
@@ -620,7 +623,7 @@ fail:
static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 size,
size_t compressed_size,
int compress_type,
- struct page **compressed_pages,
+ struct page *compressed_page,
bool update_i_size)
{
struct btrfs_drop_extents_args drop_args = { 0 };
@@ -668,7 +671,7 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 size,
ret = insert_inline_extent(trans, path, inode, drop_args.extent_inserted,
size, compressed_size, compress_type,
- compressed_pages, update_i_size);
+ compressed_page, update_i_size);
if (ret && ret != -ENOSPC) {
btrfs_abort_transaction(trans, ret);
goto out;
@@ -976,7 +979,7 @@ again:
} else {
ret = cow_file_range_inline(inode, actual_end,
total_compressed,
- compress_type, pages,
+ compress_type, pages[0],
false);
}
if (ret <= 0) {
@@ -10460,7 +10463,7 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from,
if (start == 0 && encoded->unencoded_len == encoded->len &&
encoded->unencoded_offset == 0) {
ret = cow_file_range_inline(inode, encoded->len, orig_count,
- compression, pages, true);
+ compression, pages[0], true);
if (ret <= 0) {
if (ret == 0)
ret = orig_count;