mirror of https://github.com/torvalds/linux.git
block: add a bdev_rw_virt helper
Add a helper to perform synchronous I/O on a kernel direct map range. Currently this is implemented in various places in usually not very efficient ways, so provide a generic helper instead. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Link: https://lore.kernel.org/r/20250507120451.4000627-3-hch@lst.de Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
850e210d5a
commit
10b1e59cda
30
block/bio.c
30
block/bio.c
|
|
@ -1319,6 +1319,36 @@ int submit_bio_wait(struct bio *bio)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(submit_bio_wait);
|
EXPORT_SYMBOL(submit_bio_wait);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bdev_rw_virt - synchronously read into / write from kernel mapping
|
||||||
|
* @bdev: block device to access
|
||||||
|
* @sector: sector to access
|
||||||
|
* @data: data to read/write
|
||||||
|
* @len: length in byte to read/write
|
||||||
|
* @op: operation (e.g. REQ_OP_READ/REQ_OP_WRITE)
|
||||||
|
*
|
||||||
|
* Performs synchronous I/O to @bdev for @data/@len. @data must be in
|
||||||
|
* the kernel direct mapping and not a vmalloc address.
|
||||||
|
*/
|
||||||
|
int bdev_rw_virt(struct block_device *bdev, sector_t sector, void *data,
|
||||||
|
size_t len, enum req_op op)
|
||||||
|
{
|
||||||
|
struct bio_vec bv;
|
||||||
|
struct bio bio;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
if (WARN_ON_ONCE(is_vmalloc_addr(data)))
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
bio_init(&bio, bdev, &bv, 1, op);
|
||||||
|
bio.bi_iter.bi_sector = sector;
|
||||||
|
bio_add_virt_nofail(&bio, data, len);
|
||||||
|
error = submit_bio_wait(&bio);
|
||||||
|
bio_uninit(&bio);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(bdev_rw_virt);
|
||||||
|
|
||||||
static void bio_wait_end_io(struct bio *bio)
|
static void bio_wait_end_io(struct bio *bio)
|
||||||
{
|
{
|
||||||
complete(bio->bi_private);
|
complete(bio->bi_private);
|
||||||
|
|
|
||||||
|
|
@ -402,7 +402,6 @@ static inline int bio_iov_vecs_to_alloc(struct iov_iter *iter, int max_segs)
|
||||||
|
|
||||||
struct request_queue;
|
struct request_queue;
|
||||||
|
|
||||||
extern int submit_bio_wait(struct bio *bio);
|
|
||||||
void bio_init(struct bio *bio, struct block_device *bdev, struct bio_vec *table,
|
void bio_init(struct bio *bio, struct block_device *bdev, struct bio_vec *table,
|
||||||
unsigned short max_vecs, blk_opf_t opf);
|
unsigned short max_vecs, blk_opf_t opf);
|
||||||
extern void bio_uninit(struct bio *);
|
extern void bio_uninit(struct bio *);
|
||||||
|
|
@ -419,6 +418,10 @@ void bio_add_folio_nofail(struct bio *bio, struct folio *folio, size_t len,
|
||||||
size_t off);
|
size_t off);
|
||||||
void bio_add_virt_nofail(struct bio *bio, void *vaddr, unsigned len);
|
void bio_add_virt_nofail(struct bio *bio, void *vaddr, unsigned len);
|
||||||
|
|
||||||
|
int submit_bio_wait(struct bio *bio);
|
||||||
|
int bdev_rw_virt(struct block_device *bdev, sector_t sector, void *data,
|
||||||
|
size_t len, enum req_op op);
|
||||||
|
|
||||||
int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter);
|
int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter);
|
||||||
void bio_iov_bvec_set(struct bio *bio, const struct iov_iter *iter);
|
void bio_iov_bvec_set(struct bio *bio, const struct iov_iter *iter);
|
||||||
void __bio_release_pages(struct bio *bio, bool mark_dirty);
|
void __bio_release_pages(struct bio *bio, bool mark_dirty);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue