[IA64] VIRT_CPU_ACCOUNTING (accurate cpu time accounting)
[safe/jmp/linux-2.6] / ipc / util.c
index 5432b8e..fd1b50d 100644 (file)
@@ -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);
 }