diff options
| author | Ming Lei <ming.lei@redhat.com> | 2025-10-15 19:07:27 +0800 |
|---|---|---|
| committer | Jens Axboe <axboe@kernel.dk> | 2025-11-18 06:49:51 -0700 |
| commit | fd858d1ca9694c88703a8a936d5c7596c86ada74 (patch) | |
| tree | 6b1db18c54c8f9177159b8d588a2f10058d0b17a /drivers/block | |
| parent | c3e6c11147f6f05c15e9c2d74f5d234a6661013c (diff) | |
| download | linux-next-fd858d1ca9694c88703a8a936d5c7596c86ada74.tar.gz linux-next-fd858d1ca9694c88703a8a936d5c7596c86ada74.zip | |
loop: add helper lo_rw_aio_prep()
Add helper lo_rw_aio_prep() to separate the preparation phase(setting up bio
vectors and initializing the iocb structure) from the actual I/O execution
in the loop block driver.
Prepare for using NOWAIT to improve loop performance.
Signed-off-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block')
| -rw-r--r-- | drivers/block/loop.c | 63 |
1 files changed, 40 insertions, 23 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index c6c37c9df193..c0d8d290cb78 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -350,21 +350,15 @@ static inline unsigned lo_cmd_nr_bvec(struct loop_cmd *cmd) return nr_bvec; } -static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd, - loff_t pos, int rw) +static int lo_rw_aio_prep(struct loop_device *lo, struct loop_cmd *cmd, + unsigned nr_bvec, loff_t pos) { - struct iov_iter iter; - struct req_iterator rq_iter; - struct bio_vec *bvec; struct request *rq = blk_mq_rq_from_pdu(cmd); - struct bio *bio = rq->bio; - struct file *file = lo->lo_backing_file; - struct bio_vec tmp; - unsigned int offset; - int nr_bvec = lo_cmd_nr_bvec(cmd); - int ret; if (rq->bio != rq->biotail) { + struct req_iterator rq_iter; + struct bio_vec *bvec; + struct bio_vec tmp; bvec = kmalloc_array(nr_bvec, sizeof(struct bio_vec), GFP_NOIO); @@ -382,8 +376,42 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd, *bvec = tmp; bvec++; } - bvec = cmd->bvec; + } else { + cmd->bvec = NULL; + } + + cmd->iocb.ki_pos = pos; + cmd->iocb.ki_filp = lo->lo_backing_file; + cmd->iocb.ki_ioprio = req_get_ioprio(rq); + if (cmd->use_aio) { + cmd->iocb.ki_complete = lo_rw_aio_complete; + cmd->iocb.ki_flags = IOCB_DIRECT; + } else { + cmd->iocb.ki_complete = NULL; + cmd->iocb.ki_flags = 0; + } + return 0; +} + +static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd, + loff_t pos, int rw) +{ + struct iov_iter iter; + struct bio_vec *bvec; + struct request *rq = blk_mq_rq_from_pdu(cmd); + struct bio *bio = rq->bio; + struct file *file = lo->lo_backing_file; + unsigned int offset; + int nr_bvec = lo_cmd_nr_bvec(cmd); + int ret; + + ret = lo_rw_aio_prep(lo, cmd, nr_bvec, pos); + if (unlikely(ret)) + return ret; + + if (cmd->bvec) { offset = 0; + bvec = cmd->bvec; } else { /* * Same here, this bio may be started from the middle of the @@ -398,17 +426,6 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd, iov_iter_bvec(&iter, rw, bvec, nr_bvec, blk_rq_bytes(rq)); iter.iov_offset = offset; - cmd->iocb.ki_pos = pos; - cmd->iocb.ki_filp = file; - cmd->iocb.ki_ioprio = req_get_ioprio(rq); - if (cmd->use_aio) { - cmd->iocb.ki_complete = lo_rw_aio_complete; - cmd->iocb.ki_flags = IOCB_DIRECT; - } else { - cmd->iocb.ki_complete = NULL; - cmd->iocb.ki_flags = 0; - } - if (rw == ITER_SOURCE) { kiocb_start_write(&cmd->iocb); ret = file->f_op->write_iter(&cmd->iocb, &iter); |
