mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
io_uring/msg_ring: add support for sending a sync message
Normally MSG_RING requires both a source and a destination ring. But some users don't always have a ring avilable to send a message from, yet they still need to notify a target ring. Add support for using io_uring_register(2) without having a source ring, using a file descriptor of -1 for that. Internally those are called blind registration opcodes. Implement IORING_REGISTER_SEND_MSG_RING as a blind opcode, which simply takes an sqe that the application can put on the stack and use the normal liburing helpers to initialize it. Then the app can call: io_uring_register(-1, IORING_REGISTER_SEND_MSG_RING, &sqe, 1); and get the same behavior in terms of the target, where a CQE is posted with the details given in the sqe. For now this takes a single sqe pointer argument, and hence arg must be set to that, and nr_args must be 1. Could easily be extended to take an array of sqes, but for now let's keep it simple. Link: https://lore.kernel.org/r/20240924115932.116167-3-axboe@kernel.dk Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
@@ -331,6 +331,35 @@ done:
|
||||
return IOU_OK;
|
||||
}
|
||||
|
||||
int io_uring_sync_msg_ring(struct io_uring_sqe *sqe)
|
||||
{
|
||||
struct io_msg io_msg = { };
|
||||
struct fd f;
|
||||
int ret;
|
||||
|
||||
ret = __io_msg_ring_prep(&io_msg, sqe);
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Only data sending supported, not IORING_MSG_SEND_FD as that one
|
||||
* doesn't make sense without a source ring to send files from.
|
||||
*/
|
||||
if (io_msg.cmd != IORING_MSG_DATA)
|
||||
return -EINVAL;
|
||||
|
||||
ret = -EBADF;
|
||||
f = fdget(sqe->fd);
|
||||
if (fd_file(f)) {
|
||||
ret = -EBADFD;
|
||||
if (io_is_uring_fops(fd_file(f)))
|
||||
ret = __io_msg_ring_data(fd_file(f)->private_data,
|
||||
&io_msg, IO_URING_F_UNLOCKED);
|
||||
fdput(f);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void io_msg_cache_free(const void *entry)
|
||||
{
|
||||
struct io_kiocb *req = (struct io_kiocb *) entry;
|
||||
|
||||
Reference in New Issue
Block a user