On Mon, Jun 30, 2014 at 11:48:44AM -0400, Jeff Layton wrote: > @@ -2997,6 +3009,38 @@ static __be32 nfsd4_check_seqid(struct nfsd4_compound_state *cstate, struct nfs4 > return nfserr_bad_seqid; > } > > +static __be32 lookup_clientid(clientid_t *clid, > + struct nfsd4_compound_state *cstate, > + struct nfsd_net *nn) > +{ > + struct nfs4_client *found; > + > + if (cstate->clp) { > + found = cstate->clp; > + if (!same_clid(&found->cl_clientid, clid)) > + return nfserr_stale_clientid; That's new behavior, isn't it? But sending a single compound that references multiple clients sounds nuts even in the 4.0 case, OK. Applying. (And I've merged all but the delegation locking change up through here so far.) --b. > + return nfs_ok; > + } > + > + if (STALE_CLIENTID(clid, nn)) > + return nfserr_stale_clientid; > + > + /* > + * For v4.1+ we get the client in the SEQUENCE op. If we don't have one > + * cached already then we know this is for is for v4.0 and "sessions" > + * will be false. > + */ > + WARN_ON_ONCE(cstate->session); > + found = find_confirmed_client(clid, false, nn); > + if (!found) > + return nfserr_expired; > + > + /* Cache the nfs4_client in cstate! */ > + cstate->clp = found; > + atomic_inc(&found->cl_refcount); > + return nfs_ok; > +} > + > __be32 > nfsd4_process_open1(struct nfsd4_compound_state *cstate, > struct nfsd4_open *open, struct nfsd_net *nn) > @@ -3509,18 +3553,6 @@ void nfsd4_cleanup_open_state(struct nfsd4_open *open, __be32 status) > free_generic_stateid(open->op_stp); > } > > -static __be32 lookup_clientid(clientid_t *clid, bool session, struct nfsd_net *nn, struct nfs4_client **clp) > -{ > - struct nfs4_client *found; > - > - if (STALE_CLIENTID(clid, nn)) > - return nfserr_stale_clientid; > - found = find_confirmed_client(clid, session, nn); > - if (clp) > - *clp = found; > - return found ? nfs_ok : nfserr_expired; > -} > - > __be32 > nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, > clientid_t *clid) > @@ -3532,9 +3564,10 @@ nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, > nfs4_lock_state(); > dprintk("process_renew(%08x/%08x): starting\n", > clid->cl_boot, clid->cl_id); > - status = lookup_clientid(clid, cstate->minorversion, nn, &clp); > + status = lookup_clientid(clid, cstate, nn); > if (status) > goto out; > + clp = cstate->clp; > status = nfserr_cb_path_down; > if (!list_empty(&clp->cl_delegations) > && clp->cl_cb_state != NFSD4_CB_UP) > @@ -3797,22 +3830,19 @@ nfsd4_lookup_stateid(struct nfsd4_compound_state *cstate, > stateid_t *stateid, unsigned char typemask, > struct nfs4_stid **s, struct nfsd_net *nn) > { > - struct nfs4_client *cl; > __be32 status; > - bool sessions = cstate->minorversion != 0; > > if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) > return nfserr_bad_stateid; > - status = lookup_clientid(&stateid->si_opaque.so_clid, sessions, > - nn, &cl); > + status = lookup_clientid(&stateid->si_opaque.so_clid, cstate, nn); > if (status == nfserr_stale_clientid) { > - if (sessions) > + if (cstate->session) > return nfserr_bad_stateid; > return nfserr_stale_stateid; > } > if (status) > return status; > - *s = find_stateid_by_type(cl, stateid, typemask); > + *s = find_stateid_by_type(cstate->clp, stateid, typemask); > if (!*s) > return nfserr_bad_stateid; > return nfs_ok; > @@ -4662,7 +4692,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, > nfs4_lock_state(); > > if (!nfsd4_has_session(cstate)) { > - status = lookup_clientid(&lockt->lt_clientid, false, nn, NULL); > + status = lookup_clientid(&lockt->lt_clientid, cstate, nn); > if (status) > goto out; > } > @@ -4831,7 +4861,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, > > nfs4_lock_state(); > > - status = lookup_clientid(clid, cstate->minorversion, nn, NULL); > + status = lookup_clientid(clid, cstate, nn); > if (status) > goto out; > > diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h > index 7d8af164523b..312f6483a48e 100644 > --- a/fs/nfsd/xdr4.h > +++ b/fs/nfsd/xdr4.h > @@ -55,6 +55,7 @@ struct nfsd4_compound_state { > struct svc_fh current_fh; > struct svc_fh save_fh; > struct nfs4_stateowner *replay_owner; > + struct nfs4_client *clp; > /* For sessions DRC */ > struct nfsd4_session *session; > struct nfsd4_slot *slot; > -- > 1.9.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