Add io_uring command handler to the generic BSG layer. This handler validates that SQE128 and CQE32 flags are set (required for the command structure and status information), then delegates to the SCSI-specific handler. Signed-off-by: Yang Xiuwei --- block/bsg.c | 28 ++++++++++++++++++++++++++++ drivers/scsi/scsi_bsg.c | 7 +++++++ include/linux/bsg.h | 4 ++++ 3 files changed, 39 insertions(+) diff --git a/block/bsg.c b/block/bsg.c index 72157a59b788..cdccf86b8673 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -158,11 +159,38 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } } +static int bsg_uring_cmd_checks(unsigned int issue_flags) +{ + /* BSG passthrough requires big SQE/CQE support */ + if ((issue_flags & (IO_URING_F_SQE128|IO_URING_F_CQE32)) != + (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_flags) +{ + struct bsg_device *bd = to_bsg_device(file_inode(ioucmd->file)); + struct request_queue *q = bd->queue; + bool open_for_write = ioucmd->file->f_mode & FMODE_WRITE; + int ret; + + if (!q) + return -EINVAL; + + ret = bsg_uring_cmd_checks(issue_flags); + if (ret) + return ret; + + return scsi_bsg_uring_cmd(q, ioucmd, issue_flags, open_for_write); +} + static const struct file_operations bsg_fops = { .open = bsg_open, .release = bsg_release, .unlocked_ioctl = bsg_ioctl, .compat_ioctl = compat_ptr_ioctl, + .uring_cmd = bsg_uring_cmd, .owner = THIS_MODULE, .llseek = default_llseek, }; diff --git a/drivers/scsi/scsi_bsg.c b/drivers/scsi/scsi_bsg.c index a9a9ec086a7e..4399a25990fc 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 @@ #define uptr64(val) ((void __user *)(uintptr_t)(val)) +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) { diff --git a/include/linux/bsg.h b/include/linux/bsg.h index ee2df73edf83..68ec50b5e97c 100644 --- a/include/linux/bsg.h +++ b/include/linux/bsg.h @@ -7,6 +7,7 @@ struct bsg_device; struct device; struct request_queue; +struct io_uring_cmd; typedef int (bsg_sg_io_fn)(struct request_queue *, struct sg_io_v4 *hdr, bool open_for_write, unsigned int timeout); @@ -16,4 +17,7 @@ struct bsg_device *bsg_register_queue(struct request_queue *q, bsg_sg_io_fn *sg_io_fn); void bsg_unregister_queue(struct bsg_device *bcd); +int scsi_bsg_uring_cmd(struct request_queue *q, struct io_uring_cmd *ioucmd, + unsigned int issue_flags, bool open_for_write); + #endif /* _LINUX_BSG_H */ -- 2.25.1