diff options
author | Nadia Derbey <Nadia.Derbey@bull.net> | 2007-10-19 02:40:51 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-19 14:53:44 -0400 |
commit | 023a53557ea0e987b002e9a844242ef0b0aa1eb3 (patch) | |
tree | 7f3accdd7cb1d801607bf71e56b9b99e9c7ff7ca /ipc/msg.c | |
parent | 637c36634029e4e7c81112796dafc32d56355b4a (diff) |
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
@@ -73,10 +73,7 @@ static struct ipc_ids init_msg_ids; | |||
73 | 73 | ||
74 | #define msg_ids(ns) (*((ns)->ids[IPC_MSG_IDS])) | 74 | #define msg_ids(ns) (*((ns)->ids[IPC_MSG_IDS])) |
75 | 75 | ||
76 | #define msg_lock(ns, id) ((struct msg_queue*)ipc_lock(&msg_ids(ns), id)) | ||
77 | #define msg_unlock(msq) ipc_unlock(&(msq)->q_perm) | 76 | #define msg_unlock(msq) ipc_unlock(&(msq)->q_perm) |
78 | #define msg_checkid(ns, msq, msgid) \ | ||
79 | ipc_checkid(&msg_ids(ns), &msq->q_perm, msgid) | ||
80 | #define msg_buildid(ns, id, seq) \ | 77 | #define msg_buildid(ns, id, seq) \ |
81 | ipc_buildid(&msg_ids(ns), id, seq) | 78 | ipc_buildid(&msg_ids(ns), id, seq) |
82 | 79 | ||
@@ -139,6 +136,17 @@ void __init msg_init(void) | |||
139 | IPC_MSG_IDS, sysvipc_msg_proc_show); | 136 | IPC_MSG_IDS, sysvipc_msg_proc_show); |
140 | } | 137 | } |
141 | 138 | ||
139 | static inline struct msg_queue *msg_lock(struct ipc_namespace *ns, int id) | ||
140 | { | ||
141 | return (struct msg_queue *) ipc_lock(&msg_ids(ns), id); | ||
142 | } | ||
143 | |||
144 | static inline struct msg_queue *msg_lock_check(struct ipc_namespace *ns, | ||
145 | int id) | ||
146 | { | ||
147 | return (struct msg_queue *) ipc_lock_check(&msg_ids(ns), id); | ||
148 | } | ||
149 | |||
142 | static inline void msg_rmid(struct ipc_namespace *ns, struct msg_queue *s) | 150 | static inline void msg_rmid(struct ipc_namespace *ns, struct msg_queue *s) |
143 | { | 151 | { |
144 | ipc_rmid(&msg_ids(ns), &s->q_perm); | 152 | 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) | |||
445 | if (!buf) | 453 | if (!buf) |
446 | return -EFAULT; | 454 | return -EFAULT; |
447 | 455 | ||
448 | memset(&tbuf, 0, sizeof(tbuf)); | ||
449 | |||
450 | msq = msg_lock(ns, msqid); | ||
451 | if (msq == NULL) | ||
452 | return -EINVAL; | ||
453 | |||
454 | if (cmd == MSG_STAT) { | 456 | if (cmd == MSG_STAT) { |
457 | msq = msg_lock(ns, msqid); | ||
458 | if (IS_ERR(msq)) | ||
459 | return PTR_ERR(msq); | ||
455 | success_return = msq->q_perm.id; | 460 | success_return = msq->q_perm.id; |
456 | } else { | 461 | } else { |
457 | err = -EIDRM; | 462 | msq = msg_lock_check(ns, msqid); |
458 | if (msg_checkid(ns, msq, msqid)) | 463 | if (IS_ERR(msq)) |
459 | goto out_unlock; | 464 | return PTR_ERR(msq); |
460 | success_return = 0; | 465 | success_return = 0; |
461 | } | 466 | } |
462 | err = -EACCES; | 467 | err = -EACCES; |
@@ -467,6 +472,8 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf) | |||
467 | if (err) | 472 | if (err) |
468 | goto out_unlock; | 473 | goto out_unlock; |
469 | 474 | ||
475 | memset(&tbuf, 0, sizeof(tbuf)); | ||
476 | |||
470 | kernel_to_ipc64_perm(&msq->q_perm, &tbuf.msg_perm); | 477 | kernel_to_ipc64_perm(&msq->q_perm, &tbuf.msg_perm); |
471 | tbuf.msg_stime = msq->q_stime; | 478 | tbuf.msg_stime = msq->q_stime; |
472 | tbuf.msg_rtime = msq->q_rtime; | 479 | tbuf.msg_rtime = msq->q_rtime; |
@@ -494,14 +501,12 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf) | |||
494 | } | 501 | } |
495 | 502 | ||
496 | mutex_lock(&msg_ids(ns).mutex); | 503 | mutex_lock(&msg_ids(ns).mutex); |
497 | msq = msg_lock(ns, msqid); | 504 | msq = msg_lock_check(ns, msqid); |
498 | err = -EINVAL; | 505 | if (IS_ERR(msq)) { |
499 | if (msq == NULL) | 506 | err = PTR_ERR(msq); |
500 | goto out_up; | 507 | goto out_up; |
508 | } | ||
501 | 509 | ||
502 | err = -EIDRM; | ||
503 | if (msg_checkid(ns, msq, msqid)) | ||
504 | goto out_unlock_up; | ||
505 | ipcp = &msq->q_perm; | 510 | ipcp = &msq->q_perm; |
506 | 511 | ||
507 | err = audit_ipc_obj(ipcp); | 512 | err = audit_ipc_obj(ipcp); |
@@ -644,14 +649,11 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext, | |||
644 | msg->m_type = mtype; | 649 | msg->m_type = mtype; |
645 | msg->m_ts = msgsz; | 650 | msg->m_ts = msgsz; |
646 | 651 | ||
647 | msq = msg_lock(ns, msqid); | 652 | msq = msg_lock_check(ns, msqid); |
648 | err = -EINVAL; | 653 | if (IS_ERR(msq)) { |
649 | if (msq == NULL) | 654 | err = PTR_ERR(msq); |
650 | goto out_free; | 655 | goto out_free; |
651 | 656 | } | |
652 | err= -EIDRM; | ||
653 | if (msg_checkid(ns, msq, msqid)) | ||
654 | goto out_unlock_free; | ||
655 | 657 | ||
656 | for (;;) { | 658 | for (;;) { |
657 | struct msg_sender s; | 659 | struct msg_sender s; |
@@ -758,13 +760,9 @@ long do_msgrcv(int msqid, long *pmtype, void __user *mtext, | |||
758 | mode = convert_mode(&msgtyp, msgflg); | 760 | mode = convert_mode(&msgtyp, msgflg); |
759 | ns = current->nsproxy->ipc_ns; | 761 | ns = current->nsproxy->ipc_ns; |
760 | 762 | ||
761 | msq = msg_lock(ns, msqid); | 763 | msq = msg_lock_check(ns, msqid); |
762 | if (msq == NULL) | 764 | if (IS_ERR(msq)) |
763 | return -EINVAL; | 765 | return PTR_ERR(msq); |
764 | |||
765 | msg = ERR_PTR(-EIDRM); | ||
766 | if (msg_checkid(ns, msq, msqid)) | ||
767 | goto out_unlock; | ||
768 | 766 | ||
769 | for (;;) { | 767 | for (;;) { |
770 | struct msg_receiver msr_d; | 768 | struct msg_receiver msr_d; |