util.h 3.3 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4
/*
 * linux/ipc/util.h
 * Copyright (C) 1999 Christoph Rohland
 *
5
 * ipc helper functions (c) 1999 Manfred Spraul <manfred@colorfullife.com>
K
Kirill Korotaev 已提交
6 7
 * namespaces support.      2006 OpenVZ, SWsoft Inc.
 *                               Pavel Emelianov <xemul@openvz.org>
L
Linus Torvalds 已提交
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);

K
Kirill Korotaev 已提交
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);

L
Linus Torvalds 已提交
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;
I
Ingo Molnar 已提交
38
	struct mutex mutex;
L
Linus Torvalds 已提交
39 40 41 42
	struct ipc_id_ary nullentry;
	struct ipc_id_ary* entries;
};

43
struct seq_file;
K
Kirill Korotaev 已提交
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,
K
Kirill Korotaev 已提交
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
L
Linus Torvalds 已提交
56

K
Kirill Korotaev 已提交
57 58 59 60
#define IPC_SEM_IDS	0
#define IPC_MSG_IDS	1
#define IPC_SHM_IDS	2

I
Ingo Molnar 已提交
61
/* must be called with ids->mutex acquired.*/
L
Linus Torvalds 已提交
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);

P
Pavel Emelianov 已提交
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);
}

L
Linus Torvalds 已提交
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__)
L
Linus Torvalds 已提交
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