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);
}
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 */
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;
}
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);
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));
}
/*