From: Andy Adamson <andros@xxxxxxxxxx> CREATE_SESSION can be preceeded by a SEQUENCE operation and the create session single slot cache must be maintained. Save the results of a create session call (struct nfsd4_create_session) into the cache at the end of processing while still under the state lock. If the CREATE_SESSION operation it is preceeded by a SEQUENCE operation it will also be encoded into the session slot table cache. Errors that do not change the create session cache: A create session NFS4ERR_STALE_CLIENTID error means that a client record (and associated create session slot) could not be found and therefore can't be changed. NFSERR_SEQ_MISORDERED errors do not change the slot cache. All other errors get cached. The old method of using nfsd4_store_cache_entry() for create sessions operations will be removed in a following patch. Signed-off-by: Andy Adamson <andros@xxxxxxxxxx> --- fs/nfsd/nfs4state.c | 22 +++++++++++++++++++++- 1 files changed, 21 insertions(+), 1 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 8bf1cfa..265379e 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1334,6 +1334,20 @@ check_slot_seqid(u32 seqid, u32 slot_seqid, int slot_inuse) return nfserr_seq_misordered; } +/* + * Cache the create session result into the create session single DRC + * slot cache by saving the xdr structure. sl_seqid has been set. + * Do this for solo or embedded create session operations. + */ +static void +nfsd4_cache_create_session(struct nfsd4_create_session *cr_ses, + struct nfsd4_clid_slot *slot, int nfserr) +{ + slot->sl_status = nfserr; + memcpy(&slot->sl_cr_ses, cr_ses, sizeof(*cr_ses)); +} + + __be32 nfsd4_create_session(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, @@ -1343,6 +1357,7 @@ nfsd4_create_session(struct svc_rqst *rqstp, struct nfsd4_compoundres *resp = rqstp->rq_resp; struct nfs4_client *conf, *unconf; struct nfsd4_slot *slot = NULL; + struct nfsd4_clid_slot *cs_slot = NULL; int status = 0; nfs4_lock_state(); @@ -1371,6 +1386,7 @@ nfsd4_create_session(struct svc_rqst *rqstp, conf->cl_slot.sl_seqid++; } else if (unconf) { slot = &unconf->cl_slot; + cs_slot = &unconf->cl_cs_slot; status = check_slot_seqid(cr_ses->seqid, slot->sl_seqid, slot->sl_inuse); if (status) { @@ -1382,7 +1398,7 @@ nfsd4_create_session(struct svc_rqst *rqstp, if (!same_creds(&unconf->cl_cred, &rqstp->rq_cred) || (ip_addr != unconf->cl_addr)) { status = nfserr_clid_inuse; - goto out; + goto out_cache; } slot->sl_seqid++; /* from 0 to 1 */ @@ -1412,6 +1428,10 @@ nfsd4_create_session(struct svc_rqst *rqstp, cstate->slot = slot; /* Ensure a page is used for the cache */ slot->sl_cache_entry.ce_cachethis = 1; + +out_cache: + /* cache solo and embedded create sessions under the state lock */ + nfsd4_cache_create_session(cr_ses, cs_slot, status); out: nfs4_unlock_state(); dprintk("%s returns %d\n", __func__, ntohl(status)); -- 1.5.4.3 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html