The branch main has been updated by imp:

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

commit 97add684f5306ebf93be238a0340597ba1898d0e
Author:     Ricardo Branco <rbra...@suse.de>
AuthorDate: 2024-05-17 20:31:49 +0000
Commit:     Warner Losh <i...@freebsd.org>
CommitDate: 2024-05-23 19:40:46 +0000

    linux: Support POSIX message queues
    
    Reviewed by: imp, kib
    Pull Request: https://github.com/freebsd/freebsd-src/pull/1248
---
 sys/amd64/linux/linux_dummy_machdep.c     |   6 --
 sys/amd64/linux32/linux32_dummy_machdep.c |   6 --
 sys/arm64/linux/linux_dummy_machdep.c     |   6 --
 sys/compat/linux/linux_misc.c             | 124 ++++++++++++++++++++++++++++++
 sys/i386/linux/linux_machdep.c            |  61 ---------------
 5 files changed, 124 insertions(+), 79 deletions(-)

diff --git a/sys/amd64/linux/linux_dummy_machdep.c 
b/sys/amd64/linux/linux_dummy_machdep.c
index 759586d9f1fc..53bdb8099578 100644
--- a/sys/amd64/linux/linux_dummy_machdep.c
+++ b/sys/amd64/linux/linux_dummy_machdep.c
@@ -56,12 +56,6 @@ DUMMY(io_destroy);
 DUMMY(io_getevents);
 DUMMY(io_submit);
 DUMMY(io_cancel);
-DUMMY(mq_open);
-DUMMY(mq_unlink);
-DUMMY(mq_timedsend);
-DUMMY(mq_timedreceive);
-DUMMY(mq_notify);
-DUMMY(mq_getsetattr);
 DUMMY(readahead);
 DUMMY(restart_syscall);
 /* Linux 3.15: */
diff --git a/sys/amd64/linux32/linux32_dummy_machdep.c 
b/sys/amd64/linux32/linux32_dummy_machdep.c
index c2206c81c528..1476d39b9c35 100644
--- a/sys/amd64/linux32/linux32_dummy_machdep.c
+++ b/sys/amd64/linux32/linux32_dummy_machdep.c
@@ -55,12 +55,6 @@ DUMMY(olduname);
 DUMMY(uname);
 DUMMY(bdflush);
 DUMMY(ptrace);
-DUMMY(mq_open);
-DUMMY(mq_unlink);
-DUMMY(mq_timedsend);
-DUMMY(mq_timedreceive);
-DUMMY(mq_notify);
-DUMMY(mq_getsetattr);
 /* Linux 4.11: */
 DUMMY(arch_prctl);
 /* Linux 5.0: */
diff --git a/sys/arm64/linux/linux_dummy_machdep.c 
b/sys/arm64/linux/linux_dummy_machdep.c
index a7a7795f573d..5ff6bfafe2d6 100644
--- a/sys/arm64/linux/linux_dummy_machdep.c
+++ b/sys/arm64/linux/linux_dummy_machdep.c
@@ -42,10 +42,4 @@ LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
  * Before adding new stubs to this file, please check if a stub can be added to
  * the machine-independent code in sys/compat/linux/linux_dummy.c.
  */
-DUMMY(mq_open);
-DUMMY(mq_unlink);
-DUMMY(mq_timedsend);
-DUMMY(mq_timedreceive);
-DUMMY(mq_notify);
-DUMMY(mq_getsetattr);
 DUMMY(kexec_file_load);
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index 9b8ab193f2bd..14c36669efc8 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -29,6 +29,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include "opt_posix.h"
+
 #include <sys/param.h>
 #include <sys/fcntl.h>
 #include <sys/jail.h>
@@ -36,6 +38,7 @@
 #include <sys/limits.h>
 #include <sys/lock.h>
 #include <sys/msgbuf.h>
+#include <sys/mqueue.h>
 #include <sys/mutex.h>
 #include <sys/poll.h>
 #include <sys/priv.h>
@@ -2963,3 +2966,124 @@ linux_ioprio_set(struct thread *td, struct 
linux_ioprio_set_args *args)
        }
        return (error);
 }
+
+/* The only flag is O_NONBLOCK */
+#define B2L_MQ_FLAGS(bflags)   ((bflags) != 0 ? LINUX_O_NONBLOCK : 0)
+#define L2B_MQ_FLAGS(lflags)   ((lflags) != 0 ? O_NONBLOCK : 0)
+
+int
+linux_mq_open(struct thread *td, struct linux_mq_open_args *args)
+{
+       struct mq_attr attr;
+       int error, flags;
+
+       flags = linux_common_openflags(args->oflag);
+       if ((flags & O_ACCMODE) == O_ACCMODE || (flags & O_EXEC) != 0)
+               return (EINVAL);
+       flags = FFLAGS(flags);
+       if ((flags & O_CREAT) != 0 && args->attr != NULL) {
+               error = copyin(args->attr, &attr, sizeof(attr));
+               if (error != 0)
+                       return (error);
+               attr.mq_flags = L2B_MQ_FLAGS(attr.mq_flags);
+       }
+
+       return (kern_kmq_open(td, args->name, flags, args->mode,
+           args->attr != NULL ? &attr : NULL));
+}
+
+int
+linux_mq_unlink(struct thread *td, struct linux_mq_unlink_args *args)
+{
+       struct kmq_unlink_args bsd_args = {
+               .path = PTRIN(args->name)
+       };
+
+       return (sys_kmq_unlink(td, &bsd_args));
+}
+
+int
+linux_mq_timedsend(struct thread *td, struct linux_mq_timedsend_args *args)
+{
+       struct timespec ts, *abs_timeout;
+       int error;
+
+       if (args->abs_timeout == NULL)
+               abs_timeout = NULL;
+       else {
+               error = linux_get_timespec(&ts, args->abs_timeout);
+               if (error != 0)
+                       return (error);
+               abs_timeout = &ts;
+       }
+
+       return (kern_kmq_timedsend(td, args->mqd, PTRIN(args->msg_ptr),
+               args->msg_len, args->msg_prio, abs_timeout));
+}
+
+int
+linux_mq_timedreceive(struct thread *td, struct linux_mq_timedreceive_args 
*args)
+{
+       struct timespec ts, *abs_timeout;
+       int error;
+
+       if (args->abs_timeout == NULL)
+               abs_timeout = NULL;
+       else {
+               error = linux_get_timespec(&ts, args->abs_timeout);
+               if (error != 0)
+                       return (error);
+               abs_timeout = &ts;
+       }
+
+       return (kern_kmq_timedreceive(td, args->mqd, PTRIN(args->msg_ptr),
+               args->msg_len, args->msg_prio, abs_timeout));
+}
+
+int
+linux_mq_notify(struct thread *td, struct linux_mq_notify_args *args)
+{
+       struct sigevent ev, *evp;
+       struct l_sigevent l_ev;
+       int error;
+
+       if (args->sevp == NULL)
+               evp = NULL;
+       else {
+               error = copyin(args->sevp, &l_ev, sizeof(l_ev));
+               if (error != 0)
+                       return (error);
+               error = linux_convert_l_sigevent(&l_ev, &ev);
+               if (error != 0)
+                       return (error);
+               evp = &ev;
+       }
+
+       return (kern_kmq_notify(td, args->mqd, evp));
+}
+
+int
+linux_mq_getsetattr(struct thread *td, struct linux_mq_getsetattr_args *args)
+{
+       struct mq_attr attr, oattr;
+       int error;
+
+       if (args->attr != NULL) {
+               error = copyin(args->attr, &attr, sizeof(attr));
+               if (error != 0)
+                       return (error);
+               attr.mq_flags = L2B_MQ_FLAGS(attr.mq_flags);
+       }
+
+       error = kern_kmq_setattr(td, args->mqd, args->attr != NULL ? &attr : 
NULL,
+           &oattr);
+       if (error == 0 && args->oattr != NULL) {
+               oattr.mq_flags = B2L_MQ_FLAGS(oattr.mq_flags);
+               bzero(oattr.__reserved, sizeof(oattr.__reserved));
+               error = copyout(&oattr, args->oattr, sizeof(oattr));
+       }
+
+       return (error);
+}
+
+MODULE_DEPEND(linux, mqueuefs, 1, 1, 1);
diff --git a/sys/i386/linux/linux_machdep.c b/sys/i386/linux/linux_machdep.c
index b5d42dc22162..0e056aadb4b5 100644
--- a/sys/i386/linux/linux_machdep.c
+++ b/sys/i386/linux/linux_machdep.c
@@ -592,67 +592,6 @@ linux_get_thread_area(struct thread *td, struct 
linux_get_thread_area_args *args
        return (0);
 }
 
-/* XXX: this wont work with module - convert it */
-int
-linux_mq_open(struct thread *td, struct linux_mq_open_args *args)
-{
-#ifdef P1003_1B_MQUEUE
-       return (sys_kmq_open(td, (struct kmq_open_args *)args));
-#else
-       return (ENOSYS);
-#endif
-}
-
-int
-linux_mq_unlink(struct thread *td, struct linux_mq_unlink_args *args)
-{
-#ifdef P1003_1B_MQUEUE
-       return (sys_kmq_unlink(td, (struct kmq_unlink_args *)args));
-#else
-       return (ENOSYS);
-#endif
-}
-
-int
-linux_mq_timedsend(struct thread *td, struct linux_mq_timedsend_args *args)
-{
-#ifdef P1003_1B_MQUEUE
-       return (sys_kmq_timedsend(td, (struct kmq_timedsend_args *)args));
-#else
-       return (ENOSYS);
-#endif
-}
-
-int
-linux_mq_timedreceive(struct thread *td, struct linux_mq_timedreceive_args 
*args)
-{
-#ifdef P1003_1B_MQUEUE
-       return (sys_kmq_timedreceive(td, (struct kmq_timedreceive_args *)args));
-#else
-       return (ENOSYS);
-#endif
-}
-
-int
-linux_mq_notify(struct thread *td, struct linux_mq_notify_args *args)
-{
-#ifdef P1003_1B_MQUEUE
-       return (sys_kmq_notify(td, (struct kmq_notify_args *)args));
-#else
-       return (ENOSYS);
-#endif
-}
-
-int
-linux_mq_getsetattr(struct thread *td, struct linux_mq_getsetattr_args *args)
-{
-#ifdef P1003_1B_MQUEUE
-       return (sys_kmq_setattr(td, (struct kmq_setattr_args *)args));
-#else
-       return (ENOSYS);
-#endif
-}
-
 void
 bsd_to_linux_regset(const struct reg *b_reg,
     struct linux_pt_regset *l_regset)

Reply via email to