From 4a90157551c83332f9a7ea27c77866decf188bb7 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Wed, 29 Sep 2010 16:11:06 -0400 Subject: [PATCH] --- yaml --- r: 217256 b: refs/heads/master c: 328ead287220711c3ad4490b1f3f691855df4039 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/fs/nfsd/nfs4state.c | 49 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index 9f9e11d49bee..778756495600 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: db90681d6eff89efc1eee523e1cb77eb632a6cf7 +refs/heads/master: 328ead287220711c3ad4490b1f3f691855df4039 diff --git a/trunk/fs/nfsd/nfs4state.c b/trunk/fs/nfsd/nfs4state.c index 3b4d74cbb6c8..596702e157c9 100644 --- a/trunk/fs/nfsd/nfs4state.c +++ b/trunk/fs/nfsd/nfs4state.c @@ -658,13 +658,18 @@ static struct nfsd4_conn *alloc_conn(struct svc_rqst *rqstp) return conn; } +static void __nfsd4_hash_conn(struct nfsd4_conn *conn, struct nfsd4_session *ses) +{ + conn->cn_session = ses; + list_add(&conn->cn_persession, &ses->se_conns); +} + static void nfsd4_hash_conn(struct nfsd4_conn *conn, struct nfsd4_session *ses) { struct nfs4_client *clp = ses->se_client; spin_lock(&clp->cl_lock); - conn->cn_session = ses; - list_add(&conn->cn_persession, &ses->se_conns); + __nfsd4_hash_conn(conn, ses); spin_unlock(&clp->cl_lock); } @@ -1612,6 +1617,44 @@ nfsd4_destroy_session(struct svc_rqst *r, return status; } +static struct nfsd4_conn *__nfsd4_find_conn(struct svc_rqst *r, struct nfsd4_session *s) +{ + struct nfsd4_conn *c; + + list_for_each_entry(c, &s->se_conns, cn_persession) { + if (c->cn_xprt == r->rq_xprt) { + return c; + } + } + return NULL; +} + +static void nfsd4_sequence_check_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses) +{ + struct nfs4_client *clp = ses->se_client; + struct nfsd4_conn *c, *new = NULL; + + spin_lock(&clp->cl_lock); + c = __nfsd4_find_conn(rqstp, ses); + spin_unlock(&clp->cl_lock); + if (c) + return; + + new = alloc_conn(rqstp); + + spin_lock(&clp->cl_lock); + c = __nfsd4_find_conn(rqstp, ses); + if (c) { + spin_unlock(&clp->cl_lock); + free_conn(new); + return; + } + __nfsd4_hash_conn(new, ses); + spin_unlock(&clp->cl_lock); + nfsd4_register_conn(new); + return; +} + __be32 nfsd4_sequence(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, @@ -1656,6 +1699,8 @@ nfsd4_sequence(struct svc_rqst *rqstp, if (status) goto out; + nfsd4_sequence_check_conn(rqstp, session); + /* Success! bump slot seqid */ slot->sl_inuse = true; slot->sl_seqid = seq->seqid;