summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQu Wenruo <wqu@suse.com>2026-01-29 13:53:44 +1030
committerDavid Sterba <dsterba@suse.com>2026-02-03 07:59:07 +0100
commitdafcfa1c8e377a3d8e2e1d72a76435b57ed1ac7d (patch)
treeb47f43b0618873f5550ee80297ea2816e55a1b0c
parent26902be0cd0997b34ef13593e35ef3501a3c70b5 (diff)
btrfs: get rid of compressed_folios[] usage for compressed read
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>
-rw-r--r--fs/btrfs/compression.c41
1 files changed, 21 insertions, 20 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 875e0d2bcb5d..8501a5e4132d 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -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));
}
/*