Re: [PATCH 13/44] nfsd41: use static buffers for sessions DRC

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Jun 17, 2009 at 06:03:25PM -0400, bfields wrote:
> On Tue, Jun 16, 2009 at 04:19:49AM +0300, Benny Halevy wrote:
> > From: Andy Adamson <andros@xxxxxxxxxx>
> > 
> > Change from page based to memory based NFSv4.1 DRC.
> > 
> > We need to allocate memory for the session DRC in the CREATE_SESSION operation
> > because of the guarantee to the client that the memory resource is available
> > for caching responses.
> > 
> > In preparation to remove struct nfsd4_cache_entry, add static storage to
> > struct nfsd4_slot to hold up to NFSD_SLOT_CACH_SIZE of all encoded operation
> > data past the encoded sequence operation.
> > 
> > Signed-off-by: Andy Adamson <andros@xxxxxxxxxx>
> > Signed-off-by: Benny Halevy <bhalevy@xxxxxxxxxxx>
> > ---
> >  fs/nfsd/nfs4state.c        |    9 +++++++++
> >  fs/nfsd/nfs4xdr.c          |    1 +
> >  include/linux/nfsd/state.h |    2 ++
> >  include/linux/nfsd/xdr4.h  |    1 +
> >  4 files changed, 13 insertions(+), 0 deletions(-)
> > 
> > diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
> > index a6a7968..bf40c6b 100644
> > --- a/fs/nfsd/nfs4state.c
> > +++ b/fs/nfsd/nfs4state.c
> > @@ -1052,6 +1052,7 @@ nfsd4_copy_pages(struct page **topages, struct page **frompages, short count)
> >  void
> >  nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
> >  {
> > +	struct nfsd4_slot *slot = resp->cstate.slot;
> >  	struct nfsd4_cache_entry *entry = &resp->cstate.slot->sl_cache_entry;
> >  	struct svc_rqst *rqstp = resp->rqstp;
> >  	struct nfsd4_compoundargs *args = rqstp->rq_argp;
> > @@ -1076,10 +1077,14 @@ nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
> >  	if (nfsd4_not_cached(resp)) {
> >  		entry->ce_resused = 0;
> >  		entry->ce_rpchdrlen = 0;
> > +		slot->sl_datalen = 0;
> >  		dprintk("%s Just cache SEQUENCE. ce_cachethis %d\n", __func__,
> >  			resp->cstate.slot->sl_cache_entry.ce_cachethis);
> >  		return;
> >  	}
> > +	slot->sl_datalen = (char *)resp->p - (char *)resp->cstate.datap;
> > +	memcpy(slot->sl_data, resp->cstate.datap, slot->sl_datalen);
> 
> A response (e.g. a read) can span multiple pages, even if it's short.
> So this doesn't work.

(So: probably just write a function copy_xdr_to_buf(xdr_buf, n, p) (if
there isn't one already somewhere) that copies the first n bytes out of
an xdr buffer into a given destination buffer p.)

--b.

> 
> --b.
> 
> > +
> >  	entry->ce_resused = rqstp->rq_resused;
> >  	if (entry->ce_resused > NFSD_PAGES_PER_SLOT + 1)
> >  		entry->ce_resused = NFSD_PAGES_PER_SLOT + 1;
> > @@ -1127,6 +1132,7 @@ __be32
> >  nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
> >  			 struct nfsd4_sequence *seq)
> >  {
> > +	struct nfsd4_slot *slot = resp->cstate.slot;
> >  	struct nfsd4_cache_entry *entry = &resp->cstate.slot->sl_cache_entry;
> >  	__be32 status;
> >  
> > @@ -1147,6 +1153,9 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
> >  		return nfs_ok;
> >  	}
> >  
> > +	/* The sequence operation has been encoded, cstate->datap set. */
> > +	memcpy(resp->cstate.datap, slot->sl_data, slot->sl_datalen);
> > +
> >  	if (!nfsd41_copy_replay_data(resp, entry)) {
> >  		/*
> >  		 * Not enough room to use the replay rpc header, send the
> > diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
> > index c4eda89..7ab83cc 100644
> > --- a/fs/nfsd/nfs4xdr.c
> > +++ b/fs/nfsd/nfs4xdr.c
> > @@ -3072,6 +3072,7 @@ nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr,
> >  	WRITE32(0);
> >  
> >  	ADJUST_ARGS();
> > +	resp->cstate.datap = p;	/* DRC cache data pointer */
> >  	return 0;
> >  }
> >  
> > diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h
> > index 1ebb05e..8d5daf7 100644
> > --- a/include/linux/nfsd/state.h
> > +++ b/include/linux/nfsd/state.h
> > @@ -113,6 +113,8 @@ struct nfsd4_cache_entry {
> >  struct nfsd4_slot {
> >  	bool				sl_inuse;
> >  	u32				sl_seqid;
> > +	u32				sl_datalen;
> > +	char				sl_data[NFSD_SLOT_CACHE_SIZE];
> >  	struct nfsd4_cache_entry	sl_cache_entry;
> >  };
> >  
> > diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h
> > index 5e4beb0..5144c92 100644
> > --- a/include/linux/nfsd/xdr4.h
> > +++ b/include/linux/nfsd/xdr4.h
> > @@ -52,6 +52,7 @@ struct nfsd4_compound_state {
> >  	struct nfsd4_session	*session;
> >  	struct nfsd4_slot	*slot;
> >  	__be32			*statp;
> > +	__be32			*datap;
> >  	size_t			iovlen;
> >  	u32			minorversion;
> >  	u32			status;
> > -- 
> > 1.6.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

[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux