On May. 03, 2010, 15:22 +0300, "J. Bruce Fields" <bfields@xxxxxxxxxxxx> wrote: > On Mon, May 03, 2010 at 02:20:12PM +0300, Benny Halevy wrote: >> On Apr. 29, 2010, 0:31 +0300, "J. Bruce Fields" <bfields@xxxxxxxxxxxx> wrote: >>> @@ -1131,6 +1132,8 @@ encode_op: >>> fh_put(&resp->cstate.save_fh); >>> BUG_ON(resp->cstate.replay_owner); >>> out: >>> + if (resp->cstate.session) >>> + nfsd4_put_session(resp->cstate.session); >> Bruce, I see what you wanted to do but unfortunately putting the session >> here won't work since resp->cstate.slot is referred to later on in >> nfs4svc_encode_compoundres and it points into the slot table >> which is a member of the same session, therefore the current place >> in which it gets dereferenced should be maintained. > > Whoops, good catch! (Since most of the xdr encoding is done before > nfsd4_proc_compound() exits, I think I must have forgotten that > nfs4svc_encode_compoundres() is an exception?) > >> Please see below for another suggestion > > Done as you suggest. I'd applied the patch locally but not pushed it > out yet, so I've updated it in place; the result is the following. I'll > apply and push that to for-2.6.35 if you don't see any further probleme. > > --b. > > commit 44643622678d011642531915442d404ad14eb6c6 > Author: J. Bruce Fields <bfields@xxxxxxxxxxxxxx> > Date: Sat Apr 24 15:35:43 2010 -0400 > > nfsd4: fix unlikely race in session replay case > > In the replay case, the > > renew_client(session->se_client); > > happens after we've droppped the sessionid_lock, and without holding a > reference on the session; so there's nothing preventing the session > being freed before we get here. > > Thanks to Benny Halevy for catching a bug in an earlier version of this > patch. > > Signed-off-by: J. Bruce Fields <bfields@xxxxxxxxxxxxxx> Acked-by: Benny Halevy <bhalevy@xxxxxxxxxxx> > > diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c > index e147dbc..61282f8 100644 > --- a/fs/nfsd/nfs4proc.c > +++ b/fs/nfsd/nfs4proc.c > @@ -1027,6 +1027,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, > resp->rqstp = rqstp; > resp->cstate.minorversion = args->minorversion; > resp->cstate.replay_owner = NULL; > + resp->cstate.session = NULL; > fh_init(&resp->cstate.current_fh, NFS4_FHSIZE); > fh_init(&resp->cstate.save_fh, NFS4_FHSIZE); > /* Use the deferral mechanism only for NFSv4.0 compounds */ > diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c > index bba9fff..737315c 100644 > --- a/fs/nfsd/nfs4state.c > +++ b/fs/nfsd/nfs4state.c > @@ -1443,11 +1443,10 @@ nfsd4_sequence(struct svc_rqst *rqstp, > cstate->slot = slot; > cstate->session = session; > > - /* Hold a session reference until done processing the compound: > - * nfsd4_put_session called only if the cstate slot is set. > - */ > - nfsd4_get_session(session); > out: > + /* Hold a session reference until done processing the compound. */ > + if (cstate->session) > + nfsd4_get_session(cstate->session); > spin_unlock(&sessionid_lock); > /* Renew the clientid on success and on replay */ > if (cstate->session) { > diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c > index fb27b1d..05bc5bd 100644 > --- a/fs/nfsd/nfs4xdr.c > +++ b/fs/nfsd/nfs4xdr.c > @@ -3306,10 +3306,12 @@ nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compo > iov = &rqstp->rq_res.head[0]; > iov->iov_len = ((char*)resp->p) - (char*)iov->iov_base; > BUG_ON(iov->iov_len > PAGE_SIZE); > - if (nfsd4_has_session(cs) && cs->status != nfserr_replay_cache) { > - nfsd4_store_cache_entry(resp); > - dprintk("%s: SET SLOT STATE TO AVAILABLE\n", __func__); > - resp->cstate.slot->sl_inuse = false; > + if (nfsd4_has_session(cs)) { > + if (cs->status != nfserr_replay_cache) { > + nfsd4_store_cache_entry(resp); > + dprintk("%s: SET SLOT STATE TO AVAILABLE\n", __func__); > + resp->cstate.slot->sl_inuse = false; > + } > nfsd4_put_session(resp->cstate.session); > } > return 1; > -- > 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 -- 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