From: Caleb Sander Mateos Date: Wed, 20 May 2026 20:36:54 +0000 (-0600) Subject: ublk: factor out ublk_init_iod() helper X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=23130b3ffcdb1568a9ef178ab3cba866e5486082;p=thirdparty%2Fkernel%2Flinux.git ublk: factor out ublk_init_iod() helper The code for initializing struct ublksrv_io_desc on I/O dispatch is largely duplicated in 3 places. Commit 4d4a512a1f87 ("ublk: add PFN- based buffer matching in I/O path") added support to ublk_setup_iod() for matching request buffers against registered UBLK_F_SHMEM_ZC buffers, but missed adding it to ublk_setup_iod_zoned() for zoned requests. Move the duplicated logic to a new helper ublk_init_iod(). This way, zone appends can also benefit from avoiding the data copy. Signed-off-by: Caleb Sander Mateos Reviewed-by: Ming Lei Link: https://patch.msgid.link/20260520203654.1413640-3-csander@purestorage.com Signed-off-by: Jens Axboe --- diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index 0cb29be561b54..49624e65fe75e 100644 --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -501,6 +501,31 @@ static inline unsigned int ublk_req_build_flags(struct request *req) return flags; } +static void ublk_init_iod(struct ublk_queue *ubq, struct request *req, + uint8_t ublk_op, uint32_t nr_sectors, + uint64_t start_sector) +{ + struct ublksrv_io_desc *iod = ublk_get_iod(ubq, req->tag); + struct ublk_io *io = &ubq->ios[req->tag]; + + iod->op_flags = ublk_op | ublk_req_build_flags(req); + iod->nr_sectors = nr_sectors; + iod->start_sector = start_sector; + + /* Try shmem zero-copy match before setting addr */ + if (ublk_support_shmem_zc(ubq) && blk_rq_has_data(req)) { + u32 buf_idx, buf_off; + + if (ublk_try_buf_match(ubq->dev, req, &buf_idx, &buf_off)) { + iod->op_flags |= UBLK_IO_F_SHMEM_ZC; + iod->addr = ublk_shmem_zc_addr(buf_idx, buf_off); + return; + } + } + + iod->addr = io->buf.addr; +} + #ifdef CONFIG_BLK_DEV_ZONED struct ublk_zoned_report_desc { @@ -682,8 +707,6 @@ out: static blk_status_t ublk_setup_iod_zoned(struct ublk_queue *ubq, struct request *req) { - struct ublksrv_io_desc *iod = ublk_get_iod(ubq, req->tag); - struct ublk_io *io = &ubq->ios[req->tag]; struct ublk_zoned_report_desc *desc; u32 ublk_op; @@ -713,9 +736,8 @@ static blk_status_t ublk_setup_iod_zoned(struct ublk_queue *ubq, ublk_op = desc->operation; switch (ublk_op) { case UBLK_IO_OP_REPORT_ZONES: - iod->op_flags = ublk_op | ublk_req_build_flags(req); - iod->nr_zones = desc->nr_zones; - iod->start_sector = desc->sector; + ublk_init_iod(ubq, req, ublk_op, desc->nr_zones, + desc->sector); return BLK_STS_OK; default: return BLK_STS_IOERR; @@ -727,11 +749,7 @@ static blk_status_t ublk_setup_iod_zoned(struct ublk_queue *ubq, return BLK_STS_IOERR; } - iod->op_flags = ublk_op | ublk_req_build_flags(req); - iod->nr_sectors = blk_rq_sectors(req); - iod->start_sector = blk_rq_pos(req); - iod->addr = io->buf.addr; - + ublk_init_iod(ubq, req, ublk_op, blk_rq_sectors(req), blk_rq_pos(req)); return BLK_STS_OK; } @@ -1470,8 +1488,6 @@ static unsigned int ublk_unmap_io(bool need_map, static blk_status_t ublk_setup_iod(struct ublk_queue *ubq, struct request *req) { - struct ublksrv_io_desc *iod = ublk_get_iod(ubq, req->tag); - struct ublk_io *io = &ubq->ios[req->tag]; u32 ublk_op; switch (req_op(req)) { @@ -1496,25 +1512,7 @@ static blk_status_t ublk_setup_iod(struct ublk_queue *ubq, struct request *req) return BLK_STS_IOERR; } - /* need to translate since kernel may change */ - iod->op_flags = ublk_op | ublk_req_build_flags(req); - iod->nr_sectors = blk_rq_sectors(req); - iod->start_sector = blk_rq_pos(req); - - /* Try shmem zero-copy match before setting addr */ - if (ublk_support_shmem_zc(ubq) && blk_rq_has_data(req)) { - u32 buf_idx, buf_off; - - if (ublk_try_buf_match(ubq->dev, req, - &buf_idx, &buf_off)) { - iod->op_flags |= UBLK_IO_F_SHMEM_ZC; - iod->addr = ublk_shmem_zc_addr(buf_idx, buf_off); - return BLK_STS_OK; - } - } - - iod->addr = io->buf.addr; - + ublk_init_iod(ubq, req, ublk_op, blk_rq_sectors(req), blk_rq_pos(req)); return BLK_STS_OK; }