From: Ming Lei <ming.lei@redhat.com>
To: Caleb Sander Mateos <csander@purestorage.com>
Cc: Jens Axboe <axboe@kernel.dk>, Shuah Khan <shuah@kernel.org>,
linux-block@vger.kernel.org, linux-kselftest@vger.kernel.org,
linux-kernel@vger.kernel.org,
Stanley Zhang <stazhang@purestorage.com>,
Uday Shankar <ushankar@purestorage.com>,
"Martin K . Petersen" <martin.petersen@oracle.com>
Subject: Re: [PATCH v3 09/19] ublk: implement integrity user copy
Date: Tue, 6 Jan 2026 21:34:34 +0800 [thread overview]
Message-ID: <aV0PauBTiqWVQ-26@fedora> (raw)
In-Reply-To: <20260106005752.3784925-10-csander@purestorage.com>
On Mon, Jan 05, 2026 at 05:57:41PM -0700, Caleb Sander Mateos wrote:
> From: Stanley Zhang <stazhang@purestorage.com>
>
> Add a function ublk_copy_user_integrity() to copy integrity information
> between a request and a user iov_iter. This mirrors the existing
> ublk_copy_user_pages() but operates on request integrity data instead of
> regular data. Check UBLKSRV_IO_INTEGRITY_FLAG in iocb->ki_pos in
> ublk_user_copy() to choose between copying data or integrity data.
>
> Signed-off-by: Stanley Zhang <stazhang@purestorage.com>
> [csander: change offset units from data bytes to integrity data bytes,
> test UBLKSRV_IO_INTEGRITY_FLAG after subtracting UBLKSRV_IO_BUF_OFFSET,
> fix CONFIG_BLK_DEV_INTEGRITY=n build,
> rebase on ublk user copy refactor]
> Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>
> ---
> drivers/block/ublk_drv.c | 52 +++++++++++++++++++++++++++++++++--
> include/uapi/linux/ublk_cmd.h | 4 +++
> 2 files changed, 53 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
> index e44ab9981ef4..9694a4c1caa7 100644
> --- a/drivers/block/ublk_drv.c
> +++ b/drivers/block/ublk_drv.c
> @@ -621,10 +621,15 @@ static inline unsigned ublk_pos_to_tag(loff_t pos)
> {
> return ((pos - UBLKSRV_IO_BUF_OFFSET) >> UBLK_TAG_OFF) &
> UBLK_TAG_BITS_MASK;
> }
>
> +static inline bool ublk_pos_is_integrity(loff_t pos)
> +{
> + return !!((pos - UBLKSRV_IO_BUF_OFFSET) & UBLKSRV_IO_INTEGRITY_FLAG);
> +}
> +
It could be more readable to check UBLKSRV_IO_INTEGRITY_FLAG only.
> static void ublk_dev_param_basic_apply(struct ublk_device *ub)
> {
> const struct ublk_param_basic *p = &ub->params.basic;
>
> if (p->attrs & UBLK_ATTR_READ_ONLY)
> @@ -1047,10 +1052,37 @@ static size_t ublk_copy_user_pages(const struct request *req,
> break;
> }
> return done;
> }
>
> +#ifdef CONFIG_BLK_DEV_INTEGRITY
> +static size_t ublk_copy_user_integrity(const struct request *req,
> + unsigned offset, struct iov_iter *uiter, int dir)
> +{
> + size_t done = 0;
> + struct bio *bio = req->bio;
> + struct bvec_iter iter;
> + struct bio_vec iv;
> +
> + if (!blk_integrity_rq(req))
> + return 0;
> +
> + bio_for_each_integrity_vec(iv, bio, iter) {
> + if (!ublk_copy_user_bvec(&iv, &offset, uiter, dir, &done))
> + break;
> + }
> +
> + return done;
> +}
> +#else /* #ifdef CONFIG_BLK_DEV_INTEGRITY */
> +static size_t ublk_copy_user_integrity(const struct request *req,
> + unsigned offset, struct iov_iter *uiter, int dir)
> +{
> + return 0;
> +}
> +#endif /* #ifdef CONFIG_BLK_DEV_INTEGRITY */
> +
> static inline bool ublk_need_map_req(const struct request *req)
> {
> return ublk_rq_has_data(req) && req_op(req) == REQ_OP_WRITE;
> }
>
> @@ -2654,10 +2686,12 @@ ublk_user_copy(struct kiocb *iocb, struct iov_iter *iter, int dir)
> {
> struct ublk_device *ub = iocb->ki_filp->private_data;
> struct ublk_queue *ubq;
> struct request *req;
> struct ublk_io *io;
> + unsigned data_len;
> + bool is_integrity;
> size_t buf_off;
> u16 tag, q_id;
> ssize_t ret;
>
> if (!user_backed_iter(iter))
> @@ -2667,10 +2701,11 @@ ublk_user_copy(struct kiocb *iocb, struct iov_iter *iter, int dir)
> return -EACCES;
>
> tag = ublk_pos_to_tag(iocb->ki_pos);
> q_id = ublk_pos_to_hwq(iocb->ki_pos);
> buf_off = ublk_pos_to_buf_off(iocb->ki_pos);
> + is_integrity = ublk_pos_is_integrity(iocb->ki_pos);
UBLKSRV_IO_INTEGRITY_FLAG can be set for device without UBLK_F_INTEGRITY,
so UBLK_F_INTEGRITY need to be checked in case of `is_integrity`.
>
> if (q_id >= ub->dev_info.nr_hw_queues)
> return -EINVAL;
>
> ubq = ublk_get_queue(ub, q_id);
> @@ -2683,21 +2718,31 @@ ublk_user_copy(struct kiocb *iocb, struct iov_iter *iter, int dir)
> io = &ubq->ios[tag];
> req = __ublk_check_and_get_req(ub, q_id, tag, io);
> if (!req)
> return -EINVAL;
>
> - if (buf_off > blk_rq_bytes(req)) {
> + if (is_integrity) {
> + struct blk_integrity *bi = &req->q->limits.integrity;
> +
> + data_len = bio_integrity_bytes(bi, blk_rq_sectors(req));
> + } else {
> + data_len = blk_rq_bytes(req);
> + }
> + if (buf_off > data_len) {
> ret = -EINVAL;
> goto out;
> }
>
> if (!ublk_check_ubuf_dir(req, dir)) {
> ret = -EACCES;
> goto out;
> }
>
> - ret = ublk_copy_user_pages(req, buf_off, iter, dir);
> + if (is_integrity)
> + ret = ublk_copy_user_integrity(req, buf_off, iter, dir);
> + else
> + ret = ublk_copy_user_pages(req, buf_off, iter, dir);
>
> out:
> ublk_put_req_ref(io, req);
> return ret;
> }
> @@ -3931,11 +3976,12 @@ static struct miscdevice ublk_misc = {
> static int __init ublk_init(void)
> {
> int ret;
>
> BUILD_BUG_ON((u64)UBLKSRV_IO_BUF_OFFSET +
> - UBLKSRV_IO_BUF_TOTAL_SIZE < UBLKSRV_IO_BUF_OFFSET);
> + UBLKSRV_IO_BUF_TOTAL_SIZE +
> + UBLKSRV_IO_INTEGRITY_FLAG < UBLKSRV_IO_BUF_OFFSET);
Maybe it can be simplified as:
BUILD_BUG_ON(UBLK_INTEGRITY_FLAG_OFF >= 63); /* Must fit in loff_t */
> BUILD_BUG_ON(sizeof(struct ublk_auto_buf_reg) != 8);
>
> init_waitqueue_head(&ublk_idr_wq);
>
> ret = misc_register(&ublk_misc);
> diff --git a/include/uapi/linux/ublk_cmd.h b/include/uapi/linux/ublk_cmd.h
> index c1103ad5925b..3af7e3684834 100644
> --- a/include/uapi/linux/ublk_cmd.h
> +++ b/include/uapi/linux/ublk_cmd.h
> @@ -132,10 +132,14 @@
> #define UBLK_MAX_NR_QUEUES (1U << UBLK_QID_BITS)
>
> #define UBLKSRV_IO_BUF_TOTAL_BITS (UBLK_QID_OFF + UBLK_QID_BITS)
> #define UBLKSRV_IO_BUF_TOTAL_SIZE (1ULL << UBLKSRV_IO_BUF_TOTAL_BITS)
>
> +/* Copy to/from request integrity buffer instead of data buffer */
> +#define UBLK_INTEGRITY_FLAG_OFF UBLKSRV_IO_BUF_TOTAL_BITS
> +#define UBLKSRV_IO_INTEGRITY_FLAG (1ULL << UBLK_INTEGRITY_FLAG_OFF)
> +
> /*
> * ublk server can register data buffers for incoming I/O requests with a sparse
> * io_uring buffer table. The request buffer can then be used as the data buffer
> * for io_uring operations via the fixed buffer index.
> * Note that the ublk server can never directly access the request data memory.
> --
> 2.45.2
>
Thanks,
Ming
next prev parent reply other threads:[~2026-01-06 13:34 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-06 0:57 [PATCH v3 00/19] ublk: add support for integrity data Caleb Sander Mateos
2026-01-06 0:57 ` [PATCH v3 01/19] blk-integrity: take const pointer in blk_integrity_rq() Caleb Sander Mateos
2026-01-06 0:57 ` [PATCH v3 02/19] ublk: move ublk flag check functions earlier Caleb Sander Mateos
2026-01-06 0:57 ` [PATCH v3 03/19] ublk: support UBLK_PARAM_TYPE_INTEGRITY in device creation Caleb Sander Mateos
2026-01-06 13:09 ` Ming Lei
2026-01-06 16:32 ` Caleb Sander Mateos
2026-01-07 0:15 ` Ming Lei
2026-01-07 2:20 ` Caleb Sander Mateos
2026-01-06 0:57 ` [PATCH v3 04/19] ublk: set UBLK_IO_F_INTEGRITY in ublksrv_io_desc Caleb Sander Mateos
2026-01-06 0:57 ` [PATCH v3 05/19] ublk: add ublk_copy_user_bvec() helper Caleb Sander Mateos
2026-01-06 13:14 ` Ming Lei
2026-01-06 0:57 ` [PATCH v3 06/19] ublk: split out ublk_user_copy() helper Caleb Sander Mateos
2026-01-06 0:57 ` [PATCH v3 07/19] ublk: inline ublk_check_and_get_req() into ublk_user_copy() Caleb Sander Mateos
2026-01-06 0:57 ` [PATCH v3 08/19] ublk: move offset check out of __ublk_check_and_get_req() Caleb Sander Mateos
2026-01-06 0:57 ` [PATCH v3 09/19] ublk: implement integrity user copy Caleb Sander Mateos
2026-01-06 13:34 ` Ming Lei [this message]
2026-01-06 18:20 ` Caleb Sander Mateos
2026-01-07 0:28 ` Ming Lei
2026-01-08 1:50 ` Caleb Sander Mateos
2026-01-08 2:11 ` Ming Lei
2026-01-06 13:46 ` Ming Lei
2026-01-06 0:57 ` [PATCH v3 10/19] ublk: support UBLK_F_INTEGRITY Caleb Sander Mateos
2026-01-06 13:36 ` Ming Lei
2026-01-06 0:57 ` [PATCH v3 11/19] ublk: optimize ublk_user_copy() on daemon task Caleb Sander Mateos
2026-01-06 0:57 ` [PATCH v3 12/19] selftests: ublk: display UBLK_F_INTEGRITY support Caleb Sander Mateos
2026-01-06 13:38 ` Ming Lei
2026-01-06 0:57 ` [PATCH v3 13/19] selftests: ublk: add utility to get block device metadata size Caleb Sander Mateos
2026-01-06 13:50 ` Ming Lei
2026-01-06 17:18 ` Caleb Sander Mateos
2026-01-06 0:57 ` [PATCH v3 14/19] selftests: ublk: add kublk support for integrity params Caleb Sander Mateos
2026-01-06 0:57 ` [PATCH v3 15/19] selftests: ublk: implement integrity user copy in kublk Caleb Sander Mateos
2026-01-06 0:57 ` [PATCH v3 16/19] selftests: ublk: support non-O_DIRECT backing files Caleb Sander Mateos
2026-01-06 0:57 ` [PATCH v3 17/19] selftests: ublk: add integrity data support to loop target Caleb Sander Mateos
2026-01-06 0:57 ` [PATCH v3 18/19] selftests: ublk: add integrity params test Caleb Sander Mateos
2026-01-06 0:57 ` [PATCH v3 19/19] selftests: ublk: add end-to-end integrity test Caleb Sander Mateos
2026-01-06 14:10 ` Ming Lei
2026-01-06 17:15 ` Caleb Sander Mateos
2026-01-07 0:21 ` Ming Lei
2026-01-07 1:32 ` Caleb Sander Mateos
2026-01-07 1:49 ` Ming Lei
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aV0PauBTiqWVQ-26@fedora \
--to=ming.lei@redhat.com \
--cc=axboe@kernel.dk \
--cc=csander@purestorage.com \
--cc=linux-block@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=martin.petersen@oracle.com \
--cc=shuah@kernel.org \
--cc=stazhang@purestorage.com \
--cc=ushankar@purestorage.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.