lkml.org 
[lkml]   [2012]   [Feb]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[PATCH 1/2] IPC: message queue receive cleanup
    From
    Date
    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>

    ---
    arch/tile/kernel/compat.c | 11 +----------
    include/linux/compat.h | 2 ++
    include/linux/msg.h | 5 +++--
    ipc/compat.c | 33 +++++++++++++++++----------------
    ipc/msg.c | 44 +++++++++++++++++++++++---------------------
    5 files changed, 46 insertions(+), 49 deletions(-)

    diff --git a/arch/tile/kernel/compat.c b/arch/tile/kernel/compat.c
    index bf5e9d7..d963b45 100644
    --- a/arch/tile/kernel/compat.c
    +++ b/arch/tile/kernel/compat.c
    @@ -121,16 +121,7 @@ long tile_compat_sys_msgrcv(int msqid,
    struct compat_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, compat_do_msg_fill);
    }

    /* Provide the compat syscall number to call mapping. */
    diff --git a/include/linux/compat.h b/include/linux/compat.h
    index 41c9f65..7389209 100644
    --- a/include/linux/compat.h
    +++ b/include/linux/compat.h
    @@ -224,6 +224,7 @@ struct compat_sysinfo;
    struct compat_sysctl_args;
    struct compat_kexec_segment;
    struct compat_mq_attr;
    +struct msg_msg;

    extern void compat_exit_robust_list(struct task_struct *curr);

    @@ -236,6 +237,7 @@ compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,

    long compat_sys_semctl(int first, int second, int third, void __user *uptr);
    long compat_sys_msgsnd(int first, int second, int third, void __user *uptr);
    +long compat_do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz);
    long compat_sys_msgrcv(int first, int second, int msgtyp, int third,
    int version, void __user *uptr);
    long compat_sys_msgctl(int first, int second, void __user *uptr);
    diff --git a/include/linux/msg.h b/include/linux/msg.h
    index 6689e73..9411b76 100644
    --- a/include/linux/msg.h
    +++ b/include/linux/msg.h
    @@ -105,8 +105,9 @@ 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 /* __KERNEL__ */

    diff --git a/ipc/compat.c b/ipc/compat.c
    index b828244..38c1ee5 100644
    --- a/ipc/compat.c
    +++ b/ipc/compat.c
    @@ -328,13 +328,23 @@ long compat_sys_msgsnd(int first, int second, int third, void __user *uptr)
    return do_msgsnd(first, type, up->mtext, second, third);
    }

    +long compat_do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz)
    +{
    + struct compat_msgbuf __user *msgp;
    + 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 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)
    @@ -342,23 +352,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);
    }

    static inline int get_compat_msqid64(struct msqid64_ds *m64,
    diff --git a/ipc/msg.c b/ipc/msg.c
    index 303362b..1d34c11 100644
    --- a/ipc/msg.c
    +++ b/ipc/msg.c
    @@ -762,15 +762,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_fill)(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;
    @@ -814,7 +829,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;
    }
    @@ -841,7 +856,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);
    @@ -904,29 +919,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_fill(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


    \
     
     \ /
      Last update: 2012-02-15 17:57    [W:0.033 / U:118.856 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site