diff options
author | Nadia Derbey <Nadia.Derbey@bull.net> | 2007-10-18 23:40:49 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-19 11:53:44 -0700 |
commit | 7748dbfaa010b12d5fb9ddf80199534c565c6bce (patch) | |
tree | c6756de4007c29fdcb405d54173a4322d48ff631 /ipc/msg.c | |
parent | 7ca7e564e049d8b350ec9d958ff25eaa24226352 (diff) | |
download | lwn-7748dbfaa010b12d5fb9ddf80199534c565c6bce.tar.gz lwn-7748dbfaa010b12d5fb9ddf80199534c565c6bce.zip |
ipc: unify the syscalls code
This patch introduces a change into the sys_msgget(), sys_semget() and
sys_shmget() routines: they now share a common code, which is better for
maintainability.
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 | 61 |
1 files changed, 17 insertions, 44 deletions
diff --git a/ipc/msg.c b/ipc/msg.c index 08591a0278ce..c2ee26f01055 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -81,7 +81,7 @@ static struct ipc_ids init_msg_ids; ipc_buildid(&msg_ids(ns), id, seq) static void freeque(struct ipc_namespace *, struct msg_queue *); -static int newque (struct ipc_namespace *ns, key_t key, int msgflg); +static int newque(struct ipc_namespace *, struct ipc_params *); #ifdef CONFIG_PROC_FS static int sysvipc_msg_proc_show(struct seq_file *s, void *it); #endif @@ -144,10 +144,12 @@ static inline void msg_rmid(struct ipc_namespace *ns, struct msg_queue *s) ipc_rmid(&msg_ids(ns), &s->q_perm); } -static int newque (struct ipc_namespace *ns, key_t key, int msgflg) +static int newque(struct ipc_namespace *ns, struct ipc_params *params) { struct msg_queue *msq; int id, retval; + key_t key = params->key; + int msgflg = params->flg; msq = ipc_rcu_alloc(sizeof(*msq)); if (!msq) @@ -264,56 +266,27 @@ static void freeque(struct ipc_namespace *ns, struct msg_queue *msq) ipc_rcu_putref(msq); } +static inline int msg_security(void *msq, int msgflg) +{ + return security_msg_queue_associate((struct msg_queue *) msq, msgflg); +} + asmlinkage long sys_msgget(key_t key, int msgflg) { - struct msg_queue *msq; - int ret; struct ipc_namespace *ns; + struct ipc_ops msg_ops; + struct ipc_params msg_params; ns = current->nsproxy->ipc_ns; - ret = idr_pre_get(&msg_ids(ns).ipcs_idr, GFP_KERNEL); + msg_ops.getnew = newque; + msg_ops.associate = msg_security; + msg_ops.more_checks = NULL; - if (key == IPC_PRIVATE) { - if (!ret) - ret = -ENOMEM; - else { - mutex_lock(&msg_ids(ns).mutex); - ret = newque(ns, key, msgflg); - mutex_unlock(&msg_ids(ns).mutex); - } - } else { - mutex_lock(&msg_ids(ns).mutex); - msq = (struct msg_queue *) ipc_findkey(&msg_ids(ns), key); - if (msq == NULL) { - /* key not used */ - if (!(msgflg & IPC_CREAT)) - ret = -ENOENT; - else if (!ret) - ret = -ENOMEM; - else - ret = newque(ns, key, msgflg); - } else { - /* msq has been locked by ipc_findkey() */ - - if (msgflg & IPC_CREAT && msgflg & IPC_EXCL) - ret = -EEXIST; - else { - if (ipcperms(&msq->q_perm, msgflg)) - ret = -EACCES; - else { - ret = security_msg_queue_associate( - msq, msgflg); - if (!ret) - ret = msq->q_perm.id; - } - } - msg_unlock(msq); - } - mutex_unlock(&msg_ids(ns).mutex); - } + msg_params.key = key; + msg_params.flg = msgflg; - return ret; + return ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params); } static inline unsigned long |