From: Tejun Heo Date: Thu, 7 Feb 2013 01:31:50 +0000 (+1100) Subject: ipc: convert to idr_alloc() X-Git-Tag: next-20130218~1^2~96 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=e2cb375312af9867614ae72f154a4b0d87ea7511;p=karo-tx-linux.git ipc: convert to idr_alloc() Convert to the much saner new idr interface. The new interface doesn't directly translate to the way idr_pre_get() was used around ipc_addid() as preloading disables preemption. From my cursory reading, it seems like we should be able to do all allocation from ipc_addid(), so I moved it there. Can you please check whether this would be okay? If this is wrong and ipc_addid() should be allowed to be called from non-sleepable context, I'd suggest allocating id itself in the outer functions and later install the pointer using idr_replace(). Only compile tested. Signed-off-by: Tejun Heo Cc: Stanislav Kinsbursky Cc: "Eric W. Biederman" Cc: James Morris Signed-off-by: Andrew Morton --- diff --git a/ipc/util.c b/ipc/util.c index 74e1d9c7a98a..91ce0bc621b5 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; } @@ -375,9 +370,7 @@ 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); + int err = 0; /* * Take the lock as a writer since we are potentially going to add @@ -413,9 +406,6 @@ retry: } up_write(&ids->rw_mutex); - if (err == -EAGAIN) - goto retry; - return err; }