[PATCH] ipc/msg: add msgsnd_timed and msgrcv_timed syscall for system V message queue
From: Eric Gao <hidden>
Date: 2021-02-27 06:55:07
Also in:
linux-arm-kernel
Subsystem:
abi/api, alpha port, arm port, arm64 port (aarch64 architecture), generic include/asm header files, linux for powerpc (32-bit and 64-bit), m68k architecture, microblaze architecture, mips, parisc architecture, s390 architecture, sparc + ultrasparc (sparc/sparc64), superh, tensilica xtensa port (xtensa), the rest, x86 architecture (32-bit and 64-bit), x86 entry code · Maintainers:
Richard Henderson, Matt Turner, Magnus Lindholm, Russell King, Catalin Marinas, Will Deacon, Arnd Bergmann, Madhavan Srinivasan, Geert Uytterhoeven, Michal Simek, Thomas Bogendoerfer, "James E.J. Bottomley", Helge Deller, Heiko Carstens, Vasily Gorbik, Alexander Gordeev, "David S. Miller", Andreas Larsson, Yoshinori Sato, Rich Felker, John Paul Adrian Glaubitz, Chris Zankel, Max Filippov, Linus Torvalds, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, Andy Lutomirski
sometimes, we need the msgsnd or msgrcv syscall can return after a limited time, so that the business thread do not be blocked here all the time. In this case, I add the msgsnd_timed and msgrcv_timed syscall that with time parameter, which has a unit of ms. Signed-off-by: Eric Gao <redacted> --- arch/alpha/kernel/syscalls/syscall.tbl | 2 + arch/arm/tools/syscall.tbl | 2 + arch/arm64/include/asm/unistd.h | 2 +- arch/arm64/include/asm/unistd32.h | 4 ++ arch/ia64/kernel/syscalls/syscall.tbl | 2 + arch/m68k/kernel/syscalls/syscall.tbl | 2 + arch/microblaze/kernel/syscalls/syscall.tbl | 2 + arch/mips/kernel/syscalls/syscall_n32.tbl | 2 + arch/mips/kernel/syscalls/syscall_n64.tbl | 2 + arch/mips/kernel/syscalls/syscall_o32.tbl | 2 + arch/parisc/kernel/syscalls/syscall.tbl | 2 + arch/powerpc/kernel/syscalls/syscall.tbl | 2 + arch/s390/kernel/syscalls/syscall.tbl | 2 + arch/sh/kernel/syscalls/syscall.tbl | 2 + arch/sparc/kernel/syscalls/syscall.tbl | 2 + arch/x86/entry/syscalls/syscall_32.tbl | 2 + arch/x86/entry/syscalls/syscall_64.tbl | 2 + arch/xtensa/kernel/syscalls/syscall.tbl | 2 + include/linux/compat.h | 4 ++ include/linux/syscalls.h | 4 ++ include/uapi/asm-generic/unistd.h | 6 +- ipc/msg.c | 87 ++++++++++++++++++++++++++--- kernel/sys_ni.c | 4 ++ 23 files changed, 133 insertions(+), 10 deletions(-)
diff --git a/arch/alpha/kernel/syscalls/syscall.tbl b/arch/alpha/kernel/syscalls/syscall.tbl
index 02f0244..eed8cc6 100644
--- a/arch/alpha/kernel/syscalls/syscall.tbl
+++ b/arch/alpha/kernel/syscalls/syscall.tbl@@ -482,3 +482,5 @@ 550 common process_madvise sys_process_madvise 551 common epoll_pwait2 sys_epoll_pwait2 552 common mount_setattr sys_mount_setattr +553 common msgrcv_timed sys_msgrcv_timed +554 common msgsnd_timed sys_msgsnd_timed
diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl
index dcc1191..c16baa6 100644
--- a/arch/arm/tools/syscall.tbl
+++ b/arch/arm/tools/syscall.tbl@@ -456,3 +456,5 @@ 440 common process_madvise sys_process_madvise 441 common epoll_pwait2 sys_epoll_pwait2 442 common mount_setattr sys_mount_setattr +443 common msgrcv_timed sys_msgrcv_timed +444 common msgsnd_timed sys_msgsnd_timed
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 949788f..64ebdc1e 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h@@ -38,7 +38,7 @@ #define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE + 5) #define __ARM_NR_COMPAT_END (__ARM_NR_COMPAT_BASE + 0x800) -#define __NR_compat_syscalls 443 +#define __NR_compat_syscalls 445 #endif #define __ARCH_WANT_SYS_CLONE
diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h
index 3d874f6..705676a 100644
--- a/arch/arm64/include/asm/unistd32.h
+++ b/arch/arm64/include/asm/unistd32.h@@ -893,6 +893,10 @@ __SYSCALL(__NR_process_madvise, sys_process_madvise) __SYSCALL(__NR_epoll_pwait2, compat_sys_epoll_pwait2) #define __NR_mount_setattr 442 __SYSCALL(__NR_mount_setattr, sys_mount_setattr) +#define __NR_msgrcv_timed 443 +__SYSCALL(__NR_msgrcv_timed, sys_msgrcv_timed) +#define __NR_msgsnd_timed 444 +__SYSCALL(__NR_msgsnd_timed, sys_msgsnd_timed) /* * Please add new compat syscalls above this comment and update
diff --git a/arch/ia64/kernel/syscalls/syscall.tbl b/arch/ia64/kernel/syscalls/syscall.tbl
index d892311..ad57e6d 100644
--- a/arch/ia64/kernel/syscalls/syscall.tbl
+++ b/arch/ia64/kernel/syscalls/syscall.tbl@@ -363,3 +363,5 @@ 440 common process_madvise sys_process_madvise 441 common epoll_pwait2 sys_epoll_pwait2 442 common mount_setattr sys_mount_setattr +443 common msgrcv_timed sys_msgrcv_timed +444 common msgsnd_timed sys_msgsnd_timed
diff --git a/arch/m68k/kernel/syscalls/syscall.tbl b/arch/m68k/kernel/syscalls/syscall.tbl
index 72bde67..1d33825 100644
--- a/arch/m68k/kernel/syscalls/syscall.tbl
+++ b/arch/m68k/kernel/syscalls/syscall.tbl@@ -442,3 +442,5 @@ 440 common process_madvise sys_process_madvise 441 common epoll_pwait2 sys_epoll_pwait2 442 common mount_setattr sys_mount_setattr +443 common msgrcv_timed sys_msgrcv_timed +444 common msgsnd_timed sys_msgsnd_timed
diff --git a/arch/microblaze/kernel/syscalls/syscall.tbl b/arch/microblaze/kernel/syscalls/syscall.tbl
index d603a5e..38d7f7a 100644
--- a/arch/microblaze/kernel/syscalls/syscall.tbl
+++ b/arch/microblaze/kernel/syscalls/syscall.tbl@@ -448,3 +448,5 @@ 440 common process_madvise sys_process_madvise 441 common epoll_pwait2 sys_epoll_pwait2 442 common mount_setattr sys_mount_setattr +443 common msgrcv_timed sys_msgrcv_timed +444 common msgsnd_timed sys_msgsnd_timed
diff --git a/arch/mips/kernel/syscalls/syscall_n32.tbl b/arch/mips/kernel/syscalls/syscall_n32.tbl
index 8fd8c17..42b7db5 100644
--- a/arch/mips/kernel/syscalls/syscall_n32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_n32.tbl@@ -381,3 +381,5 @@ 440 n32 process_madvise sys_process_madvise 441 n32 epoll_pwait2 compat_sys_epoll_pwait2 442 n32 mount_setattr sys_mount_setattr +443 n32 msgrcv_timed sys_msgrcv_timed +444 n32 msgsnd_timed sys_msgsnd_timed
diff --git a/arch/mips/kernel/syscalls/syscall_n64.tbl b/arch/mips/kernel/syscalls/syscall_n64.tbl
index 169f214..060208b 100644
--- a/arch/mips/kernel/syscalls/syscall_n64.tbl
+++ b/arch/mips/kernel/syscalls/syscall_n64.tbl@@ -357,3 +357,5 @@ 440 n64 process_madvise sys_process_madvise 441 n64 epoll_pwait2 sys_epoll_pwait2 442 n64 mount_setattr sys_mount_setattr +443 n64 msgrcv_timed sys_msgrcv_timed +444 n64 msgsnd_timed sys_msgsnd_timed
diff --git a/arch/mips/kernel/syscalls/syscall_o32.tbl b/arch/mips/kernel/syscalls/syscall_o32.tbl
index 090d29c..0f1f6ee 100644
--- a/arch/mips/kernel/syscalls/syscall_o32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_o32.tbl@@ -430,3 +430,5 @@ 440 o32 process_madvise sys_process_madvise 441 o32 epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2 442 o32 mount_setattr sys_mount_setattr +443 o32 msgrcv_timed sys_msgrcv_timed +444 o32 msgsnd_timed sys_msgsnd_timed
diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl
index 271a925..fef5544 100644
--- a/arch/parisc/kernel/syscalls/syscall.tbl
+++ b/arch/parisc/kernel/syscalls/syscall.tbl@@ -440,3 +440,5 @@ 440 common process_madvise sys_process_madvise 441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2 442 common mount_setattr sys_mount_setattr +443 common msgrcv_timed sys_msgrcv_timed compat_sys_msgrcv_timed +444 common msgsnd_timed sys_msgsnd_timed compat_sys_msgsnd_timed
diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl
index 0b2480c..115217c 100644
--- a/arch/powerpc/kernel/syscalls/syscall.tbl
+++ b/arch/powerpc/kernel/syscalls/syscall.tbl@@ -522,3 +522,5 @@ 440 common process_madvise sys_process_madvise 441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2 442 common mount_setattr sys_mount_setattr +443 common msgrcv_timed sys_msgrcv_timed compat_sys_msgrcv_timed +444 common msgsnd_timed sys_msgsnd_timed compat_sys_msgsnd_timed
diff --git a/arch/s390/kernel/syscalls/syscall.tbl b/arch/s390/kernel/syscalls/syscall.tbl
index 3abef21..863b992 100644
--- a/arch/s390/kernel/syscalls/syscall.tbl
+++ b/arch/s390/kernel/syscalls/syscall.tbl@@ -445,3 +445,5 @@ 440 common process_madvise sys_process_madvise sys_process_madvise 441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2 442 common mount_setattr sys_mount_setattr sys_mount_setattr +443 common msgrcv_timed sys_msgrcv_timed compat_sys_msgrcv_timed +444 common msgsnd_timed sys_msgsnd_timed compat_sys_msgsnd_timed
diff --git a/arch/sh/kernel/syscalls/syscall.tbl b/arch/sh/kernel/syscalls/syscall.tbl
index d08eeba..24245c0 100644
--- a/arch/sh/kernel/syscalls/syscall.tbl
+++ b/arch/sh/kernel/syscalls/syscall.tbl@@ -445,3 +445,5 @@ 440 common process_madvise sys_process_madvise 441 common epoll_pwait2 sys_epoll_pwait2 442 common mount_setattr sys_mount_setattr +443 common msgrcv_timed sys_msgrcv_timed +444 common msgsnd_timed sys_msgsnd_timed
diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/syscalls/syscall.tbl
index 84403a9..d35e062 100644
--- a/arch/sparc/kernel/syscalls/syscall.tbl
+++ b/arch/sparc/kernel/syscalls/syscall.tbl@@ -488,3 +488,5 @@ 440 common process_madvise sys_process_madvise 441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2 442 common mount_setattr sys_mount_setattr +443 common msgrcv_timed sys_msgrcv_timed compat_sys_msgrcv_timed +444 common msgsnd_timed sys_msgsnd_timed compat_sys_msgsnd_timed
diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
index a1c9f496f..6adc251 100644
--- a/arch/x86/entry/syscalls/syscall_32.tbl
+++ b/arch/x86/entry/syscalls/syscall_32.tbl@@ -447,3 +447,5 @@ 440 i386 process_madvise sys_process_madvise 441 i386 epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2 442 i386 mount_setattr sys_mount_setattr +443 i386 msgrcv_timed sys_msgrcv_timed compat_sys_msgrcv_timed +444 i386 msgsnd_timed sys_msgsnd_timed compat_sys_msgsnd_timed
diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
index 7bf01cb..44e4c63 100644
--- a/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/arch/x86/entry/syscalls/syscall_64.tbl@@ -364,6 +364,8 @@ 440 common process_madvise sys_process_madvise 441 common epoll_pwait2 sys_epoll_pwait2 442 common mount_setattr sys_mount_setattr +443 common msgrcv_timed sys_msgrcv_timed +444 common msgsnd_timed sys_msgsnd_timed # # Due to a historical design error, certain syscalls are numbered differently
diff --git a/arch/xtensa/kernel/syscalls/syscall.tbl b/arch/xtensa/kernel/syscalls/syscall.tbl
index 365a9b8..12bdd62 100644
--- a/arch/xtensa/kernel/syscalls/syscall.tbl
+++ b/arch/xtensa/kernel/syscalls/syscall.tbl@@ -413,3 +413,5 @@ 440 common process_madvise sys_process_madvise 441 common epoll_pwait2 sys_epoll_pwait2 442 common mount_setattr sys_mount_setattr +443 common msgrcv_timed sys_msgrcv_timed +444 common msgsnd_timed sys_msgsnd_timed
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 6e65be7..e2fd2ac 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h@@ -743,6 +743,10 @@ asmlinkage long compat_sys_msgrcv(int msqid, compat_uptr_t msgp, compat_ssize_t msgsz, compat_long_t msgtyp, int msgflg); asmlinkage long compat_sys_msgsnd(int msqid, compat_uptr_t msgp, compat_ssize_t msgsz, int msgflg); +asmlinkage long compat_sys_msgrcv_timed(int msqid, compat_uptr_t msgp, + compat_ssize_t msgsz, compat_long_t msgtyp, int msgflg, compat_long_t timeoutms); +asmlinkage long compat_sys_msgsnd_timed(int msqid, compat_uptr_t msgp, + compat_ssize_t msgsz, int msgflg, compat_long_t timeoutms); /* ipc/sem.c */ asmlinkage long compat_sys_semctl(int semid, int semnum, int cmd, int arg);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 2839dc9..369cc19 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h@@ -808,6 +808,10 @@ asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, long msgtyp, int msgflg); asmlinkage long sys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz, int msgflg); +asmlinkage long sys_msgrcv_timed(int msqid, struct msgbuf __user *msgp, + size_t msgsz, long msgtyp, int msgflg, long timeoutms); +asmlinkage long sys_msgsnd_timed(int msqid, struct msgbuf __user *msgp, + size_t msgsz, int msgflg, long timeoutms); /* ipc/sem.c */ asmlinkage long sys_semget(key_t key, int nsems, int semflg);
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index ce58cff..ef3cfad 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h@@ -561,6 +561,10 @@ __SC_COMP(__NR_msgctl, sys_msgctl, compat_sys_msgctl) __SC_COMP(__NR_msgrcv, sys_msgrcv, compat_sys_msgrcv) #define __NR_msgsnd 189 __SC_COMP(__NR_msgsnd, sys_msgsnd, compat_sys_msgsnd) +#define __NR_msgrcv_timed 443 +__SC_COMP(__NR_msgrcv_timed, sys_msgrcv_timed, compat_sys_msgrcv_timed) +#define __NR_msgsnd_timed 444 +__SC_COMP(__NR_msgsnd_timed, sys_msgsnd_timed, compat_sys_msgsnd_timed) /* ipc/sem.c */ #define __NR_semget 190
@@ -865,7 +869,7 @@ __SC_COMP(__NR_epoll_pwait2, sys_epoll_pwait2, compat_sys_epoll_pwait2) __SYSCALL(__NR_mount_setattr, sys_mount_setattr) #undef __NR_syscalls -#define __NR_syscalls 443 +#define __NR_syscalls 445 /* * 32 bit systems traditionally used different
diff --git a/ipc/msg.c b/ipc/msg.c
index acd1bc7..88167c0 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c@@ -838,13 +838,14 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg, } static long do_msgsnd(int msqid, long mtype, void __user *mtext, - size_t msgsz, int msgflg) + size_t msgsz, int msgflg, long timeoutms) { struct msg_queue *msq; struct msg_msg *msg; int err; struct ipc_namespace *ns; DEFINE_WAKE_Q(wake_q); + bool timeoutflag = false; ns = current->nsproxy->ipc_ns;
@@ -905,7 +906,15 @@ static long do_msgsnd(int msqid, long mtype, void __user *mtext, ipc_unlock_object(&msq->q_perm); rcu_read_unlock(); - schedule(); + + /* sometimes, we need msgsnd syscall return after a given time */ + if (timeoutms <= 0) { + schedule(); + } else { + timeoutms = schedule_timeout(timeoutms); + if (timeoutms == 0) + timeoutflag = true; + } rcu_read_lock(); ipc_lock_object(&msq->q_perm);
@@ -918,6 +927,11 @@ static long do_msgsnd(int msqid, long mtype, void __user *mtext, } ss_del(&s); + if (true == timeoutflag) { + err = -ETIME; + goto out_unlock0; + } + if (signal_pending(current)) { err = -ERESTARTNOHAND; goto out_unlock0;
@@ -957,7 +971,7 @@ long ksys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz, if (get_user(mtype, &msgp->mtype)) return -EFAULT; - return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg); + return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg, 0); } SYSCALL_DEFINE4(msgsnd, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
@@ -966,6 +980,18 @@ SYSCALL_DEFINE4(msgsnd, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz, return ksys_msgsnd(msqid, msgp, msgsz, msgflg); } +SYSCALL_DEFINE5(msgsnd_timed, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz, + int, msgflg, long, timeoutms) +{ + long mtype; + + timeoutms = (timeoutms + 9) / 10; + + if (get_user(mtype, &msgp->mtype)) + return -EFAULT; + return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg, timeoutms); +} + #ifdef CONFIG_COMPAT struct compat_msgbuf {
@@ -981,7 +1007,7 @@ long compat_ksys_msgsnd(int msqid, compat_uptr_t msgp, if (get_user(mtype, &up->mtype)) return -EFAULT; - return do_msgsnd(msqid, mtype, up->mtext, (ssize_t)msgsz, msgflg); + return do_msgsnd(msqid, mtype, up->mtext, (ssize_t)msgsz, msgflg, 0); } COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp,
@@ -989,6 +1015,20 @@ COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp, { return compat_ksys_msgsnd(msqid, msgp, msgsz, msgflg); } + +COMPAT_SYSCALL_DEFINE5(msgsnd_timed, int, msqid, compat_uptr_t, msgp, + compat_ssize_t, msgsz, int, msgflg, compat_long_t, timeoutms) +{ + struct compat_msgbuf __user *up = compat_ptr(msgp); + compat_long_t mtype; + + timeoutms = (timeoutms + 9) / 10; + + if (get_user(mtype, &up->mtype)) + return -EFAULT; + + return do_msgsnd(msqid, mtype, up->mtext, (ssize_t)msgsz, msgflg, (long)timeoutms); +} #endif static inline int convert_mode(long *msgtyp, int msgflg)
@@ -1088,13 +1128,14 @@ static struct msg_msg *find_msg(struct msg_queue *msq, long *msgtyp, int mode) } static long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgflg, - long (*msg_handler)(void __user *, struct msg_msg *, size_t)) + long (*msg_handler)(void __user *, struct msg_msg *, size_t), long timeoutms) { int mode; struct msg_queue *msq; struct ipc_namespace *ns; struct msg_msg *msg, *copy = NULL; DEFINE_WAKE_Q(wake_q); + bool timeoutflag = false; ns = current->nsproxy->ipc_ns;
@@ -1187,7 +1228,15 @@ static long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, in ipc_unlock_object(&msq->q_perm); rcu_read_unlock(); - schedule(); + + /* sometimes, we need msgrcv syscall return after a given time */ + if (timeoutms <= 0) { + schedule(); + } else { + timeoutms = schedule_timeout(timeoutms); + if (timeoutms == 0) + timeoutflag = true; + } /* * Lockless receive, part 1:
@@ -1229,6 +1278,12 @@ static long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, in goto out_unlock0; list_del(&msr_d.r_list); + + if (true == timeoutflag) { + msg = ERR_PTR(-ETIME); + goto out_unlock0; + } + if (signal_pending(current)) { msg = ERR_PTR(-ERESTARTNOHAND); goto out_unlock0;
@@ -1256,7 +1311,7 @@ static long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, in long ksys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, long msgtyp, int msgflg) { - return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill); + return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill, 0); } SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
@@ -1265,6 +1320,13 @@ SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz, return ksys_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg); } +SYSCALL_DEFINE6(msgrcv_timed, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz, + long, msgtyp, int, msgflg, long, timeoutms) +{ + timeoutms = (timeoutms + 9) / 10; + return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill, timeoutms); +} + #ifdef CONFIG_COMPAT static long compat_do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz) {
@@ -1284,7 +1346,7 @@ long compat_ksys_msgrcv(int msqid, compat_uptr_t msgp, compat_ssize_t msgsz, compat_long_t msgtyp, int msgflg) { return do_msgrcv(msqid, compat_ptr(msgp), (ssize_t)msgsz, (long)msgtyp, - msgflg, compat_do_msg_fill); + msgflg, compat_do_msg_fill, 0); } COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp,
@@ -1293,6 +1355,15 @@ COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp, { return compat_ksys_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg); } + +COMPAT_SYSCALL_DEFINE6(msgrcv_timed, int, msqid, compat_uptr_t, msgp, + compat_ssize_t, msgsz, compat_long_t, msgtyp, + int, msgflg, compat_long_t, timeoutms) +{ + timeoutms = (timeoutms + 9) / 10; + return do_msgrcv(msqid, compat_ptr(msgp), (ssize_t)msgsz, (long)msgtyp, + msgflg, compat_do_msg_fill, (long)timeoutms); +} #endif void msg_init_ns(struct ipc_namespace *ns)
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 19aa8068..783a1de 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c@@ -212,6 +212,10 @@ COND_SYSCALL(msgrcv); COND_SYSCALL_COMPAT(msgrcv); COND_SYSCALL(msgsnd); COND_SYSCALL_COMPAT(msgsnd); +COND_SYSCALL(msgrcv_timed); +COND_SYSCALL_COMPAT(msgrcv_timed); +COND_SYSCALL(msgsnd_timed); +COND_SYSCALL_COMPAT(msgsnd_timed); /* ipc/sem.c */ COND_SYSCALL(semget);
--
2.7.4