]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
loop: add helper lo_rw_aio_prep()
authorMing Lei <ming.lei@redhat.com>
Wed, 15 Oct 2025 11:07:27 +0000 (19:07 +0800)
committerJens Axboe <axboe@kernel.dk>
Tue, 18 Nov 2025 13:49:51 +0000 (06:49 -0700)
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>
drivers/block/loop.c

index c6c37c9df193d09b085ecf051eac19a99ac6eff1..c0d8d290cb780704f951e316b39e7a30ae4919ba 100644 (file)
@@ -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);