xfs: simplify xfs_rw_bdev

Delegate to bdev_rw_virt when operating on non-vmalloc memory and use
bio_add_vmalloc_chunk to insulate xfs from the details of adding vmalloc
memory to a bio.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Link: https://lore.kernel.org/r/20250507120451.4000627-17-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Christoph Hellwig 2025-05-07 14:04:40 +02:00 committed by Jens Axboe
parent 9dccf2aa6e
commit d486bbecc9
1 changed files with 12 additions and 18 deletions

View File

@ -18,42 +18,36 @@ xfs_rw_bdev(
enum req_op op) enum req_op op)
{ {
unsigned int is_vmalloc = is_vmalloc_addr(data); unsigned int done = 0, added;
unsigned int left = count;
int error; int error;
struct bio *bio; struct bio *bio;
if (is_vmalloc && op == REQ_OP_WRITE) op |= REQ_META | REQ_SYNC;
flush_kernel_vmap_range(data, count); if (!is_vmalloc_addr(data))
return bdev_rw_virt(bdev, sector, data, count, op);
bio = bio_alloc(bdev, bio_max_vecs(left), op | REQ_META | REQ_SYNC, bio = bio_alloc(bdev, bio_max_vecs(count), op, GFP_KERNEL);
GFP_KERNEL);
bio->bi_iter.bi_sector = sector; bio->bi_iter.bi_sector = sector;
do { do {
struct page *page = kmem_to_page(data); added = bio_add_vmalloc_chunk(bio, data + done, count - done);
unsigned int off = offset_in_page(data); if (!added) {
unsigned int len = min_t(unsigned, left, PAGE_SIZE - off);
while (bio_add_page(bio, page, len, off) != len) {
struct bio *prev = bio; struct bio *prev = bio;
bio = bio_alloc(prev->bi_bdev, bio_max_vecs(left), bio = bio_alloc(prev->bi_bdev,
bio_max_vecs(count - done),
prev->bi_opf, GFP_KERNEL); prev->bi_opf, GFP_KERNEL);
bio->bi_iter.bi_sector = bio_end_sector(prev); bio->bi_iter.bi_sector = bio_end_sector(prev);
bio_chain(prev, bio); bio_chain(prev, bio);
submit_bio(prev); submit_bio(prev);
} }
done += added;
data += len; } while (done < count);
left -= len;
} while (left > 0);
error = submit_bio_wait(bio); error = submit_bio_wait(bio);
bio_put(bio); bio_put(bio);
if (is_vmalloc && op == REQ_OP_READ) if (op == REQ_OP_READ)
invalidate_kernel_vmap_range(data, count); invalidate_kernel_vmap_range(data, count);
return error; return error;
} }