From: Stanislav Kinsbursky <skinsbursky@parallels.com>
To: akpm@linux-foundation.org
Cc: serge.hallyn@canonical.com, ebiederm@xmission.com,
linux-kernel@vger.kernel.org, xemul@parallels.com,
catalin.marinas@arm.com, will.deacon@arm.com, jmorris@namei.org,
cmetcalf@tilera.com, joe.korty@ccur.com, dhowells@redhat.com,
dledford@redhat.com, viro@zeniv.linux.org.uk,
kosaki.motohiro@jp.fujitsu.com, linux-api@vger.kernel.org,
serue@us.ibm.com, tglx@linutronix.de, paulmck@linux.vnet.ibm.com,
devel@openvz.org, mtk.manpages@gmail.com
Subject: [PATCH v8 3/5] ipc: message queue receive cleanup
Date: Wed, 24 Oct 2012 19:35:15 +0400 [thread overview]
Message-ID: <20121024153515.5642.78383.stgit@localhost.localdomain> (raw)
In-Reply-To: <20121024151555.5642.79086.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 ad9518e..eb3ea16 100644
--- a/ipc/compat.c
+++ b/ipc/compat.c
@@ -306,6 +306,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)
{
@@ -337,10 +351,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)
@@ -348,23 +358,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)
@@ -385,16 +386,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 2f272fa..532ebc3 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -755,15 +755,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;
@@ -804,7 +819,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;
}
@@ -831,7 +846,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);
@@ -894,29 +909,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-24 15:35 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-24 15:34 [RFC PATCH v8 0/5] IPC: checkpoint/restore in userspace enhancements Stanislav Kinsbursky
2012-10-24 15:35 ` [PATCH v8 2/5] ipc: add sysctl to specify desired next object id Stanislav Kinsbursky
2012-10-24 21:41 ` Andrew Morton
[not found] ` <20121024144123.0a77584b.akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
2012-10-25 7:53 ` Stanislav Kinsbursky
2012-10-25 7:53 ` Stanislav Kinsbursky
2012-10-24 15:35 ` Stanislav Kinsbursky [this message]
2012-10-24 15:35 ` [PATCH v8 4/5] ipc: message queue copy feature introduced Stanislav Kinsbursky
2012-10-24 21:41 ` Andrew Morton
2012-10-24 15:35 ` [PATCH v8 5/5] test: IPC message queue copy feture test Stanislav Kinsbursky
[not found] ` <20121024151555.5642.79086.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2012-10-24 15:35 ` [PATCH v8 1/5] ipc: remove forced assignment of selected message Stanislav Kinsbursky
2012-10-24 15:35 ` Stanislav Kinsbursky
2012-10-24 21:42 ` [RFC PATCH v8 0/5] IPC: checkpoint/restore in userspace enhancements Andrew Morton
2012-10-24 21:42 ` Andrew Morton
2012-12-18 20:36 ` Andrew Morton
2012-12-18 20:36 ` Andrew Morton
[not found] ` <20121218123601.113a29c0.akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
2012-12-20 4:06 ` Stanislav Kinsbursky
2012-12-20 4:06 ` Stanislav Kinsbursky
[not found] ` <50D28EC8.7000708-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
2012-12-20 20:47 ` Andrew Morton
2012-12-20 20:47 ` Andrew Morton
[not found] ` <20121220124751.d7ccbd8e.akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
2012-12-21 20:46 ` Stanislav Kinsbursky
2012-12-21 20:46 ` Stanislav Kinsbursky
[not found] ` <50D4CA90.60205-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
2012-12-21 21:57 ` Sasha Levin
2012-12-21 21:57 ` Sasha Levin
[not found] ` <50D4DB5D.9020309-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>
2012-12-22 15:43 ` Sasha Levin
2012-12-22 15:43 ` Sasha Levin
[not found] ` <50D5D50B.8090309-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>
2013-01-09 8:24 ` Stanislav Kinsbursky
2013-01-09 8:24 ` Stanislav Kinsbursky
2013-01-14 6:31 ` Sasha Levin
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=20121024153515.5642.78383.stgit@localhost.localdomain \
--to=skinsbursky@parallels.com \
--cc=akpm@linux-foundation.org \
--cc=catalin.marinas@arm.com \
--cc=cmetcalf@tilera.com \
--cc=devel@openvz.org \
--cc=dhowells@redhat.com \
--cc=dledford@redhat.com \
--cc=ebiederm@xmission.com \
--cc=jmorris@namei.org \
--cc=joe.korty@ccur.com \
--cc=kosaki.motohiro@jp.fujitsu.com \
--cc=linux-api@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mtk.manpages@gmail.com \
--cc=paulmck@linux.vnet.ibm.com \
--cc=serge.hallyn@canonical.com \
--cc=serue@us.ibm.com \
--cc=tglx@linutronix.de \
--cc=viro@zeniv.linux.org.uk \
--cc=will.deacon@arm.com \
--cc=xemul@parallels.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.