ipc: unify the syscalls code
[linux-2.6.git] / ipc / util.h
index 07d689452363a6d7748bd37e1731a350ab51e42a..30b2a6d7cbed9655cf059f688670ce93122e36df 100644 (file)
@@ -2,12 +2,16 @@
  * linux/ipc/util.h
  * Copyright (C) 1999 Christoph Rohland
  *
- * ipc helper functions (c) 1999 Manfred Spraul <manfreds@colorfullife.com>
+ * ipc helper functions (c) 1999 Manfred Spraul <manfred@colorfullife.com>
+ * namespaces support.      2006 OpenVZ, SWsoft Inc.
+ *                               Pavel Emelianov <xemul@openvz.org>
  */
 
 #ifndef _IPC_UTIL_H
 #define _IPC_UTIL_H
 
+#include <linux/idr.h>
+
 #define USHRT_MAX 0xffff
 #define SEQ_MULTIPLIER (IPCMNI)
 
@@ -15,29 +19,71 @@ void sem_init (void);
 void msg_init (void);
 void shm_init (void);
 
-struct ipc_id_ary {
-       int size;
-       struct kern_ipc_perm *p[0];
-};
+int sem_init_ns(struct ipc_namespace *ns);
+int msg_init_ns(struct ipc_namespace *ns);
+int shm_init_ns(struct ipc_namespace *ns);
+
+void sem_exit_ns(struct ipc_namespace *ns);
+void msg_exit_ns(struct ipc_namespace *ns);
+void shm_exit_ns(struct ipc_namespace *ns);
 
 struct ipc_ids {
        int in_use;
-       int max_id;
        unsigned short seq;
        unsigned short seq_max;
-       struct semaphore sem;   
-       struct ipc_id_ary nullentry;
-       struct ipc_id_ary* entries;
+       struct mutex mutex;
+       struct idr ipcs_idr;
+};
+
+/*
+ * Structure that holds the parameters needed by the ipc operations
+ * (see after)
+ */
+struct ipc_params {
+       key_t key;
+       int flg;
+       union {
+               size_t size;    /* for shared memories */
+               int nsems;      /* for semaphores */
+       } u;                    /* holds the getnew() specific param */
 };
 
-void __init ipc_init_ids(struct ipc_ids* ids, int size);
+/*
+ * Structure that holds some ipc operations. This structure is used to unify
+ * the calls to sys_msgget(), sys_semget(), sys_shmget()
+ *      . routine to call to create a new ipc object. Can be one of newque,
+ *        newary, newseg
+ *      . routine to call to call to check permissions for a new ipc object.
+ *        Can be one of security_msg_associate, security_sem_associate,
+ *        security_shm_associate
+ *      . routine to call for an extra check if needed
+ */
+struct ipc_ops {
+       int (*getnew) (struct ipc_namespace *, struct ipc_params *);
+       int (*associate) (void *, int);
+       int (*more_checks) (void *, struct ipc_params *);
+};
+
+struct seq_file;
+
+void ipc_init_ids(struct ipc_ids *);
+#ifdef CONFIG_PROC_FS
+void __init ipc_init_proc_interface(const char *path, const char *header,
+               int ids, int (*show)(struct seq_file *, void *));
+#else
+#define ipc_init_proc_interface(path, header, ids, show) do {} while (0)
+#endif
+
+#define IPC_SEM_IDS    0
+#define IPC_MSG_IDS    1
+#define IPC_SHM_IDS    2
 
-/* must be called with ids->sem acquired.*/
-int ipc_findkey(struct ipc_ids* ids, key_t key);
-int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size);
+/* must be called with ids->mutex acquired.*/
+int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int);
+int ipc_get_maxid(struct ipc_ids *);
 
 /* must be called with both locks acquired. */
-struct kern_ipc_perm* ipc_rmid(struct ipc_ids* ids, int id);
+void ipc_rmid(struct ipc_ids *, struct kern_ipc_perm *);
 
 int ipcperms (struct kern_ipc_perm *ipcp, short flg);
 
@@ -67,7 +113,7 @@ int ipc_checkid(struct ipc_ids* ids, struct kern_ipc_perm* ipcp, int uid);
 void kernel_to_ipc64_perm(struct kern_ipc_perm *in, struct ipc64_perm *out);
 void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out);
 
-#if defined(__ia64__) || defined(__x86_64__) || defined(__hppa__)
+#if defined(__ia64__) || defined(__x86_64__) || defined(__hppa__) || defined(__XTENSA__)
   /* On IA-64, we always use the "64-bit version" of the IPC structures.  */ 
 # define ipc_parse_version(cmd)        IPC_64
 #else
@@ -77,5 +123,18 @@ int ipc_parse_version (int *cmd);
 extern void free_msg(struct msg_msg *msg);
 extern struct msg_msg *load_msg(const void __user *src, int len);
 extern int store_msg(void __user *dest, struct msg_msg *msg, int len);
+extern int ipcget_new(struct ipc_namespace *, struct ipc_ids *,
+                       struct ipc_ops *, struct ipc_params *);
+extern int ipcget_public(struct ipc_namespace *, struct ipc_ids *,
+                       struct ipc_ops *, struct ipc_params *);
+
+static inline 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);
+}
 
 #endif