git: e30621d58fa1 - main - mqueue: Introduce kern_kmq_timedreceive & kern_kmq_timedsend

From: Warner Losh <imp_at_FreeBSD.org>
Date: Thu, 23 May 2024 19:42:14 UTC
The branch main has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=e30621d58fa10d82f3d4a89bb6b5572e2517b024

commit e30621d58fa10d82f3d4a89bb6b5572e2517b024
Author:     Ricardo Branco <rbranco@suse.de>
AuthorDate: 2024-05-18 15:19:39 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2024-05-23 19:40:46 +0000

    mqueue: Introduce kern_kmq_timedreceive & kern_kmq_timedsend
    
    Reviewed by: imp, kib
    Pull Request: https://github.com/freebsd/freebsd-src/pull/1248
---
 sys/kern/uipc_mqueue.c | 106 ++++++++++++++++++++++++-------------------------
 sys/sys/mqueue.h       |   6 ---
 sys/sys/syscallsubr.h  |  10 +++++
 3 files changed, 63 insertions(+), 59 deletions(-)

diff --git a/sys/kern/uipc_mqueue.c b/sys/kern/uipc_mqueue.c
index b48abf8788f6..c0948d40c47b 100644
--- a/sys/kern/uipc_mqueue.c
+++ b/sys/kern/uipc_mqueue.c
@@ -2275,58 +2275,77 @@ sys_kmq_setattr(struct thread *td, struct kmq_setattr_args *uap)
 }
 
 int
-sys_kmq_timedreceive(struct thread *td, struct kmq_timedreceive_args *uap)
+kern_kmq_timedreceive(struct thread *td, int mqd, char *msg_ptr,
+	size_t msg_len, unsigned int *msg_prio, const struct timespec *abs_timeout)
 {
 	struct mqueue *mq;
 	struct file *fp;
+	int error, waitok;
+
+	AUDIT_ARG_FD(mqd);
+	error = getmq_read(td, mqd, &fp, NULL, &mq);
+	if (error != 0)
+		return (error);
+	waitok = (fp->f_flag & O_NONBLOCK) == 0;
+	error = mqueue_receive(mq, msg_ptr, msg_len, msg_prio, waitok,
+	    abs_timeout);
+	fdrop(fp, td);
+	return (error);
+}
+
+int
+sys_kmq_timedreceive(struct thread *td, struct kmq_timedreceive_args *uap)
+{
 	struct timespec *abs_timeout, ets;
 	int error;
-	int waitok;
 
-	AUDIT_ARG_FD(uap->mqd);
-	error = getmq_read(td, uap->mqd, &fp, NULL, &mq);
-	if (error)
-		return (error);
 	if (uap->abs_timeout != NULL) {
 		error = copyin(uap->abs_timeout, &ets, sizeof(ets));
 		if (error != 0)
-			goto out;
+			return (error);
 		abs_timeout = &ets;
 	} else
 		abs_timeout = NULL;
-	waitok = !(fp->f_flag & O_NONBLOCK);
-	error = mqueue_receive(mq, uap->msg_ptr, uap->msg_len,
-		uap->msg_prio, waitok, abs_timeout);
-out:
-	fdrop(fp, td);
-	return (error);
+
+	return (kern_kmq_timedreceive(td, uap->mqd, uap->msg_ptr, uap->msg_len,
+		uap->msg_prio, abs_timeout));
 }
 
 int
-sys_kmq_timedsend(struct thread *td, struct kmq_timedsend_args *uap)
+kern_kmq_timedsend(struct thread *td, int mqd, const char *msg_ptr,
+	size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout)
 {
 	struct mqueue *mq;
 	struct file *fp;
-	struct timespec *abs_timeout, ets;
 	int error, waitok;
 
-	AUDIT_ARG_FD(uap->mqd);
-	error = getmq_write(td, uap->mqd, &fp, NULL, &mq);
-	if (error)
+	AUDIT_ARG_FD(mqd);
+	error = getmq_write(td, mqd, &fp, NULL, &mq);
+	if (error != 0)
 		return (error);
+	waitok = (fp->f_flag & O_NONBLOCK) == 0;
+	error = mqueue_send(mq, msg_ptr, msg_len, msg_prio, waitok,
+		abs_timeout);
+	fdrop(fp, td);
+	return (error);
+}
+
+int
+sys_kmq_timedsend(struct thread *td, struct kmq_timedsend_args *uap)
+{
+	struct timespec *abs_timeout, ets;
+	int error;
+
 	if (uap->abs_timeout != NULL) {
 		error = copyin(uap->abs_timeout, &ets, sizeof(ets));
 		if (error != 0)
-			goto out;
+			return (error);
 		abs_timeout = &ets;
 	} else
 		abs_timeout = NULL;
-	waitok = !(fp->f_flag & O_NONBLOCK);
-	error = mqueue_send(mq, uap->msg_ptr, uap->msg_len,
-		uap->msg_prio, waitok, abs_timeout);
-out:
-	fdrop(fp, td);
-	return (error);
+
+	return (kern_kmq_timedsend(td, uap->mqd, uap->msg_ptr, uap->msg_len,
+		uap->msg_prio, abs_timeout));
 }
 
 int
@@ -2801,63 +2820,44 @@ int
 freebsd32_kmq_timedsend(struct thread *td,
     struct freebsd32_kmq_timedsend_args *uap)
 {
-	struct mqueue *mq;
-	struct file *fp;
 	struct timespec32 ets32;
 	struct timespec *abs_timeout, ets;
 	int error;
-	int waitok;
 
-	AUDIT_ARG_FD(uap->mqd);
-	error = getmq_write(td, uap->mqd, &fp, NULL, &mq);
-	if (error)
-		return (error);
 	if (uap->abs_timeout != NULL) {
 		error = copyin(uap->abs_timeout, &ets32, sizeof(ets32));
 		if (error != 0)
-			goto out;
+			return (error);
 		CP(ets32, ets, tv_sec);
 		CP(ets32, ets, tv_nsec);
 		abs_timeout = &ets;
 	} else
 		abs_timeout = NULL;
-	waitok = !(fp->f_flag & O_NONBLOCK);
-	error = mqueue_send(mq, uap->msg_ptr, uap->msg_len,
-	    uap->msg_prio, waitok, abs_timeout);
-out:
-	fdrop(fp, td);
-	return (error);
+
+	return (kern_kmq_timedsend(td, uap->mqd, uap->msg_ptr, uap->msg_len,
+		uap->msg_prio, abs_timeout));
 }
 
 int
 freebsd32_kmq_timedreceive(struct thread *td,
     struct freebsd32_kmq_timedreceive_args *uap)
 {
-	struct mqueue *mq;
-	struct file *fp;
 	struct timespec32 ets32;
 	struct timespec *abs_timeout, ets;
-	int error, waitok;
+	int error;
 
-	AUDIT_ARG_FD(uap->mqd);
-	error = getmq_read(td, uap->mqd, &fp, NULL, &mq);
-	if (error)
-		return (error);
 	if (uap->abs_timeout != NULL) {
 		error = copyin(uap->abs_timeout, &ets32, sizeof(ets32));
 		if (error != 0)
-			goto out;
+			return (error);
 		CP(ets32, ets, tv_sec);
 		CP(ets32, ets, tv_nsec);
 		abs_timeout = &ets;
 	} else
 		abs_timeout = NULL;
-	waitok = !(fp->f_flag & O_NONBLOCK);
-	error = mqueue_receive(mq, uap->msg_ptr, uap->msg_len,
-	    uap->msg_prio, waitok, abs_timeout);
-out:
-	fdrop(fp, td);
-	return (error);
+
+	return (kern_kmq_timedreceive(td, uap->mqd, uap->msg_ptr, uap->msg_len,
+		uap->msg_prio, abs_timeout));
 }
 
 int
diff --git a/sys/sys/mqueue.h b/sys/sys/mqueue.h
index 78f34c197c7e..50f6681ce218 100644
--- a/sys/sys/mqueue.h
+++ b/sys/sys/mqueue.h
@@ -38,14 +38,8 @@ struct mq_attr {
 };
 
 #ifdef _KERNEL
-struct sigevent;
 struct thread;
 struct file;
 extern void	(*mq_fdclose)(struct thread *td, int fd, struct file *fp);
-int	kern_kmq_notify(struct thread *, int, struct sigevent *);
-int	kern_kmq_open(struct thread *, const char *, int, mode_t,
-		const struct mq_attr *);
-int	kern_kmq_setattr(struct thread *, int, const struct mq_attr *,
-		struct mq_attr *);
 #endif
 #endif
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
index 6652619287ad..8ac3f55596e6 100644
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -49,6 +49,7 @@ struct kevent_copyops;
 struct kld_file_stat;
 struct ksiginfo;
 struct mbuf;
+struct mq_attr;
 struct msghdr;
 struct msqid_ds;
 struct pollfd;
@@ -385,6 +386,15 @@ int	kern_writev(struct thread *td, int fd, struct uio *auio);
 int	kern_socketpair(struct thread *td, int domain, int type, int protocol,
 	    int *rsv);
 int	kern_unmount(struct thread *td, const char *path, int flags);
+int	kern_kmq_notify(struct thread *, int, struct sigevent *);
+int	kern_kmq_open(struct thread *, const char *, int, mode_t,
+		const struct mq_attr *);
+int	kern_kmq_setattr(struct thread *, int, const struct mq_attr *,
+		struct mq_attr *);
+int	kern_kmq_timedreceive(struct thread *, int, char *,
+		size_t, unsigned int *, const struct timespec *);
+int	kern_kmq_timedsend(struct thread *td, int, const char *,
+		size_t, unsigned int, const struct timespec *);
 
 /* flags for kern_sigaction */
 #define	KSA_OSIGSET	0x0001	/* uses osigact_t */