do_msgsnd is split into check_and_load_msgsnd and __do_msgsnd. This does not introduce any change in the functions' operation. Its only needed for async msgsnd in io_uring which will be added in a later patch. Functions used for msgsnd and msgrcv are also declared in the header file for use in io_uring patches later. Signed-off-by: Usama Arif <usama.arif@xxxxxxxxxxxxx> --- include/linux/msg.h | 11 ++++++++++ ipc/msg.c | 52 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 51 insertions(+), 12 deletions(-) diff --git a/include/linux/msg.h b/include/linux/msg.h index 9a972a296b95..36e3116fed86 100644 --- a/include/linux/msg.h +++ b/include/linux/msg.h @@ -15,4 +15,15 @@ struct msg_msg { /* the actual message follows immediately */ }; +long check_and_load_msgsnd(int msqid, long mtype, void __user *mtext, + struct msg_msg **msg, size_t msgsz); + +void free_msg(struct msg_msg *msg); + +long __do_msgsnd(int msqid, long mtype, struct msg_msg **msg, + size_t msgsz, int msgflg); + +long ksys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, + long msgtyp, int msgflg); + #endif /* _LINUX_MSG_H */ diff --git a/ipc/msg.c b/ipc/msg.c index a0d05775af2c..0682204a684e 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -839,14 +839,11 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg, return 0; } -static long do_msgsnd(int msqid, long mtype, void __user *mtext, - size_t msgsz, int msgflg) +long check_and_load_msgsnd(int msqid, long mtype, void __user *mtext, + struct msg_msg **msg, size_t msgsz) { - struct msg_queue *msq; - struct msg_msg *msg; - int err; struct ipc_namespace *ns; - DEFINE_WAKE_Q(wake_q); + struct msg_msg *tmp; ns = current->nsproxy->ipc_ns; @@ -855,12 +852,45 @@ static long do_msgsnd(int msqid, long mtype, void __user *mtext, if (mtype < 1) return -EINVAL; - msg = load_msg(mtext, msgsz); + tmp = load_msg(mtext, msgsz); if (IS_ERR(msg)) return PTR_ERR(msg); - msg->m_type = mtype; - msg->m_ts = msgsz; + tmp->m_type = mtype; + tmp->m_ts = msgsz; + + *msg = tmp; + return 0; +} + +static long do_msgsnd(int msqid, long mtype, void __user *mtext, + size_t msgsz, int msgflg) +{ + struct msg_msg *msg; + int err; + + err = check_and_load_msgsnd(msqid, mtype, mtext, &msg, msgsz); + if (err) + return err; + + err = __do_msgsnd(msqid, mtype, &msg, msgsz, msgflg); + if (msg != NULL) + free_msg(msg); + + return err; +} + +long __do_msgsnd(int msqid, long mtype, struct msg_msg **_msg, + size_t msgsz, int msgflg) +{ + struct msg_queue *msq; + struct msg_msg *msg; + int err; + struct ipc_namespace *ns; + DEFINE_WAKE_Q(wake_q); + + msg = *_msg; + ns = current->nsproxy->ipc_ns; rcu_read_lock(); msq = msq_obtain_object_check(ns, msqid); @@ -940,15 +970,13 @@ static long do_msgsnd(int msqid, long mtype, void __user *mtext, } err = 0; - msg = NULL; + *_msg = NULL; out_unlock0: ipc_unlock_object(&msq->q_perm); wake_up_q(&wake_q); out_unlock1: rcu_read_unlock(); - if (msg != NULL) - free_msg(msg); return err; } -- 2.25.1