From nobody Thu Apr 9 23:26:36 2026 Received: from m16.mail.163.com (m16.mail.163.com [117.135.210.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4C79323EAAB; Thu, 5 Mar 2026 01:29:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=117.135.210.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772674191; cv=none; b=NrfZG9IY77Lj2EyrbyBhBdgkse9Q/Ps0YIV7R6tNT246tA/rPPlvdxCvGQn/gSs4WCAa+rqjeZ36VKjPkPjnt7wsAN2pAM8CrQRXT2yc/if63AHkrVwiEzPlO5LXyDBLZrNNzBbkHGzYgvtboSbXFy1C/iD5rlxvjyqRadR0DiM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772674191; c=relaxed/simple; bh=4nhnK/caT+5lVyHZhvTwEdE//w0eYhU8dWxnE45mTEY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=PPQd0nY5t8+BmnFsevukEWwaYxCiza7QiGB61Bykv8g6MoBAnFKOgd46fNTbsH3knFOeQihH5WakNT+84YTkSJdypY+V97DM0w9i1Tb6WSdagaGA7yJqCZk/JPI9/8b3rSS9AcvrzCzZ3Nwq3+Nf3trQHvjAJmke4uMzns8lLmY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=HAzPNtBp; arc=none smtp.client-ip=117.135.210.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="HAzPNtBp" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=1Y BNzXxLpA3HY1a54/AnAdwwruJdKBfVzW9rKDno53k=; b=HAzPNtBpghsoi0cjHd clSRJTLKmnMAHejPqdkV3jlsx+IuqRuJNd/NF+lFzVpeZsDL0eCUeAiIVzrfzq8Z IpUAuQRUWW9YgHvkpIFlzm4p8plQEX6LSXQBI48tgMAjTIc/gM+i2tkZzBVpeDU8 YG1ovE4kQpWeOD3keajdMReUI= Received: from localhost.localdomain (unknown []) by gzga-smtp-mtada-g1-2 (Coremail) with SMTP id _____wBXMO9b3Khp6W63OA--.24976S3; Thu, 05 Mar 2026 09:29:05 +0800 (CST) From: Yang Xiuwei To: fujita.tomonori@lab.ntt.co.jp, axboe@kernel.dk, James.Bottomley@HansenPartnership.com, martin.petersen@oracle.com Cc: bvanassche@acm.org, linux-scsi@vger.kernel.org, linux-block@vger.kernel.org, io-uring@vger.kernel.org, linux-kernel@vger.kernel.org, Yang Xiuwei Subject: [PATCH v6 1/3] bsg: add bsg_uring_cmd uapi structure Date: Thu, 5 Mar 2026 09:28:55 +0800 Message-Id: <20260305012857.2136525-2-yangxiuwei@kylinos.cn> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20260305012857.2136525-1-yangxiuwei@kylinos.cn> References: <20260304080313.675768-1-yangxiuwei@kylinos.cn> <20260305012857.2136525-1-yangxiuwei@kylinos.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wBXMO9b3Khp6W63OA--.24976S3 X-Coremail-Antispam: 1Uf129KBjvJXoW7CF1xJF4fWFWfXF4xJFWUurg_yoW8XrWfpF s8Kw4fXFWUWw4I9r43Wa4jka4YqF40y3W7G3y7Zrn093Z0qFy8Ar4UCF4UK3Wjq39rAry0 9r17trZ8Cw4jvw7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07jUzV8UUUUU= Sender: yangxiuwei2025@163.com X-CM-SenderInfo: p1dqw55lxzvxisqskqqrwthudrp/xtbC6QHTZGmo3GGYEwAA3o Content-Type: text/plain; charset="utf-8" Add the bsg_uring_cmd structure to the BSG UAPI header to support io_uring-based SCSI passthrough operations via IORING_OP_URING_CMD. Signed-off-by: Yang Xiuwei --- include/uapi/linux/bsg.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/include/uapi/linux/bsg.h b/include/uapi/linux/bsg.h index cd6302def5ed..983c6e2b6871 100644 --- a/include/uapi/linux/bsg.h +++ b/include/uapi/linux/bsg.h @@ -63,5 +63,26 @@ struct sg_io_v4 { __u32 padding; }; =20 +struct bsg_uring_cmd { + __u64 request; /* [i], [*i] command descriptor address */ + __u32 request_len; /* [i] command descriptor length in bytes */ + __u32 protocol; /* [i] protocol type (BSG_PROTOCOL_*) */ + __u32 subprotocol; /* [i] subprotocol type (BSG_SUB_PROTOCOL_*) */ + __u32 max_response_len; /* [i] response buffer size in bytes */ + + __u64 response; /* [i], [*o] response data address */ + __u64 dout_xferp; /* [i], [*i] */ + __u32 dout_xfer_len; /* [i] bytes to be transferred to device */ + __u32 dout_iovec_count; /* [i] 0 -> "flat" dout transfer else + * dout_xferp points to array of iovec + */ + __u64 din_xferp; /* [i], [*o] */ + __u32 din_xfer_len; /* [i] bytes to be transferred from device */ + __u32 din_iovec_count; /* [i] 0 -> "flat" din transfer */ + + __u32 timeout_ms; /* [i] timeout in milliseconds */ + __u32 flags; /* [i] bit mask */ + __u8 reserved[8]; /* reserved for future extension */ +}; =20 #endif /* _UAPIBSG_H */ --=20 2.25.1 From nobody Thu Apr 9 23:26:36 2026 Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CD9942459CF; Thu, 5 Mar 2026 01:29:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.31.2 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772674191; cv=none; b=igIqthGWosqQ1rpY3cGxa2XbVB+MpjAPAwGCm4uyOeb4wUJNA1OmPT3fyur15EC5o+OjnG2PEgcj8vtwp2yDSkC4RK5YIryPfxO9KhMrrvhRxpTPLKlgiZI1EI+lzDyqVSBs0WlO2ZGLKUt+17NQ1Hs5RJXykTjSE5/q3n6F9Uw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772674191; c=relaxed/simple; bh=w5vyPlIfOAMnbGPPUCuguXE4vYVsW8ud2BcFogYfJXU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=GPkm+v0aCTMsfBrSEsEFapVQZUUAesZQLvF59tI73xd/KevxmiXHMc7cjlUWgqtlMk2EvDRsY6tlRYJDjuyebjP+iNmnKvGMgO93/7XIVoQtPHkPVlAbeBlNl6xKjAOpPN+ReFc1ASEnYZ04JY6BUUJVE+I+rxccujw2tGsiDMw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=mE2cQ9/0; arc=none smtp.client-ip=220.197.31.2 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="mE2cQ9/0" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=js Rq3aKCns44BgXCd6DPRxFhJT1owmPQTzZLhub7kdU=; b=mE2cQ9/0BeJv+jVK74 +CtlKtjliO5U7PFPlmaQ7JpBLFso8Ep7GxxkZx15pzT9mXYIIBtMtLdAZRuDsiQ2 ny+Zq/a/B0n2rrCqxcpFCnw2WcpPHM5nyJ8BuY7rUDVWv81QInmQ5rUInlp73AQP 5FozqOgdBPah9B2Kv1q3Zi7h4= Received: from localhost.localdomain (unknown []) by gzga-smtp-mtada-g1-2 (Coremail) with SMTP id _____wBXMO9b3Khp6W63OA--.24976S4; Thu, 05 Mar 2026 09:29:06 +0800 (CST) From: Yang Xiuwei To: fujita.tomonori@lab.ntt.co.jp, axboe@kernel.dk, James.Bottomley@HansenPartnership.com, martin.petersen@oracle.com Cc: bvanassche@acm.org, linux-scsi@vger.kernel.org, linux-block@vger.kernel.org, io-uring@vger.kernel.org, linux-kernel@vger.kernel.org, Yang Xiuwei Subject: [PATCH v6 2/3] bsg: add io_uring command support to generic layer Date: Thu, 5 Mar 2026 09:28:56 +0800 Message-Id: <20260305012857.2136525-3-yangxiuwei@kylinos.cn> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20260305012857.2136525-1-yangxiuwei@kylinos.cn> References: <20260304080313.675768-1-yangxiuwei@kylinos.cn> <20260305012857.2136525-1-yangxiuwei@kylinos.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wBXMO9b3Khp6W63OA--.24976S4 X-Coremail-Antispam: 1Uf129KBjvJXoWxKFWrtw4rJr4kuFyftw17trb_yoW7CryrpF WrXa15JrWFgr4xua98JFs8Jr9Iqw48K3yxJFyI9345KrnFyr9Yqr1kuFy0qFWrJrWkCayY qanYqrWDCr1UAw7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07j47KxUUUUU= Sender: yangxiuwei2025@163.com X-CM-SenderInfo: p1dqw55lxzvxisqskqqrwthudrp/xtbCwgLTZGmo3GLv0wAA30 Content-Type: text/plain; charset="utf-8" Add an io_uring command handler to the generic BSG layer. The new .uring_cmd file operation validates io_uring features and delegates handling to a per-queue bsg_uring_cmd_fn callback. Extend bsg_register_queue() so transport drivers can register both sg_io and io_uring command handlers. Signed-off-by: Yang Xiuwei --- block/bsg-lib.c | 2 +- block/bsg.c | 32 +++++++++++++++++++++++++++++++- drivers/scsi/scsi_bsg.c | 10 +++++++++- include/linux/bsg.h | 6 +++++- 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/block/bsg-lib.c b/block/bsg-lib.c index 20cd0ef3c394..fdb4b290ca68 100644 --- a/block/bsg-lib.c +++ b/block/bsg-lib.c @@ -393,7 +393,7 @@ struct request_queue *bsg_setup_queue(struct device *de= v, const char *name, =20 blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT); =20 - bset->bd =3D bsg_register_queue(q, dev, name, bsg_transport_sg_io_fn); + bset->bd =3D bsg_register_queue(q, dev, name, bsg_transport_sg_io_fn, NUL= L); if (IS_ERR(bset->bd)) { ret =3D PTR_ERR(bset->bd); goto out_cleanup_queue; diff --git a/block/bsg.c b/block/bsg.c index e0af6206ed28..8f23296a7033 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -12,6 +12,7 @@ #include #include #include +#include =20 #include #include @@ -28,6 +29,7 @@ struct bsg_device { unsigned int timeout; unsigned int reserved_size; bsg_sg_io_fn *sg_io_fn; + bsg_uring_cmd_fn *uring_cmd_fn; }; =20 static inline struct bsg_device *to_bsg_device(struct inode *inode) @@ -158,11 +160,37 @@ static long bsg_ioctl(struct file *file, unsigned int= cmd, unsigned long arg) } } =20 +static int bsg_check_uring_features(unsigned int issue_flags) +{ + /* BSG passthrough requires big SQE/CQE support */ + if ((issue_flags & (IO_URING_F_SQE128|IO_URING_F_CQE32)) !=3D + (IO_URING_F_SQE128|IO_URING_F_CQE32)) + return -EOPNOTSUPP; + return 0; +} + +static int bsg_uring_cmd(struct io_uring_cmd *ioucmd, unsigned int issue_f= lags) +{ + struct bsg_device *bd =3D to_bsg_device(file_inode(ioucmd->file)); + struct request_queue *q =3D bd->queue; + bool open_for_write =3D ioucmd->file->f_mode & FMODE_WRITE; + int ret; + + ret =3D bsg_check_uring_features(issue_flags); + if (ret) + return ret; + + if (bd->uring_cmd_fn) + return bd->uring_cmd_fn(q, ioucmd, issue_flags, open_for_write); + return -EOPNOTSUPP; +} + static const struct file_operations bsg_fops =3D { .open =3D bsg_open, .release =3D bsg_release, .unlocked_ioctl =3D bsg_ioctl, .compat_ioctl =3D compat_ptr_ioctl, + .uring_cmd =3D bsg_uring_cmd, .owner =3D THIS_MODULE, .llseek =3D default_llseek, }; @@ -187,7 +215,8 @@ void bsg_unregister_queue(struct bsg_device *bd) EXPORT_SYMBOL_GPL(bsg_unregister_queue); =20 struct bsg_device *bsg_register_queue(struct request_queue *q, - struct device *parent, const char *name, bsg_sg_io_fn *sg_io_fn) + struct device *parent, const char *name, bsg_sg_io_fn *sg_io_fn, + bsg_uring_cmd_fn *uring_cmd_fn) { struct bsg_device *bd; int ret; @@ -199,6 +228,7 @@ struct bsg_device *bsg_register_queue(struct request_qu= eue *q, bd->reserved_size =3D INT_MAX; bd->queue =3D q; bd->sg_io_fn =3D sg_io_fn; + bd->uring_cmd_fn =3D uring_cmd_fn; =20 ret =3D ida_alloc_max(&bsg_minor_ida, BSG_MAX_DEVS - 1, GFP_KERNEL); if (ret < 0) { diff --git a/drivers/scsi/scsi_bsg.c b/drivers/scsi/scsi_bsg.c index a9a9ec086a7e..4d57e524e141 100644 --- a/drivers/scsi/scsi_bsg.c +++ b/drivers/scsi/scsi_bsg.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include #include #include @@ -9,6 +10,12 @@ =20 #define uptr64(val) ((void __user *)(uintptr_t)(val)) =20 +static int scsi_bsg_uring_cmd(struct request_queue *q, struct io_uring_cmd= *ioucmd, + unsigned int issue_flags, bool open_for_write) +{ + return -EOPNOTSUPP; +} + static int scsi_bsg_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr, bool open_for_write, unsigned int timeout) { @@ -99,5 +106,6 @@ static int scsi_bsg_sg_io_fn(struct request_queue *q, st= ruct sg_io_v4 *hdr, struct bsg_device *scsi_bsg_register_queue(struct scsi_device *sdev) { return bsg_register_queue(sdev->request_queue, &sdev->sdev_gendev, - dev_name(&sdev->sdev_gendev), scsi_bsg_sg_io_fn); + dev_name(&sdev->sdev_gendev), scsi_bsg_sg_io_fn, + scsi_bsg_uring_cmd); } diff --git a/include/linux/bsg.h b/include/linux/bsg.h index ee2df73edf83..162730bfc2d8 100644 --- a/include/linux/bsg.h +++ b/include/linux/bsg.h @@ -7,13 +7,17 @@ struct bsg_device; struct device; struct request_queue; +struct io_uring_cmd; =20 typedef int (bsg_sg_io_fn)(struct request_queue *, struct sg_io_v4 *hdr, bool open_for_write, unsigned int timeout); =20 +typedef int (bsg_uring_cmd_fn)(struct request_queue *q, struct io_uring_cm= d *ioucmd, + unsigned int issue_flags, bool open_for_write); + struct bsg_device *bsg_register_queue(struct request_queue *q, struct device *parent, const char *name, - bsg_sg_io_fn *sg_io_fn); + bsg_sg_io_fn *sg_io_fn, bsg_uring_cmd_fn *uring_cmd_fn); void bsg_unregister_queue(struct bsg_device *bcd); =20 #endif /* _LINUX_BSG_H */ --=20 2.25.1 From nobody Thu Apr 9 23:26:36 2026 Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0C5A91BBBE5; Thu, 5 Mar 2026 01:30:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.31.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772674211; cv=none; b=b+Un4PtfaS3nDu0cuNVhPv10VUrG/s0Ne1Y9ya2y5nJBTyQiHFAykP8tSrtHAfN/hr5N3kGZq6atEDOx/OQ8YDXt4syT/f7KWT91H7V8mf5MARpuHD80pwZ7MmfJKXAAfLZBBxgUgpXi4jWcnrelZWByYXRhva+6nJIPgmrU0Qk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772674211; c=relaxed/simple; bh=7h7iAgaehaGowJLub2iWzs5bBaTqpodKb57T5p22y/w=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ZaWS2ECl385rIg8QiaNfCFLHIL+Q92SCnrFDb4mYA97daqFqY5ZsGVuFOePQ5lEiHACB63Thew7rraXHHkHvSPmHXvQzqsCukPk8i0X+U73K+rz/VRmJE3dvNcSsk8Fw1MzC7QobahMsh8UEEAiFPEbmXxMQnEMB8A848vEFapY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=Pjzy+3gB; arc=none smtp.client-ip=220.197.31.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="Pjzy+3gB" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=iV IzEj15OBqZg8q5GF/ie6nbLyMrr9zGDb0IgIwmMms=; b=Pjzy+3gBWSsAJ3fzlt izGQ8Stp1cV2XljPUYcGfmgr54zgxc8yDOSit12XtMws2PHqeiXC71ytikoViTz3 FbiU6CFNppXHWj/iwh1PaH3J6LCzH2TzYuq3SxcfDeFwHOqtcQYEfyw43WhT+dXC +eI/f1Hpw4y+ReV9BkY8Pd/N0= Received: from localhost.localdomain (unknown []) by gzga-smtp-mtada-g1-2 (Coremail) with SMTP id _____wBXMO9b3Khp6W63OA--.24976S5; Thu, 05 Mar 2026 09:29:07 +0800 (CST) From: Yang Xiuwei To: fujita.tomonori@lab.ntt.co.jp, axboe@kernel.dk, James.Bottomley@HansenPartnership.com, martin.petersen@oracle.com Cc: bvanassche@acm.org, linux-scsi@vger.kernel.org, linux-block@vger.kernel.org, io-uring@vger.kernel.org, linux-kernel@vger.kernel.org, Yang Xiuwei Subject: [PATCH v6 3/3] scsi: bsg: add io_uring passthrough handler Date: Thu, 5 Mar 2026 09:28:57 +0800 Message-Id: <20260305012857.2136525-4-yangxiuwei@kylinos.cn> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20260305012857.2136525-1-yangxiuwei@kylinos.cn> References: <20260304080313.675768-1-yangxiuwei@kylinos.cn> <20260305012857.2136525-1-yangxiuwei@kylinos.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wBXMO9b3Khp6W63OA--.24976S5 X-Coremail-Antispam: 1Uf129KBjvJXoW3GrWfGrWrXr18urW3Zr13urg_yoW3JF48pF W5tw4YvrW5Wr4I9FZayrZ8CFyYqws5Ca47KFW3uw4fGr1UCr9a93W8KF10qF1fArWkAa47 XF4vqFW5CFyqq37anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07jceOJUUUUU= Sender: yangxiuwei2025@163.com X-CM-SenderInfo: p1dqw55lxzvxisqskqqrwthudrp/xtbC6QPTZGmo3GOYRAAA3- Content-Type: text/plain; charset="utf-8" Implement the SCSI-specific io_uring command handler for BSG using struct bsg_uring_cmd. The handler builds a SCSI request from the io_uring command, maps user buffers (including fixed buffers), and completes asynchronously via a request end_io callback and task_work. Completion returns a 32-bit status and packed residual/sense information via CQE res and res2, and supports IO_URING_F_NONBLOCK. Signed-off-by: Yang Xiuwei --- drivers/scsi/scsi_bsg.c | 199 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 198 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_bsg.c b/drivers/scsi/scsi_bsg.c index 4d57e524e141..5b6ed15b8b19 100644 --- a/drivers/scsi/scsi_bsg.c +++ b/drivers/scsi/scsi_bsg.c @@ -10,10 +10,207 @@ =20 #define uptr64(val) ((void __user *)(uintptr_t)(val)) =20 +/* + * Per-command BSG SCSI PDU stored in io_uring_cmd.pdu[32]. + * Holds temporary state between submission, completion and task_work. + */ +struct scsi_bsg_uring_cmd_pdu { + struct bio *bio; /* mapped user buffer, unmap in task work */ + struct request *req; /* block request, freed in task work */ + u64 response_addr; /* user space response buffer address */ + u32 resid_len; /* residual transfer length */ + /* Protocol-specific status fields using union for extensibility */ + union { + struct { + u8 device_status; /* SCSI device status (low 8 bits of result) */ + u8 driver_status; /* SCSI driver status (DRIVER_SENSE if check) */ + u8 host_status; /* SCSI host status (host_byte of result) */ + u8 sense_len_wr; /* actual sense data length written */ + } scsi; + /* Future protocols can add their own status layouts here */ + }; +}; + +static inline struct scsi_bsg_uring_cmd_pdu *scsi_bsg_uring_cmd_pdu( + struct io_uring_cmd *ioucmd) +{ + return io_uring_cmd_to_pdu(ioucmd, struct scsi_bsg_uring_cmd_pdu); +} + +/* + * Task work callback executed in process context. + * Builds res2 with status information and copies sense data to user space. + * res2 layout (64-bit): + * 0-7: device_status + * 8-15: driver_status + * 16-23: host_status + * 24-31: sense_len_wr + * 32-63: resid_len + */ +static void scsi_bsg_uring_task_cb(struct io_tw_req tw_req, io_tw_token_t = tw) +{ + struct io_uring_cmd *ioucmd =3D io_uring_cmd_from_tw(tw_req); + struct scsi_bsg_uring_cmd_pdu *pdu =3D scsi_bsg_uring_cmd_pdu(ioucmd); + struct scsi_cmnd *scmd; + struct request *rq =3D pdu->req; + int ret =3D 0; + u64 res2; + + scmd =3D blk_mq_rq_to_pdu(rq); + + if (pdu->bio) + blk_rq_unmap_user(pdu->bio); + + /* Build res2 with status information */ + res2 =3D ((u64)pdu->resid_len << 32) | + ((u64)(pdu->scsi.sense_len_wr & 0xff) << 24) | + ((u64)(pdu->scsi.host_status & 0xff) << 16) | + ((u64)(pdu->scsi.driver_status & 0xff) << 8) | + (pdu->scsi.device_status & 0xff); + + if (pdu->scsi.sense_len_wr && pdu->response_addr) { + if (copy_to_user(uptr64(pdu->response_addr), scmd->sense_buffer, + pdu->scsi.sense_len_wr)) + ret =3D -EFAULT; + } + + blk_mq_free_request(rq); + io_uring_cmd_done32(ioucmd, ret, res2, + IO_URING_CMD_TASK_WORK_ISSUE_FLAGS); +} + +static enum rq_end_io_ret scsi_bsg_uring_cmd_done(struct request *req, + blk_status_t status, + const struct io_comp_batch *iocb) +{ + struct io_uring_cmd *ioucmd =3D req->end_io_data; + struct scsi_bsg_uring_cmd_pdu *pdu =3D scsi_bsg_uring_cmd_pdu(ioucmd); + struct scsi_cmnd *scmd =3D blk_mq_rq_to_pdu(req); + + /* Pack SCSI status fields into union */ + pdu->scsi.device_status =3D scmd->result & 0xff; + pdu->scsi.host_status =3D host_byte(scmd->result); + pdu->scsi.driver_status =3D 0; + pdu->scsi.sense_len_wr =3D 0; + + if (scsi_status_is_check_condition(scmd->result)) { + pdu->scsi.driver_status =3D DRIVER_SENSE; + if (pdu->response_addr) + pdu->scsi.sense_len_wr =3D min_t(u8, scmd->sense_len, SCSI_SENSE_BUFFER= SIZE); + } + + pdu->resid_len =3D scmd->resid_len; + + io_uring_cmd_do_in_task_lazy(ioucmd, scsi_bsg_uring_task_cb); + return RQ_END_IO_NONE; +} + +static int scsi_bsg_map_user_buffer(struct request *req, + struct io_uring_cmd *ioucmd, + unsigned int issue_flags, gfp_t gfp_mask) +{ + const struct bsg_uring_cmd *cmd =3D io_uring_sqe128_cmd(ioucmd->sqe, stru= ct bsg_uring_cmd); + struct iov_iter iter; + bool is_write =3D cmd->dout_xfer_len > 0; + u64 buf_addr =3D is_write ? cmd->dout_xferp : cmd->din_xferp; + unsigned long buf_len =3D is_write ? cmd->dout_xfer_len : cmd->din_xfer_l= en; + int ret; + + if (ioucmd->flags & IORING_URING_CMD_FIXED) { + ret =3D io_uring_cmd_import_fixed(buf_addr, buf_len, + is_write ? WRITE : READ, + &iter, ioucmd, issue_flags); + if (ret < 0) + return ret; + ret =3D blk_rq_map_user_iov(req->q, req, NULL, &iter, gfp_mask); + } else { + ret =3D blk_rq_map_user(req->q, req, NULL, uptr64(buf_addr), + buf_len, gfp_mask); + } + + return ret; +} + static int scsi_bsg_uring_cmd(struct request_queue *q, struct io_uring_cmd= *ioucmd, unsigned int issue_flags, bool open_for_write) { - return -EOPNOTSUPP; + struct scsi_bsg_uring_cmd_pdu *pdu =3D scsi_bsg_uring_cmd_pdu(ioucmd); + const struct bsg_uring_cmd *cmd =3D io_uring_sqe128_cmd(ioucmd->sqe, stru= ct bsg_uring_cmd); + struct scsi_cmnd *scmd; + struct request *req; + blk_mq_req_flags_t blk_flags =3D 0; + gfp_t gfp_mask =3D GFP_KERNEL; + int ret =3D 0; + + if (cmd->protocol !=3D BSG_PROTOCOL_SCSI || + cmd->subprotocol !=3D BSG_SUB_PROTOCOL_SCSI_CMD) + return -EINVAL; + + if (!cmd->request || cmd->request_len =3D=3D 0) + return -EINVAL; + + if (cmd->dout_xfer_len && cmd->din_xfer_len) { + pr_warn_once("BIDI support in bsg has been removed.\n"); + return -EOPNOTSUPP; + } + + if (cmd->dout_iovec_count > 0 || cmd->din_iovec_count > 0) + return -EOPNOTSUPP; + + if (issue_flags & IO_URING_F_NONBLOCK) { + blk_flags =3D BLK_MQ_REQ_NOWAIT; + gfp_mask =3D GFP_NOWAIT; + } + + req =3D scsi_alloc_request(q, cmd->dout_xfer_len ? + REQ_OP_DRV_OUT : REQ_OP_DRV_IN, blk_flags); + if (IS_ERR(req)) + return PTR_ERR(req); + + scmd =3D blk_mq_rq_to_pdu(req); + scmd->cmd_len =3D cmd->request_len; + if (scmd->cmd_len > sizeof(scmd->cmnd)) { + ret =3D -EINVAL; + goto out_free_req; + } + scmd->allowed =3D SG_DEFAULT_RETRIES; + + if (copy_from_user(scmd->cmnd, uptr64(cmd->request), cmd->request_len)) { + ret =3D -EFAULT; + goto out_free_req; + } + + if (!scsi_cmd_allowed(scmd->cmnd, open_for_write)) { + ret =3D -EPERM; + goto out_free_req; + } + + pdu->response_addr =3D cmd->response; + scmd->sense_len =3D cmd->max_response_len ? + min(cmd->max_response_len, SCSI_SENSE_BUFFERSIZE) : SCSI_SENSE_BUFFERSIZ= E; + + if (cmd->dout_xfer_len || cmd->din_xfer_len) { + ret =3D scsi_bsg_map_user_buffer(req, ioucmd, issue_flags, gfp_mask); + if (ret) + goto out_free_req; + pdu->bio =3D req->bio; + } else { + pdu->bio =3D NULL; + } + + req->timeout =3D cmd->timeout_ms ? + msecs_to_jiffies(cmd->timeout_ms) : BLK_DEFAULT_SG_TIMEOUT; + + req->end_io =3D scsi_bsg_uring_cmd_done; + req->end_io_data =3D ioucmd; + pdu->req =3D req; + + blk_execute_rq_nowait(req, false); + return -EIOCBQUEUED; + +out_free_req: + blk_mq_free_request(req); + return ret; } =20 static int scsi_bsg_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr, --=20 2.25.1