lkml.org 
[lkml]   [2013]   [May]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 06/11] ipc,msg: introduce msgctl_nolock
    Date
    Similar to semctl, when calling msgctl, the *_INFO and *_STAT
    commands can be performed without acquiring the ipc object.

    Add a msgctl_nolock() function and move the logic of *_INFO
    and *_STAT out of msgctl(). This change still takes the lock
    and it will be properly lockless in the next patch

    Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
    ---
    ipc/msg.c | 49 ++++++++++++++++++++++++++++++++++---------------
    1 file changed, 34 insertions(+), 15 deletions(-)

    diff --git a/ipc/msg.c b/ipc/msg.c
    index 264ebe0..20361b5 100644
    --- a/ipc/msg.c
    +++ b/ipc/msg.c
    @@ -469,17 +469,11 @@ out_up:
    return err;
    }

    -SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
    +static int msgctl_nolock(struct ipc_namespace *ns, int msqid,
    + int cmd, int version, void __user *buf)
    {
    + int err;
    struct msg_queue *msq;
    - int err, version;
    - struct ipc_namespace *ns;
    -
    - if (msqid < 0 || cmd < 0)
    - return -EINVAL;
    -
    - version = ipc_parse_version(&cmd);
    - ns = current->nsproxy->ipc_ns;

    switch (cmd) {
    case IPC_INFO:
    @@ -490,6 +484,7 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)

    if (!buf)
    return -EFAULT;
    +
    /*
    * We must not return kernel stack data.
    * due to padding, it's not enough
    @@ -521,7 +516,8 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
    return -EFAULT;
    return (max_id < 0) ? 0 : max_id;
    }
    - case MSG_STAT: /* msqid is an index rather than a msg queue id */
    +
    + case MSG_STAT:
    case IPC_STAT:
    {
    struct msqid64_ds tbuf;
    @@ -565,19 +561,42 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
    return -EFAULT;
    return success_return;
    }
    - case IPC_SET:
    - case IPC_RMID:
    - err = msgctl_down(ns, msqid, cmd, buf, version);
    - return err;
    +
    default:
    - return -EINVAL;
    + return -EINVAL;
    }

    + return err;
    out_unlock:
    msg_unlock(msq);
    return err;
    }

    +SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
    +{
    + int version;
    + struct ipc_namespace *ns;
    +
    + if (msqid < 0 || cmd < 0)
    + return -EINVAL;
    +
    + version = ipc_parse_version(&cmd);
    + ns = current->nsproxy->ipc_ns;
    +
    + switch (cmd) {
    + case IPC_INFO:
    + case MSG_INFO:
    + case MSG_STAT: /* msqid is an index rather than a msg queue id */
    + case IPC_STAT:
    + return msgctl_nolock(ns, msqid, cmd, version, buf);
    + case IPC_SET:
    + case IPC_RMID:
    + return msgctl_down(ns, msqid, cmd, buf, version);
    + default:
    + return -EINVAL;
    + }
    +}
    +
    static int testmsg(struct msg_msg *msg, long type, int mode)
    {
    switch(mode)
    --
    1.7.11.7


    \
     
     \ /
      Last update: 2013-05-16 04:01    [W:2.961 / U:0.708 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site