diff options
| -rw-r--r-- | fs/btrfs/compression.c | 41 |
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)); } /* |
