X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=ipc%2Futil.c;h=fd1b50da9db8858793a11c0e6c503fb523280786;hb=4bbf5ebf1fdedd08d84c80a8ba011fd353d8fc5b;hp=5432b8e34c9b9506757174ba513a7c079641baab;hpb=ae5e1b22f17983da929a0d0178896269e19da186;p=linux-2.6-omap-h63xx.git diff --git a/ipc/util.c b/ipc/util.c index 5432b8e34c9..fd1b50da9db 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -248,7 +248,7 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) * This routine is called by sys_msgget, sys_semget() and sys_shmget() * when the key is IPC_PRIVATE. */ -int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids, +static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids, struct ipc_ops *ops, struct ipc_params *params) { int err; @@ -312,7 +312,7 @@ static int ipc_check_perms(struct kern_ipc_perm *ipcp, struct ipc_ops *ops, * * On success, the ipc id is returned. */ -int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids, +static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids, struct ipc_ops *ops, struct ipc_params *params) { struct kern_ipc_perm *ipcp; @@ -710,6 +710,57 @@ struct kern_ipc_perm *ipc_lock_down(struct ipc_ids *ids, int id) return out; } +struct kern_ipc_perm *ipc_lock_check_down(struct ipc_ids *ids, int id) +{ + struct kern_ipc_perm *out; + + out = ipc_lock_down(ids, id); + if (IS_ERR(out)) + return out; + + if (ipc_checkid(out, id)) { + ipc_unlock(out); + return ERR_PTR(-EIDRM); + } + + return out; +} + +struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids, int id) +{ + struct kern_ipc_perm *out; + + out = ipc_lock(ids, id); + if (IS_ERR(out)) + return out; + + if (ipc_checkid(out, id)) { + ipc_unlock(out); + return ERR_PTR(-EIDRM); + } + + return out; +} + +/** + * ipcget - Common sys_*get() code + * @ns : namsepace + * @ids : IPC identifier set + * @ops : operations to be called on ipc object creation, permission checks + * and further checks + * @params : the parameters needed by the previous operations. + * + * Common routine called by sys_msgget(), sys_semget() and sys_shmget(). + */ +int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids, + struct ipc_ops *ops, struct ipc_params *params) +{ + if (params->key == IPC_PRIVATE) + return ipcget_new(ns, ids, ops, params); + else + return ipcget_public(ns, ids, ops, params); +} + #ifdef __ARCH_WANT_IPC_PARSE_VERSION @@ -782,7 +833,7 @@ static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos) if (ipc && ipc != SEQ_START_TOKEN) ipc_unlock(ipc); - return sysvipc_find_ipc(iter->ns->ids[iface->ids], *pos, pos); + return sysvipc_find_ipc(&iter->ns->ids[iface->ids], *pos, pos); } /* @@ -795,7 +846,7 @@ static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos) struct ipc_proc_iface *iface = iter->iface; struct ipc_ids *ids; - ids = iter->ns->ids[iface->ids]; + ids = &iter->ns->ids[iface->ids]; /* * Take the lock - this will be released by the corresponding @@ -826,7 +877,7 @@ static void sysvipc_proc_stop(struct seq_file *s, void *it) if (ipc && ipc != SEQ_START_TOKEN) ipc_unlock(ipc); - ids = iter->ns->ids[iface->ids]; + ids = &iter->ns->ids[iface->ids]; /* Release the lock we took in start() */ up_read(&ids->rw_mutex); }