diff options
| author | Ming Lei <ming.lei@redhat.com> | 2025-05-20 12:54:34 +0800 |
|---|---|---|
| committer | Jens Axboe <axboe@kernel.dk> | 2025-05-20 10:24:45 -0600 |
| commit | 53f427e7944b4f288866cc4a69835086e0958c6a (patch) | |
| tree | 636765f12a35e020e5a49be736f4c4c3771af26e /drivers/block | |
| parent | 99c1e4eb6a3fbbec27c7c70e5fce15cdc1422893 (diff) | |
ublk: support UBLK_AUTO_BUF_REG_FALLBACK
For UBLK_F_AUTO_BUF_REG, buffer is registered to uring_cmd context
automatically with the provided buffer index. User may provide one wrong
buffer index, or the specified buffer is registered by application already.
Add UBLK_AUTO_BUF_REG_FALLBACK for supporting to auto buffer registering
fallback by completing the uring_cmd and telling ublk server the
register failure via UBLK_AUTO_BUF_REG_FALLBACK, then ublk server still
can register the buffer from userspace.
So we can provide reliable way for supporting auto buffer register.
Signed-off-by: Ming Lei <ming.lei@redhat.com>
Link: https://lore.kernel.org/r/20250520045455.515691-5-ming.lei@redhat.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block')
| -rw-r--r-- | drivers/block/ublk_drv.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index 1aabc655652b..2474788ef263 100644 --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -1182,6 +1182,16 @@ static inline void __ublk_abort_rq(struct ublk_queue *ubq, blk_mq_end_request(rq, BLK_STS_IOERR); } +static void ublk_auto_buf_reg_fallback(struct request *req, struct ublk_io *io) +{ + const struct ublk_queue *ubq = req->mq_hctx->driver_data; + struct ublksrv_io_desc *iod = ublk_get_iod(ubq, req->tag); + struct ublk_rq_data *data = blk_mq_rq_to_pdu(req); + + iod->op_flags |= UBLK_IO_F_NEED_REG_BUF; + refcount_set(&data->ref, 1); +} + static bool ublk_auto_buf_reg(struct request *req, struct ublk_io *io, unsigned int issue_flags) { @@ -1192,6 +1202,10 @@ static bool ublk_auto_buf_reg(struct request *req, struct ublk_io *io, ret = io_buffer_register_bvec(io->cmd, req, ublk_io_release, pdu->buf.index, issue_flags); if (ret) { + if (pdu->buf.flags & UBLK_AUTO_BUF_REG_FALLBACK) { + ublk_auto_buf_reg_fallback(req, io); + return true; + } blk_mq_end_request(req, BLK_STS_IOERR); return false; } @@ -1971,6 +1985,8 @@ static inline int ublk_set_auto_buf_reg(struct io_uring_cmd *cmd) if (pdu->buf.reserved0 || pdu->buf.reserved1) return -EINVAL; + if (pdu->buf.flags & ~UBLK_AUTO_BUF_REG_F_MASK) + return -EINVAL; return 0; } |
