From: Stanislav Kinsbursky <skinsbursky@parallels.com>
To: akpm@linux-foundation.org
Cc: catalin.marinas@arm.com, will.deacon@arm.com,
dhowells@redhat.com, manfred@colorfullife.com, hughd@google.com,
jmorris@namei.org, mtk.manpages@gmail.com,
kosaki.motohiro@jp.fujitsu.com, paulmck@linux.vnet.ibm.com,
sds@tycho.nsa.gov, devel@openvz.org, a.p.zijlstra@chello.nl,
cmetcalf@tilera.com, linux-driver@qlogic.com,
ron.mercer@qlogic.com, viro@zeniv.linux.org.uk,
eparis@parisplace.org, tglx@linutronix.de,
jitendra.kalsaria@qlogic.com, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-security-module@vger.kernel.org, ebiederm@xmission.com,
casey@schaufler-ca.com
Subject: [PATCH v7 08/10] IPC: message queue receive cleanup
Date: Thu, 18 Oct 2012 14:23:17 +0400 [thread overview]
Message-ID: <20121018102317.16036.31807.stgit@localhost.localdomain> (raw)
In-Reply-To: <20121018101543.16036.12221.stgit@localhost.localdomain>
This patch moves all message related manipulation into one function msg_fill().
Actually, two functions because of the compat one.
Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
---
include/linux/msg.h | 5 +++--
ipc/compat.c | 45 +++++++++++++++++++--------------------------
ipc/msg.c | 44 +++++++++++++++++++++++---------------------
3 files changed, 45 insertions(+), 49 deletions(-)
diff --git a/include/linux/msg.h b/include/linux/msg.h
index 7a4b9e9..f38edba 100644
--- a/include/linux/msg.h
+++ b/include/linux/msg.h
@@ -34,7 +34,8 @@ struct msg_queue {
/* Helper routines for sys_msgsnd and sys_msgrcv */
extern long do_msgsnd(int msqid, long mtype, void __user *mtext,
size_t msgsz, int msgflg);
-extern long do_msgrcv(int msqid, long *pmtype, void __user *mtext,
- size_t msgsz, long msgtyp, int msgflg);
+extern long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp,
+ int msgflg,
+ long (*msg_fill)(void __user *, struct msg_msg *, size_t ));
#endif /* _LINUX_MSG_H */
diff --git a/ipc/compat.c b/ipc/compat.c
index 84d8efd..1fd8d1c 100644
--- a/ipc/compat.c
+++ b/ipc/compat.c
@@ -313,6 +313,20 @@ static long do_compat_semctl(int first, int second, int third, u32 pad)
return err;
}
+long compat_do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz)
+{
+ struct compat_msgbuf __user *msgp = dest;
+ size_t msgsz;
+
+ if (put_user(msg->m_type, &msgp->mtype))
+ return -EFAULT;
+
+ msgsz = (bufsz > msg->m_ts) ? msg->m_ts : bufsz;
+ if (store_msg(msgp->mtext, msg, msgsz))
+ return -EFAULT;
+ return msgsz;
+}
+
#ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC
long compat_sys_semctl(int first, int second, int third, void __user *uptr)
{
@@ -344,10 +358,6 @@ long compat_sys_msgsnd(int first, int second, int third, void __user *uptr)
long compat_sys_msgrcv(int first, int second, int msgtyp, int third,
int version, void __user *uptr)
{
- struct compat_msgbuf __user *up;
- long type;
- int err;
-
if (first < 0)
return -EINVAL;
if (second < 0)
@@ -355,23 +365,14 @@ long compat_sys_msgrcv(int first, int second, int msgtyp, int third,
if (!version) {
struct compat_ipc_kludge ipck;
- err = -EINVAL;
if (!uptr)
- goto out;
- err = -EFAULT;
+ return -EINVAL;
if (copy_from_user (&ipck, uptr, sizeof(ipck)))
- goto out;
+ return -EFAULT;
uptr = compat_ptr(ipck.msgp);
msgtyp = ipck.msgtyp;
}
- up = uptr;
- err = do_msgrcv(first, &type, up->mtext, second, msgtyp, third);
- if (err < 0)
- goto out;
- if (put_user(type, &up->mtype))
- err = -EFAULT;
-out:
- return err;
+ return do_msgrcv(first, uptr, second, msgtyp, third, compat_do_msg_fill);
}
#else
long compat_sys_semctl(int semid, int semnum, int cmd, int arg)
@@ -392,16 +393,8 @@ long compat_sys_msgsnd(int msqid, struct compat_msgbuf __user *msgp,
long compat_sys_msgrcv(int msqid, struct compat_msgbuf __user *msgp,
compat_ssize_t msgsz, long msgtyp, int msgflg)
{
- long err, mtype;
-
- err = do_msgrcv(msqid, &mtype, msgp->mtext, (ssize_t)msgsz, msgtyp, msgflg);
- if (err < 0)
- goto out;
-
- if (put_user(mtype, &msgp->mtype))
- err = -EFAULT;
- out:
- return err;
+ return do_msgrcv(msqid, msgp, (ssize_t)msgsz, msgtyp, msgflg,
+ compat_do_msg_fill);
}
#endif
diff --git a/ipc/msg.c b/ipc/msg.c
index 3c13b99..028ab87 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -767,15 +767,30 @@ static inline int convert_mode(long *msgtyp, int msgflg)
return SEARCH_EQUAL;
}
-long do_msgrcv(int msqid, long *pmtype, void __user *mtext,
- size_t msgsz, long msgtyp, int msgflg)
+static long do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz)
+{
+ struct msgbuf __user *msgp = dest;
+ size_t msgsz;
+
+ if (put_user(msg->m_type, &msgp->mtype))
+ return -EFAULT;
+
+ msgsz = (bufsz > msg->m_ts) ? msg->m_ts : bufsz;
+ if (store_msg(msgp->mtext, msg, msgsz))
+ return -EFAULT;
+ return msgsz;
+}
+
+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 ))
{
struct msg_queue *msq;
struct msg_msg *msg;
int mode;
struct ipc_namespace *ns;
- if (msqid < 0 || (long) msgsz < 0)
+ if (msqid < 0 || (long) bufsz < 0)
return -EINVAL;
mode = convert_mode(&msgtyp, msgflg);
ns = current->nsproxy->ipc_ns;
@@ -816,7 +831,7 @@ long do_msgrcv(int msqid, long *pmtype, void __user *mtext,
* Found a suitable message.
* Unlink it from the queue.
*/
- if ((msgsz < msg->m_ts) && !(msgflg & MSG_NOERROR)) {
+ if ((bufsz < msg->m_ts) && !(msgflg & MSG_NOERROR)) {
msg = ERR_PTR(-E2BIG);
goto out_unlock;
}
@@ -843,7 +858,7 @@ long do_msgrcv(int msqid, long *pmtype, void __user *mtext,
if (msgflg & MSG_NOERROR)
msr_d.r_maxsize = INT_MAX;
else
- msr_d.r_maxsize = msgsz;
+ msr_d.r_maxsize = bufsz;
msr_d.r_msg = ERR_PTR(-EAGAIN);
current->state = TASK_INTERRUPTIBLE;
msg_unlock(msq);
@@ -906,29 +921,16 @@ out_unlock:
if (IS_ERR(msg))
return PTR_ERR(msg);
- msgsz = (msgsz > msg->m_ts) ? msg->m_ts : msgsz;
- *pmtype = msg->m_type;
- if (store_msg(mtext, msg, msgsz))
- msgsz = -EFAULT;
-
+ bufsz = msg_handler(buf, msg, bufsz);
free_msg(msg);
- return msgsz;
+ return bufsz;
}
SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
long, msgtyp, int, msgflg)
{
- long err, mtype;
-
- err = do_msgrcv(msqid, &mtype, msgp->mtext, msgsz, msgtyp, msgflg);
- if (err < 0)
- goto out;
-
- if (put_user(mtype, &msgp->mtype))
- err = -EFAULT;
-out:
- return err;
+ return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill);
}
#ifdef CONFIG_PROC_FS
next prev parent reply other threads:[~2012-10-18 10:22 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-18 10:22 [PATCH v7 00/10] IPC: checkpoint/restore in userspace enhancements Stanislav Kinsbursky
2012-10-18 10:22 ` [PATCH v7 01/10] ipc: remove forced assignment of selected message Stanislav Kinsbursky
2012-10-18 10:22 ` [PATCH v7 02/10] ipc: "use key as id" functionality for resource get system call introduced Stanislav Kinsbursky
2012-10-18 10:22 ` [PATCH v7 03/10] ipc: segment key change helper introduced Stanislav Kinsbursky
2012-10-18 10:22 ` [PATCH v7 04/10] ipc: add new SHM_SET command for sys_shmctl() call Stanislav Kinsbursky
2012-10-18 10:23 ` [PATCH v7 05/10] ipc: add new MSG_SET command for sys_msgctl() call Stanislav Kinsbursky
2012-10-18 10:23 ` [PATCH v7 06/10] qlge driver: rename internal SEM_SET macro to SEM_INIT Stanislav Kinsbursky
2012-10-18 10:23 ` [PATCH v7 07/10] ipc: add new SEM_SET command for sys_semctl() call Stanislav Kinsbursky
2012-10-18 10:23 ` Stanislav Kinsbursky [this message]
2012-10-18 10:23 ` [PATCH v7 09/10] IPC: message queue copy feature introduced Stanislav Kinsbursky
2012-10-18 10:39 ` Michael Kerrisk (man-pages)
2012-10-18 10:23 ` [PATCH v7 10/10] test: IPC message queue copy feture test Stanislav Kinsbursky
2012-10-18 10:41 ` [PATCH v7 00/10] IPC: checkpoint/restore in userspace enhancements Michael Kerrisk (man-pages)
2012-10-18 12:11 ` Eric W. Biederman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20121018102317.16036.31807.stgit@localhost.localdomain \
--to=skinsbursky@parallels.com \
--cc=a.p.zijlstra@chello.nl \
--cc=akpm@linux-foundation.org \
--cc=casey@schaufler-ca.com \
--cc=catalin.marinas@arm.com \
--cc=cmetcalf@tilera.com \
--cc=devel@openvz.org \
--cc=dhowells@redhat.com \
--cc=ebiederm@xmission.com \
--cc=eparis@parisplace.org \
--cc=hughd@google.com \
--cc=jitendra.kalsaria@qlogic.com \
--cc=jmorris@namei.org \
--cc=kosaki.motohiro@jp.fujitsu.com \
--cc=linux-driver@qlogic.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=manfred@colorfullife.com \
--cc=mtk.manpages@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=paulmck@linux.vnet.ibm.com \
--cc=ron.mercer@qlogic.com \
--cc=sds@tycho.nsa.gov \
--cc=tglx@linutronix.de \
--cc=viro@zeniv.linux.org.uk \
--cc=will.deacon@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox