diff options
Diffstat (limited to 'ipc/util.c')
| -rw-r--r-- | ipc/util.c | 30 | 
1 files changed, 9 insertions, 21 deletions
diff --git a/ipc/util.c b/ipc/util.c index 74e1d9c7a98..464a8abd779 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -252,7 +252,7 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)  {  	kuid_t euid;  	kgid_t egid; -	int id, err; +	int id;  	int next_id = ids->next_id;  	if (size > IPCMNI) @@ -261,17 +261,21 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)  	if (ids->in_use >= size)  		return -ENOSPC; +	idr_preload(GFP_KERNEL); +  	spin_lock_init(&new->lock);  	new->deleted = 0;  	rcu_read_lock();  	spin_lock(&new->lock); -	err = idr_get_new_above(&ids->ipcs_idr, new, -				(next_id < 0) ? 0 : ipcid_to_idx(next_id), &id); -	if (err) { +	id = idr_alloc(&ids->ipcs_idr, new, +		       (next_id < 0) ? 0 : ipcid_to_idx(next_id), 0, +		       GFP_NOWAIT); +	idr_preload_end(); +	if (id < 0) {  		spin_unlock(&new->lock);  		rcu_read_unlock(); -		return err; +		return id;  	}  	ids->in_use++; @@ -307,19 +311,10 @@ static 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) -		return -ENOMEM;  	down_write(&ids->rw_mutex);  	err = ops->getnew(ns, params);  	up_write(&ids->rw_mutex); - -	if (err == -EAGAIN) -		goto retry; -  	return err;  } @@ -376,8 +371,6 @@ static 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);  	/*  	 * Take the lock as a writer since we are potentially going to add @@ -389,8 +382,6 @@ retry:  		/* key not used */  		if (!(flg & IPC_CREAT))  			err = -ENOENT; -		else if (!err) -			err = -ENOMEM;  		else  			err = ops->getnew(ns, params);  	} else { @@ -413,9 +404,6 @@ retry:  	}  	up_write(&ids->rw_mutex); -	if (err == -EAGAIN) -		goto retry; -  	return err;  }  |