]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
btrfs: get rid of compressed_folios[] usage for compressed read
authorQu Wenruo <wqu@suse.com>
Thu, 29 Jan 2026 03:23:44 +0000 (13:53 +1030)
committerDavid Sterba <dsterba@suse.com>
Tue, 3 Feb 2026 06:59:07 +0000 (07:59 +0100)
Currently btrfs_submit_compressed_read() still uses
compressed_bio::compressed_folios[] array.

Change it to allocate each folio and queue them into the compressed bio
so that we do not need to allocate that array.

Considering how small each compressed read bio is (less than 128KiB), we
do not benefit that much from btrfs_alloc_folio_array() anyway,
while we may benefit more from btrfs_alloc_compr_folio() by using
the global folio pool.

So changing from btrfs_alloc_folio_array() to btrfs_alloc_compr_folio()
in a loop should still be fine.

This removes one error path, and paves the way to completely remove
compressed_folios[] array.

Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/compression.c

index 875e0d2bcb5d00f781022b071d07b14018020c67..8501a5e4132d529ef4344768d2de21f1030b63e8 100644 (file)
@@ -239,7 +239,7 @@ static void end_bbio_compressed_read(struct btrfs_bio *bbio)
 
        btrfs_bio_end_io(cb->orig_bbio, status);
        bio_for_each_folio_all(fi, &bbio->bio)
-               folio_put(fi.folio);
+               btrfs_free_compr_folio(fi.folio);
        bio_put(&bbio->bio);
 }
 
@@ -537,13 +537,13 @@ void btrfs_submit_compressed_read(struct btrfs_bio *bbio)
        struct extent_map_tree *em_tree = &inode->extent_tree;
        struct compressed_bio *cb;
        unsigned int compressed_len;
+       const u32 min_folio_size = btrfs_min_folio_size(fs_info);
        u64 file_offset = bbio->file_offset;
        u64 em_len;
        u64 em_start;
        struct extent_map *em;
        unsigned long pflags;
        int memstall = 0;
-       blk_status_t status;
        int ret;
 
        /* we need the actual starting offset of this extent in the file */
@@ -551,7 +551,7 @@ void btrfs_submit_compressed_read(struct btrfs_bio *bbio)
        em = btrfs_lookup_extent_mapping(em_tree, file_offset, fs_info->sectorsize);
        read_unlock(&em_tree->lock);
        if (!em) {
-               status = BLK_STS_IOERR;
+               ret = -EIO;
                goto out;
        }
 
@@ -573,27 +573,30 @@ void btrfs_submit_compressed_read(struct btrfs_bio *bbio)
 
        btrfs_free_extent_map(em);
 
-       cb->nr_folios = DIV_ROUND_UP(compressed_len, btrfs_min_folio_size(fs_info));
-       cb->compressed_folios = kcalloc(cb->nr_folios, sizeof(struct folio *), GFP_NOFS);
-       if (!cb->compressed_folios) {
-               status = BLK_STS_RESOURCE;
-               goto out_free_bio;
-       }
+       for (int i = 0; i * min_folio_size < compressed_len; i++) {
+               struct folio *folio;
+               u32 cur_len = min(compressed_len - i * min_folio_size, min_folio_size);
 
-       ret = btrfs_alloc_folio_array(cb->nr_folios, fs_info->block_min_order,
-                                     cb->compressed_folios);
-       if (ret) {
-               status = BLK_STS_RESOURCE;
-               goto out_free_compressed_pages;
+               folio = btrfs_alloc_compr_folio(fs_info);
+               if (!folio) {
+                       ret = -ENOMEM;
+                       goto out_free_bio;
+               }
+
+               ret = bio_add_folio(&cb->bbio.bio, folio, cur_len, 0);
+               if (unlikely(!ret)) {
+                       folio_put(folio);
+                       ret = -EINVAL;
+                       goto out_free_bio;
+               }
        }
+       ASSERT(cb->bbio.bio.bi_iter.bi_size == compressed_len);
 
        add_ra_bio_pages(&inode->vfs_inode, em_start + em_len, cb, &memstall,
                         &pflags);
 
-       /* include any pages we added in add_ra-bio_pages */
        cb->len = bbio->bio.bi_iter.bi_size;
        cb->bbio.bio.bi_iter.bi_sector = bbio->bio.bi_iter.bi_sector;
-       btrfs_add_compressed_bio_folios(cb);
 
        if (memstall)
                psi_memstall_leave(&pflags);
@@ -601,12 +604,10 @@ void btrfs_submit_compressed_read(struct btrfs_bio *bbio)
        btrfs_submit_bbio(&cb->bbio, 0);
        return;
 
-out_free_compressed_pages:
-       kfree(cb->compressed_folios);
 out_free_bio:
-       bio_put(&cb->bbio.bio);
+       cleanup_compressed_bio(cb);
 out:
-       btrfs_bio_end_io(bbio, status);
+       btrfs_bio_end_io(bbio, errno_to_blk_status(ret));
 }
 
 /*