@@ -346,7 +346,6 @@ static void nfs4_file_put_access(struct nfs4_file *fp, int oflag)
static struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct
kmem_cache *slab)
{
- struct idr *stateids = &cl->cl_stateids;
struct nfs4_stid *stid;
int new_id;
@@ -354,7 +353,11 @@ kmem_cache *slab)
if (!stid)
return NULL;
- new_id = idr_alloc_cyclic(stateids, stid, 0, 0, GFP_KERNEL);
+ idr_preload(GFP_KERNEL);
+ spin_lock(&cl->cl_lock);
+ new_id = idr_alloc_cyclic(&cl->cl_stateids, stid, 0, 0, GFP_NOWAIT);
+ spin_unlock(&cl->cl_lock);
+ idr_preload_end();
if (new_id < 0)
goto out_free;
stid->sc_client = cl;
@@ -490,9 +493,11 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct sv
static void remove_stid(struct nfs4_stid *s)
{
- struct idr *stateids = &s->sc_client->cl_stateids;
+ struct nfs4_client *clp = s->sc_client;
- idr_remove(stateids, s->sc_stateid.si_opaque.so_id);
+ spin_lock(&clp->cl_lock);
+ idr_remove(&clp->cl_stateids, s->sc_stateid.si_opaque.so_id);
+ spin_unlock(&clp->cl_lock);
}
static void nfs4_free_stid(struct kmem_cache *slab, struct nfs4_stid *s)
@@ -1266,7 +1271,9 @@ free_client(struct nfs4_client *clp)
rpc_destroy_wait_queue(&clp->cl_cb_waitq);
free_svc_cred(&clp->cl_cred);
kfree(clp->cl_name.data);
+ spin_lock(&clp->cl_lock);
idr_destroy(&clp->cl_stateids);
+ spin_unlock(&clp->cl_lock);
kfree(clp);
}
@@ -1489,7 +1496,9 @@ static struct nfs4_stid *find_stateid(struct nfs4_client *cl, stateid_t *t)
{
struct nfs4_stid *ret;
+ spin_lock(&cl->cl_lock);
ret = idr_find(&cl->cl_stateids, t->si_opaque.so_id);
+ spin_unlock(&cl->cl_lock);
if (!ret || !ret->sc_type)
return NULL;
return ret;