diff options
Diffstat (limited to 'ipc/util.h')
-rw-r--r-- | ipc/util.h | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/ipc/util.h b/ipc/util.h index 59d78aa94987..9c47d6f6c7b4 100644 --- a/ipc/util.h +++ b/ipc/util.h | |||
@@ -15,9 +15,9 @@ | |||
15 | 15 | ||
16 | #define SEQ_MULTIPLIER (IPCMNI) | 16 | #define SEQ_MULTIPLIER (IPCMNI) |
17 | 17 | ||
18 | void sem_init (void); | 18 | void sem_init(void); |
19 | void msg_init (void); | 19 | void msg_init(void); |
20 | void shm_init (void); | 20 | void shm_init(void); |
21 | 21 | ||
22 | struct ipc_namespace; | 22 | struct ipc_namespace; |
23 | 23 | ||
@@ -100,6 +100,7 @@ void __init ipc_init_proc_interface(const char *path, const char *header, | |||
100 | 100 | ||
101 | #define ipcid_to_idx(id) ((id) % SEQ_MULTIPLIER) | 101 | #define ipcid_to_idx(id) ((id) % SEQ_MULTIPLIER) |
102 | #define ipcid_to_seqx(id) ((id) / SEQ_MULTIPLIER) | 102 | #define ipcid_to_seqx(id) ((id) / SEQ_MULTIPLIER) |
103 | #define IPCID_SEQ_MAX min_t(int, INT_MAX/SEQ_MULTIPLIER, USHRT_MAX) | ||
103 | 104 | ||
104 | /* must be called with ids->rwsem acquired for writing */ | 105 | /* must be called with ids->rwsem acquired for writing */ |
105 | int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int); | 106 | int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int); |
@@ -116,8 +117,8 @@ int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flg); | |||
116 | /* for rare, potentially huge allocations. | 117 | /* for rare, potentially huge allocations. |
117 | * both function can sleep | 118 | * both function can sleep |
118 | */ | 119 | */ |
119 | void* ipc_alloc(int size); | 120 | void *ipc_alloc(int size); |
120 | void ipc_free(void* ptr, int size); | 121 | void ipc_free(void *ptr, int size); |
121 | 122 | ||
122 | /* | 123 | /* |
123 | * For allocation that need to be freed by RCU. | 124 | * For allocation that need to be freed by RCU. |
@@ -125,7 +126,7 @@ void ipc_free(void* ptr, int size); | |||
125 | * getref increases the refcount, the putref call that reduces the recount | 126 | * getref increases the refcount, the putref call that reduces the recount |
126 | * to 0 schedules the rcu destruction. Caller must guarantee locking. | 127 | * to 0 schedules the rcu destruction. Caller must guarantee locking. |
127 | */ | 128 | */ |
128 | void* ipc_rcu_alloc(int size); | 129 | void *ipc_rcu_alloc(int size); |
129 | int ipc_rcu_getref(void *ptr); | 130 | int ipc_rcu_getref(void *ptr); |
130 | void ipc_rcu_putref(void *ptr, void (*func)(struct rcu_head *head)); | 131 | void ipc_rcu_putref(void *ptr, void (*func)(struct rcu_head *head)); |
131 | void ipc_rcu_free(struct rcu_head *head); | 132 | void ipc_rcu_free(struct rcu_head *head); |
@@ -144,7 +145,7 @@ struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns, | |||
144 | /* On IA-64, we always use the "64-bit version" of the IPC structures. */ | 145 | /* On IA-64, we always use the "64-bit version" of the IPC structures. */ |
145 | # define ipc_parse_version(cmd) IPC_64 | 146 | # define ipc_parse_version(cmd) IPC_64 |
146 | #else | 147 | #else |
147 | int ipc_parse_version (int *cmd); | 148 | int ipc_parse_version(int *cmd); |
148 | #endif | 149 | #endif |
149 | 150 | ||
150 | extern void free_msg(struct msg_msg *msg); | 151 | extern void free_msg(struct msg_msg *msg); |
@@ -185,6 +186,19 @@ static inline void ipc_unlock(struct kern_ipc_perm *perm) | |||
185 | rcu_read_unlock(); | 186 | rcu_read_unlock(); |
186 | } | 187 | } |
187 | 188 | ||
189 | /* | ||
190 | * ipc_valid_object() - helper to sort out IPC_RMID races for codepaths | ||
191 | * where the respective ipc_ids.rwsem is not being held down. | ||
192 | * Checks whether the ipc object is still around or if it's gone already, as | ||
193 | * ipc_rmid() may have already freed the ID while the ipc lock was spinning. | ||
194 | * Needs to be called with kern_ipc_perm.lock held -- exception made for one | ||
195 | * checkpoint case at sys_semtimedop() as noted in code commentary. | ||
196 | */ | ||
197 | static inline bool ipc_valid_object(struct kern_ipc_perm *perm) | ||
198 | { | ||
199 | return !perm->deleted; | ||
200 | } | ||
201 | |||
188 | struct kern_ipc_perm *ipc_obtain_object_check(struct ipc_ids *ids, int id); | 202 | struct kern_ipc_perm *ipc_obtain_object_check(struct ipc_ids *ids, int id); |
189 | int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids, | 203 | int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids, |
190 | struct ipc_ops *ops, struct ipc_params *params); | 204 | struct ipc_ops *ops, struct ipc_params *params); |