mirror of
https://github.com/openharmony/third_party_liburing.git
synced 2026-07-21 07:05:34 -04:00
add multishot recvmsg API
This adds a new API to do multishot recvmsg. This is more complicated than multishot recv as it requires handling a well known data layout copied by the kernel. Signed-off-by: Dylan Yudaken <dylany@fb.com> Link: https://lore.kernel.org/r/20220714115428.1569612-2-dylany@fb.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
committed by
Jens Axboe
parent
3552b72812
commit
df4f819eaf
@@ -419,6 +419,13 @@ static inline void io_uring_prep_recvmsg(struct io_uring_sqe *sqe, int fd,
|
||||
sqe->msg_flags = flags;
|
||||
}
|
||||
|
||||
static inline void io_uring_prep_recvmsg_multishot(struct io_uring_sqe *sqe, int fd,
|
||||
struct msghdr *msg, unsigned flags)
|
||||
{
|
||||
io_uring_prep_recvmsg(sqe, fd, msg, flags);
|
||||
sqe->ioprio |= IORING_RECV_MULTISHOT;
|
||||
}
|
||||
|
||||
static inline void io_uring_prep_sendmsg(struct io_uring_sqe *sqe, int fd,
|
||||
const struct msghdr *msg,
|
||||
unsigned flags)
|
||||
@@ -685,6 +692,65 @@ static inline void io_uring_prep_recv_multishot(struct io_uring_sqe *sqe,
|
||||
sqe->ioprio |= IORING_RECV_MULTISHOT;
|
||||
}
|
||||
|
||||
static inline struct io_uring_recvmsg_out *io_uring_recvmsg_validate(
|
||||
void *buf, int buf_len, struct msghdr *m)
|
||||
{
|
||||
size_t header = m->msg_controllen + m->msg_namelen + sizeof(struct io_uring_recvmsg_out);
|
||||
|
||||
if (buf_len < header)
|
||||
return NULL;
|
||||
return (struct io_uring_recvmsg_out *)buf;
|
||||
}
|
||||
|
||||
static inline void *io_uring_recvmsg_name(struct io_uring_recvmsg_out *o)
|
||||
{
|
||||
return (void *)&o[1];
|
||||
}
|
||||
|
||||
static inline struct cmsghdr *io_uring_recvmsg_cmsg_firsthdr(struct io_uring_recvmsg_out *o,
|
||||
struct msghdr *m)
|
||||
{
|
||||
if (o->controllen < sizeof(struct cmsghdr))
|
||||
return NULL;
|
||||
return (struct cmsghdr *)((unsigned char *)io_uring_recvmsg_name(o) + m->msg_namelen);
|
||||
}
|
||||
|
||||
static inline void *io_uring_recvmsg_payload(struct io_uring_recvmsg_out *o,
|
||||
struct msghdr *m)
|
||||
{
|
||||
return (void *)((unsigned char *)io_uring_recvmsg_name(o) +
|
||||
m->msg_namelen + m->msg_controllen);
|
||||
}
|
||||
|
||||
static inline size_t io_uring_recvmsg_payload_length(struct io_uring_recvmsg_out *o,
|
||||
int buf_length,
|
||||
struct msghdr *m)
|
||||
{
|
||||
unsigned long payload_start = (unsigned long)io_uring_recvmsg_payload(o, m);
|
||||
unsigned long payload_end = (unsigned long)o + buf_length;
|
||||
|
||||
return payload_end - payload_start;
|
||||
}
|
||||
|
||||
static inline struct cmsghdr *io_uring_recvmsg_cmsg_nexthdr(struct io_uring_recvmsg_out *o,
|
||||
struct msghdr *m,
|
||||
struct cmsghdr *cmsg)
|
||||
{
|
||||
unsigned char *end;
|
||||
|
||||
if (cmsg->cmsg_len < sizeof(struct cmsghdr))
|
||||
return NULL;
|
||||
end = (unsigned char *)io_uring_recvmsg_payload(o, m);
|
||||
cmsg = (struct cmsghdr *)((unsigned char *)cmsg + CMSG_ALIGN(cmsg->cmsg_len));
|
||||
|
||||
if ((unsigned char *)(cmsg + 1) > end)
|
||||
return NULL;
|
||||
if (((unsigned char *)cmsg) + CMSG_ALIGN(cmsg->cmsg_len) > end)
|
||||
return NULL;
|
||||
|
||||
return cmsg;
|
||||
}
|
||||
|
||||
static inline void io_uring_prep_openat2(struct io_uring_sqe *sqe, int dfd,
|
||||
const char *path, struct open_how *how)
|
||||
{
|
||||
|
||||
@@ -573,6 +573,13 @@ struct io_uring_file_index_range {
|
||||
__u64 resv;
|
||||
};
|
||||
|
||||
struct io_uring_recvmsg_out {
|
||||
__u32 namelen;
|
||||
__u32 controllen;
|
||||
__u32 payloadlen;
|
||||
__u32 flags;
|
||||
};
|
||||
|
||||
/*
|
||||
* accept flags stored in sqe->ioprio
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user