diff options
author | Nadia Derbey <Nadia.Derbey@bull.net> | 2007-10-18 23:40:51 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-19 11:53:44 -0700 |
commit | 023a53557ea0e987b002e9a844242ef0b0aa1eb3 (patch) | |
tree | 7f3accdd7cb1d801607bf71e56b9b99e9c7ff7ca /ipc/msg.c | |
parent | 637c36634029e4e7c81112796dafc32d56355b4a (diff) | |
download | linux-023a53557ea0e987b002e9a844242ef0b0aa1eb3.tar.gz linux-023a53557ea0e987b002e9a844242ef0b0aa1eb3.tar.bz2 linux-023a53557ea0e987b002e9a844242ef0b0aa1eb3.zip |
ipc: integrate ipc_checkid() into ipc_lock()
This patch introduces a new ipc_lock_check() routine interface:
. each time ipc_checkid() is called, this is done after calling ipc_lock().
ipc_checkid() is now called from inside ipc_lock_check().
[akpm@linux-foundation.org: build fix]
[akpm@linux-foundation.org: fix RCU locking]
Signed-off-by: Nadia Derbey <Nadia.Derbey@bull.net>
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 | 62 |
1 files changed, 30 insertions, 32 deletions
diff --git a/ipc/msg.c b/ipc/msg.c index c2ee26f01055..74e672035675 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -73,10 +73,7 @@ static struct ipc_ids init_msg_ids; #define msg_ids(ns) (*((ns)->ids[IPC_MSG_IDS])) -#define msg_lock(ns, id) ((struct msg_queue*)ipc_lock(&msg_ids(ns), id)) #define msg_unlock(msq) ipc_unlock(&(msq)->q_perm) -#define msg_checkid(ns, msq, msgid) \ - ipc_checkid(&msg_ids(ns), &msq->q_perm, msgid) #define msg_buildid(ns, id, seq) \ ipc_buildid(&msg_ids(ns), id, seq) @@ -139,6 +136,17 @@ void __init msg_init(void) IPC_MSG_IDS, sysvipc_msg_proc_show); } +static inline struct msg_queue *msg_lock(struct ipc_namespace *ns, int id) +{ + return (struct msg_queue *) ipc_lock(&msg_ids(ns), id); +} + +static inline struct msg_queue *msg_lock_check(struct ipc_namespace *ns, + int id) +{ + return (struct msg_queue *) ipc_lock_check(&msg_ids(ns), id); +} + static inline void msg_rmid(struct ipc_namespace *ns, struct msg_queue *s) { ipc_rmid(&msg_ids(ns), &s->q_perm); @@ -445,18 +453,15 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf) if (!buf) return -EFAULT; - memset(&tbuf, 0, sizeof(tbuf)); - - msq = msg_lock(ns, msqid); - if (msq == NULL) - return -EINVAL; - if (cmd == MSG_STAT) { + msq = msg_lock(ns, msqid); + if (IS_ERR(msq)) + return PTR_ERR(msq); success_return = msq->q_perm.id; } else { - err = -EIDRM; - if (msg_checkid(ns, msq, msqid)) - goto out_unlock; + msq = msg_lock_check(ns, msqid); + if (IS_ERR(msq)) + return PTR_ERR(msq); success_return = 0; } err = -EACCES; @@ -467,6 +472,8 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf) if (err) goto out_unlock; + memset(&tbuf, 0, sizeof(tbuf)); + kernel_to_ipc64_perm(&msq->q_perm, &tbuf.msg_perm); tbuf.msg_stime = msq->q_stime; tbuf.msg_rtime = msq->q_rtime; @@ -494,14 +501,12 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf) } mutex_lock(&msg_ids(ns).mutex); - msq = msg_lock(ns, msqid); - err = -EINVAL; - if (msq == NULL) + msq = msg_lock_check(ns, msqid); + if (IS_ERR(msq)) { + err = PTR_ERR(msq); goto out_up; + } - err = -EIDRM; - if (msg_checkid(ns, msq, msqid)) - goto out_unlock_up; ipcp = &msq->q_perm; err = audit_ipc_obj(ipcp); @@ -644,14 +649,11 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext, msg->m_type = mtype; msg->m_ts = msgsz; - msq = msg_lock(ns, msqid); - err = -EINVAL; - if (msq == NULL) + msq = msg_lock_check(ns, msqid); + if (IS_ERR(msq)) { + err = PTR_ERR(msq); goto out_free; - - err= -EIDRM; - if (msg_checkid(ns, msq, msqid)) - goto out_unlock_free; + } for (;;) { struct msg_sender s; @@ -758,13 +760,9 @@ long do_msgrcv(int msqid, long *pmtype, void __user *mtext, mode = convert_mode(&msgtyp, msgflg); ns = current->nsproxy->ipc_ns; - msq = msg_lock(ns, msqid); - if (msq == NULL) - return -EINVAL; - - msg = ERR_PTR(-EIDRM); - if (msg_checkid(ns, msq, msqid)) - goto out_unlock; + msq = msg_lock_check(ns, msqid); + if (IS_ERR(msq)) + return PTR_ERR(msq); for (;;) { struct msg_receiver msr_d; |