util.h 3.33 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1 2 3 4
/*
 * linux/ipc/util.h
 * Copyright (C) 1999 Christoph Rohland
 *
5
 * ipc helper functions (c) 1999 Manfred Spraul <manfred@colorfullife.com>
6 7
 * namespaces support.      2006 OpenVZ, SWsoft Inc.
 *                               Pavel Emelianov <xemul@openvz.org>
Linus Torvalds's avatar
Linus Torvalds committed
8 9 10 11 12 13 14 15 16 17 18 19
 */

#ifndef _IPC_UTIL_H
#define _IPC_UTIL_H

#define USHRT_MAX 0xffff
#define SEQ_MULTIPLIER	(IPCMNI)

void sem_init (void);
void msg_init (void);
void shm_init (void);

20 21 22 23 24 25 26 27
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);

Linus Torvalds's avatar
Linus Torvalds committed
28 29 30 31 32 33 34 35 36 37
struct ipc_id_ary {
	int size;
	struct kern_ipc_perm *p[0];
};

struct ipc_ids {
	int in_use;
	int max_id;
	unsigned short seq;
	unsigned short seq_max;
Ingo Molnar's avatar
Ingo Molnar committed
38
	struct mutex mutex;
Linus Torvalds's avatar
Linus Torvalds committed
39 40 41 42
	struct ipc_id_ary nullentry;
	struct ipc_id_ary* entries;
};

43
struct seq_file;
44 45 46 47 48 49
#ifdef CONFIG_IPC_NS
#define __ipc_init
#else
#define __ipc_init	__init
#endif
void __ipc_init ipc_init_ids(struct ipc_ids *ids, int size);
50 51
#ifdef CONFIG_PROC_FS
void __init ipc_init_proc_interface(const char *path, const char *header,
52
		int ids, int (*show)(struct seq_file *, void *));
53 54 55
#else
#define ipc_init_proc_interface(path, header, ids, show) do {} while (0)
#endif
Linus Torvalds's avatar
Linus Torvalds committed
56

57 58 59 60
#define IPC_SEM_IDS	0
#define IPC_MSG_IDS	1
#define IPC_SHM_IDS	2

Ingo Molnar's avatar
Ingo Molnar committed
61
/* must be called with ids->mutex acquired.*/
Linus Torvalds's avatar
Linus Torvalds committed
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
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 both locks acquired. */
struct kern_ipc_perm* ipc_rmid(struct ipc_ids* ids, int id);

int ipcperms (struct kern_ipc_perm *ipcp, short flg);

/* for rare, potentially huge allocations.
 * both function can sleep
 */
void* ipc_alloc(int size);
void ipc_free(void* ptr, int size);

/*
 * For allocation that need to be freed by RCU.
 * Objects are reference counted, they start with reference count 1.
 * getref increases the refcount, the putref call that reduces the recount
 * to 0 schedules the rcu destruction. Caller must guarantee locking.
 */
void* ipc_rcu_alloc(int size);
void ipc_rcu_getref(void *ptr);
void ipc_rcu_putref(void *ptr);

86 87 88 89 90 91 92 93 94 95 96 97
static inline void __ipc_fini_ids(struct ipc_ids *ids,
		struct ipc_id_ary *entries)
{
	if (entries != &ids->nullentry)
		ipc_rcu_putref(entries);
}

static inline void ipc_fini_ids(struct ipc_ids *ids)
{
	__ipc_fini_ids(ids, ids->entries);
}

Linus Torvalds's avatar
Linus Torvalds committed
98 99 100 101 102 103 104 105 106 107
struct kern_ipc_perm* ipc_get(struct ipc_ids* ids, int id);
struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id);
void ipc_lock_by_ptr(struct kern_ipc_perm *ipcp);
void ipc_unlock(struct kern_ipc_perm* perm);
int ipc_buildid(struct ipc_ids* ids, int id, int seq);
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);

108
#if defined(__ia64__) || defined(__x86_64__) || defined(__hppa__) || defined(__XTENSA__)
Linus Torvalds's avatar
Linus Torvalds committed
109 110 111 112 113 114 115 116 117 118 119
  /* On IA-64, we always use the "64-bit version" of the IPC structures.  */ 
# define ipc_parse_version(cmd)	IPC_64
#else
int ipc_parse_version (int *cmd);
#endif

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);

#endif