diff options
-rw-r--r-- | ipc/msg.c | 4 | ||||
-rw-r--r-- | ipc/sem.c | 4 | ||||
-rw-r--r-- | ipc/shm.c | 5 | ||||
-rw-r--r-- | ipc/util.c | 16 |
4 files changed, 18 insertions, 11 deletions
diff --git a/ipc/msg.c b/ipc/msg.c index ccf5f495db7..fdf3db5731c 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -203,10 +203,10 @@ static int newque(struct ipc_namespace *ns, struct ipc_params *params) * ipc_addid() locks msq */ id = ipc_addid(&msg_ids(ns), &msq->q_perm, ns->msg_ctlmni); - if (id == -1) { + if (id < 0) { security_msg_queue_free(msq); ipc_rcu_putref(msq); - return -ENOSPC; + return id; } msq->q_perm.id = msg_buildid(id, msq->q_perm.seq); diff --git a/ipc/sem.c b/ipc/sem.c index 7617f4f34ed..35952c0bae4 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -283,10 +283,10 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params) } id = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni); - if(id == -1) { + if (id < 0) { security_sem_free(sma); ipc_rcu_putref(sma); - return -ENOSPC; + return id; } ns->used_sems += nsems; diff --git a/ipc/shm.c b/ipc/shm.c index 05c97c7513c..3818fae625c 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -433,10 +433,11 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) if (IS_ERR(file)) goto no_file; - error = -ENOSPC; id = shm_addid(ns, shp); - if(id == -1) + if (id < 0) { + error = id; goto no_id; + } shp->shm_cprid = task_tgid_vnr(current); shp->shm_lprid = 0; diff --git a/ipc/util.c b/ipc/util.c index b42fbd58973..1aa0ebf71ba 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -262,7 +262,7 @@ int ipc_get_maxid(struct ipc_ids *ids) * Add an entry 'new' to the IPC ids idr. The permissions object is * initialised and the first free entry is set up and the id assigned * is returned. The 'new' entry is returned in a locked state on success. - * On failure the entry is not locked and -1 is returned. + * On failure the entry is not locked and a negative err-code is returned. * * Called with ipc_ids.rw_mutex held as a writer. */ @@ -275,11 +275,11 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) size = IPCMNI; if (ids->in_use >= size) - return -1; + return -ENOSPC; err = idr_get_new(&ids->ipcs_idr, new, &id); if (err) - return -1; + return err; ids->in_use++; @@ -311,7 +311,7 @@ int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids, struct ipc_ops *ops, struct ipc_params *params) { int err; - +retry: err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL); if (!err) @@ -321,6 +321,9 @@ int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids, err = ops->getnew(ns, params); up_write(&ids->rw_mutex); + if (err == -EAGAIN) + goto retry; + return err; } @@ -374,7 +377,7 @@ int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids, struct kern_ipc_perm *ipcp; int flg = params->flg; int err; - +retry: err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL); /* @@ -411,6 +414,9 @@ int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids, } up_write(&ids->rw_mutex); + if (err == -EAGAIN) + goto retry; + return err; } |