diff options
Diffstat (limited to 'ipc/util.c')
-rw-r--r-- | ipc/util.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/ipc/util.c b/ipc/util.c index b42fbd58973a..1aa0ebf71bac 100644 --- a/ipc/util.c +++ b/ipc/util.c | |||
@@ -262,7 +262,7 @@ int ipc_get_maxid(struct ipc_ids *ids) | |||
262 | * Add an entry 'new' to the IPC ids idr. The permissions object is | 262 | * Add an entry 'new' to the IPC ids idr. The permissions object is |
263 | * initialised and the first free entry is set up and the id assigned | 263 | * initialised and the first free entry is set up and the id assigned |
264 | * is returned. The 'new' entry is returned in a locked state on success. | 264 | * is returned. The 'new' entry is returned in a locked state on success. |
265 | * On failure the entry is not locked and -1 is returned. | 265 | * On failure the entry is not locked and a negative err-code is returned. |
266 | * | 266 | * |
267 | * Called with ipc_ids.rw_mutex held as a writer. | 267 | * Called with ipc_ids.rw_mutex held as a writer. |
268 | */ | 268 | */ |
@@ -275,11 +275,11 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) | |||
275 | size = IPCMNI; | 275 | size = IPCMNI; |
276 | 276 | ||
277 | if (ids->in_use >= size) | 277 | if (ids->in_use >= size) |
278 | return -1; | 278 | return -ENOSPC; |
279 | 279 | ||
280 | err = idr_get_new(&ids->ipcs_idr, new, &id); | 280 | err = idr_get_new(&ids->ipcs_idr, new, &id); |
281 | if (err) | 281 | if (err) |
282 | return -1; | 282 | return err; |
283 | 283 | ||
284 | ids->in_use++; | 284 | ids->in_use++; |
285 | 285 | ||
@@ -311,7 +311,7 @@ int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids, | |||
311 | struct ipc_ops *ops, struct ipc_params *params) | 311 | struct ipc_ops *ops, struct ipc_params *params) |
312 | { | 312 | { |
313 | int err; | 313 | int err; |
314 | 314 | retry: | |
315 | err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL); | 315 | err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL); |
316 | 316 | ||
317 | if (!err) | 317 | if (!err) |
@@ -321,6 +321,9 @@ int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids, | |||
321 | err = ops->getnew(ns, params); | 321 | err = ops->getnew(ns, params); |
322 | up_write(&ids->rw_mutex); | 322 | up_write(&ids->rw_mutex); |
323 | 323 | ||
324 | if (err == -EAGAIN) | ||
325 | goto retry; | ||
326 | |||
324 | return err; | 327 | return err; |
325 | } | 328 | } |
326 | 329 | ||
@@ -374,7 +377,7 @@ int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids, | |||
374 | struct kern_ipc_perm *ipcp; | 377 | struct kern_ipc_perm *ipcp; |
375 | int flg = params->flg; | 378 | int flg = params->flg; |
376 | int err; | 379 | int err; |
377 | 380 | retry: | |
378 | err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL); | 381 | err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL); |
379 | 382 | ||
380 | /* | 383 | /* |
@@ -411,6 +414,9 @@ int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids, | |||
411 | } | 414 | } |
412 | up_write(&ids->rw_mutex); | 415 | up_write(&ids->rw_mutex); |
413 | 416 | ||
417 | if (err == -EAGAIN) | ||
418 | goto retry; | ||
419 | |||
414 | return err; | 420 | return err; |
415 | } | 421 | } |
416 | 422 | ||