Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

bsg: add io_uring command support to generic layer

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 <yangxiuwei@kylinos.cn>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Link: https://patch.msgid.link/20260317072226.2598233-3-yangxiuwei@kylinos.cn
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Yang Xiuwei and committed by
Jens Axboe
a1e97ce8 7da9261b

+47 -4
+1 -1
block/bsg-lib.c
··· 393 393 394 394 blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT); 395 395 396 - bset->bd = bsg_register_queue(q, dev, name, bsg_transport_sg_io_fn); 396 + bset->bd = bsg_register_queue(q, dev, name, bsg_transport_sg_io_fn, NULL); 397 397 if (IS_ERR(bset->bd)) { 398 398 ret = PTR_ERR(bset->bd); 399 399 goto out_cleanup_queue;
+32 -1
block/bsg.c
··· 12 12 #include <linux/idr.h> 13 13 #include <linux/bsg.h> 14 14 #include <linux/slab.h> 15 + #include <linux/io_uring/cmd.h> 15 16 16 17 #include <scsi/scsi.h> 17 18 #include <scsi/scsi_ioctl.h> ··· 29 28 unsigned int timeout; 30 29 unsigned int reserved_size; 31 30 bsg_sg_io_fn *sg_io_fn; 31 + bsg_uring_cmd_fn *uring_cmd_fn; 32 32 }; 33 33 34 34 static inline struct bsg_device *to_bsg_device(struct inode *inode) ··· 160 158 } 161 159 } 162 160 161 + static int bsg_check_uring_features(unsigned int issue_flags) 162 + { 163 + /* BSG passthrough requires big SQE/CQE support */ 164 + if ((issue_flags & (IO_URING_F_SQE128|IO_URING_F_CQE32)) != 165 + (IO_URING_F_SQE128|IO_URING_F_CQE32)) 166 + return -EOPNOTSUPP; 167 + return 0; 168 + } 169 + 170 + static int bsg_uring_cmd(struct io_uring_cmd *ioucmd, unsigned int issue_flags) 171 + { 172 + struct bsg_device *bd = to_bsg_device(file_inode(ioucmd->file)); 173 + bool open_for_write = ioucmd->file->f_mode & FMODE_WRITE; 174 + struct request_queue *q = bd->queue; 175 + int ret; 176 + 177 + ret = bsg_check_uring_features(issue_flags); 178 + if (ret) 179 + return ret; 180 + 181 + if (!bd->uring_cmd_fn) 182 + return -EOPNOTSUPP; 183 + 184 + return bd->uring_cmd_fn(q, ioucmd, issue_flags, open_for_write); 185 + } 186 + 163 187 static const struct file_operations bsg_fops = { 164 188 .open = bsg_open, 165 189 .release = bsg_release, 166 190 .unlocked_ioctl = bsg_ioctl, 167 191 .compat_ioctl = compat_ptr_ioctl, 192 + .uring_cmd = bsg_uring_cmd, 168 193 .owner = THIS_MODULE, 169 194 .llseek = default_llseek, 170 195 }; ··· 216 187 EXPORT_SYMBOL_GPL(bsg_unregister_queue); 217 188 218 189 struct bsg_device *bsg_register_queue(struct request_queue *q, 219 - struct device *parent, const char *name, bsg_sg_io_fn *sg_io_fn) 190 + struct device *parent, const char *name, bsg_sg_io_fn *sg_io_fn, 191 + bsg_uring_cmd_fn *uring_cmd_fn) 220 192 { 221 193 struct bsg_device *bd; 222 194 int ret; ··· 229 199 bd->reserved_size = INT_MAX; 230 200 bd->queue = q; 231 201 bd->sg_io_fn = sg_io_fn; 202 + bd->uring_cmd_fn = uring_cmd_fn; 232 203 233 204 ret = ida_alloc_max(&bsg_minor_ida, BSG_MAX_DEVS - 1, GFP_KERNEL); 234 205 if (ret < 0) {
+9 -1
drivers/scsi/scsi_bsg.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 #include <linux/bsg.h> 3 + #include <linux/io_uring/cmd.h> 3 4 #include <scsi/scsi.h> 4 5 #include <scsi/scsi_ioctl.h> 5 6 #include <scsi/scsi_cmnd.h> ··· 9 8 #include "scsi_priv.h" 10 9 11 10 #define uptr64(val) ((void __user *)(uintptr_t)(val)) 11 + 12 + static int scsi_bsg_uring_cmd(struct request_queue *q, struct io_uring_cmd *ioucmd, 13 + unsigned int issue_flags, bool open_for_write) 14 + { 15 + return -EOPNOTSUPP; 16 + } 12 17 13 18 static int scsi_bsg_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr, 14 19 bool open_for_write, unsigned int timeout) ··· 106 99 struct bsg_device *scsi_bsg_register_queue(struct scsi_device *sdev) 107 100 { 108 101 return bsg_register_queue(sdev->request_queue, &sdev->sdev_gendev, 109 - dev_name(&sdev->sdev_gendev), scsi_bsg_sg_io_fn); 102 + dev_name(&sdev->sdev_gendev), scsi_bsg_sg_io_fn, 103 + scsi_bsg_uring_cmd); 110 104 }
+5 -1
include/linux/bsg.h
··· 7 7 struct bsg_device; 8 8 struct device; 9 9 struct request_queue; 10 + struct io_uring_cmd; 10 11 11 12 typedef int (bsg_sg_io_fn)(struct request_queue *, struct sg_io_v4 *hdr, 12 13 bool open_for_write, unsigned int timeout); 13 14 15 + typedef int (bsg_uring_cmd_fn)(struct request_queue *q, struct io_uring_cmd *ioucmd, 16 + unsigned int issue_flags, bool open_for_write); 17 + 14 18 struct bsg_device *bsg_register_queue(struct request_queue *q, 15 19 struct device *parent, const char *name, 16 - bsg_sg_io_fn *sg_io_fn); 20 + bsg_sg_io_fn *sg_io_fn, bsg_uring_cmd_fn *uring_cmd_fn); 17 21 void bsg_unregister_queue(struct bsg_device *bcd); 18 22 19 23 #endif /* _LINUX_BSG_H */