diff options
author | Stanislav Kinsbursky <skinsbursky@parallels.com> | 2013-01-04 18:34:52 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-01-04 19:11:45 -0500 |
commit | f9dd87f4738c7555aca2cdf8cb2b2326cafb0cad (patch) | |
tree | 4fb581910eaee4309ae6befeef8c4f921b274c5d /ipc/msg.c | |
parent | 03f595668017f1a1fb971c02fc37140bc6e7bb1c (diff) |
ipc: message queue receive cleanup
Move all message related manipulation into one function msg_fill().
Actually, two functions because of the compat one.
[akpm@linux-foundation.org: checkpatch fixes]
Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Cc: Serge Hallyn <serge.hallyn@canonical.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Pavel Emelyanov <xemul@parallels.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Michael Kerrisk <mtk.manpages@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'ipc/msg.c')
-rw-r--r-- | ipc/msg.c | 44 |
1 files changed, 23 insertions, 21 deletions
@@ -755,15 +755,30 @@ static inline int convert_mode(long *msgtyp, int msgflg) | |||
755 | return SEARCH_EQUAL; | 755 | return SEARCH_EQUAL; |
756 | } | 756 | } |
757 | 757 | ||
758 | long do_msgrcv(int msqid, long *pmtype, void __user *mtext, | 758 | static long do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz) |
759 | size_t msgsz, long msgtyp, int msgflg) | 759 | { |
760 | struct msgbuf __user *msgp = dest; | ||
761 | size_t msgsz; | ||
762 | |||
763 | if (put_user(msg->m_type, &msgp->mtype)) | ||
764 | return -EFAULT; | ||
765 | |||
766 | msgsz = (bufsz > msg->m_ts) ? msg->m_ts : bufsz; | ||
767 | if (store_msg(msgp->mtext, msg, msgsz)) | ||
768 | return -EFAULT; | ||
769 | return msgsz; | ||
770 | } | ||
771 | |||
772 | long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, | ||
773 | int msgflg, | ||
774 | long (*msg_handler)(void __user *, struct msg_msg *, size_t)) | ||
760 | { | 775 | { |
761 | struct msg_queue *msq; | 776 | struct msg_queue *msq; |
762 | struct msg_msg *msg; | 777 | struct msg_msg *msg; |
763 | int mode; | 778 | int mode; |
764 | struct ipc_namespace *ns; | 779 | struct ipc_namespace *ns; |
765 | 780 | ||
766 | if (msqid < 0 || (long) msgsz < 0) | 781 | if (msqid < 0 || (long) bufsz < 0) |
767 | return -EINVAL; | 782 | return -EINVAL; |
768 | mode = convert_mode(&msgtyp, msgflg); | 783 | mode = convert_mode(&msgtyp, msgflg); |
769 | ns = current->nsproxy->ipc_ns; | 784 | ns = current->nsproxy->ipc_ns; |
@@ -804,7 +819,7 @@ long do_msgrcv(int msqid, long *pmtype, void __user *mtext, | |||
804 | * Found a suitable message. | 819 | * Found a suitable message. |
805 | * Unlink it from the queue. | 820 | * Unlink it from the queue. |
806 | */ | 821 | */ |
807 | if ((msgsz < msg->m_ts) && !(msgflg & MSG_NOERROR)) { | 822 | if ((bufsz < msg->m_ts) && !(msgflg & MSG_NOERROR)) { |
808 | msg = ERR_PTR(-E2BIG); | 823 | msg = ERR_PTR(-E2BIG); |
809 | goto out_unlock; | 824 | goto out_unlock; |
810 | } | 825 | } |
@@ -831,7 +846,7 @@ long do_msgrcv(int msqid, long *pmtype, void __user *mtext, | |||
831 | if (msgflg & MSG_NOERROR) | 846 | if (msgflg & MSG_NOERROR) |
832 | msr_d.r_maxsize = INT_MAX; | 847 | msr_d.r_maxsize = INT_MAX; |
833 | else | 848 | else |
834 | msr_d.r_maxsize = msgsz; | 849 | msr_d.r_maxsize = bufsz; |
835 | msr_d.r_msg = ERR_PTR(-EAGAIN); | 850 | msr_d.r_msg = ERR_PTR(-EAGAIN); |
836 | current->state = TASK_INTERRUPTIBLE; | 851 | current->state = TASK_INTERRUPTIBLE; |
837 | msg_unlock(msq); | 852 | msg_unlock(msq); |
@@ -894,29 +909,16 @@ out_unlock: | |||
894 | if (IS_ERR(msg)) | 909 | if (IS_ERR(msg)) |
895 | return PTR_ERR(msg); | 910 | return PTR_ERR(msg); |
896 | 911 | ||
897 | msgsz = (msgsz > msg->m_ts) ? msg->m_ts : msgsz; | 912 | bufsz = msg_handler(buf, msg, bufsz); |
898 | *pmtype = msg->m_type; | ||
899 | if (store_msg(mtext, msg, msgsz)) | ||
900 | msgsz = -EFAULT; | ||
901 | |||
902 | free_msg(msg); | 913 | free_msg(msg); |
903 | 914 | ||
904 | return msgsz; | 915 | return bufsz; |
905 | } | 916 | } |
906 | 917 | ||
907 | SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz, | 918 | SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz, |
908 | long, msgtyp, int, msgflg) | 919 | long, msgtyp, int, msgflg) |
909 | { | 920 | { |
910 | long err, mtype; | 921 | return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill); |
911 | |||
912 | err = do_msgrcv(msqid, &mtype, msgp->mtext, msgsz, msgtyp, msgflg); | ||
913 | if (err < 0) | ||
914 | goto out; | ||
915 | |||
916 | if (put_user(mtype, &msgp->mtype)) | ||
917 | err = -EFAULT; | ||
918 | out: | ||
919 | return err; | ||
920 | } | 922 | } |
921 | 923 | ||
922 | #ifdef CONFIG_PROC_FS | 924 | #ifdef CONFIG_PROC_FS |