Commit dafcfa1c authored by Qu Wenruo's avatar Qu Wenruo Committed by David Sterba
Browse files

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: default avatarBoris Burkov <boris@bur.io>
Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 26902be0
Loading
Loading
Loading
Loading
+21 −20
Original line number Diff line number Diff line
@@ -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;
	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);

		folio = btrfs_alloc_compr_folio(fs_info);
		if (!folio) {
			ret = -ENOMEM;
			goto out_free_bio;
		}

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

/*