Re: [PATCH v2 1/4] NFSD: Return eof and maxcount to nfsd4_encode_read()

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

 



On Fri, Feb 14, 2020 at 05:20:37PM -0500, Chuck Lever wrote:
> 
> 
> > On Feb 14, 2020, at 4:12 PM, schumaker.anna@xxxxxxxxx wrote:
> > 
> > From: Anna Schumaker <Anna.Schumaker@xxxxxxxxxx>
> > 
> > I want to reuse nfsd4_encode_readv() and nfsd4_encode_splice_read() in
> > READ_PLUS rather than reimplementing them. READ_PLUS returns a single
> > eof flag for the entire call and a separate maxcount for each data
> > segment, so we need to have the READ call encode these values in a
> > different place.
> 
> This probably collides pretty nastily with the fix I posted today for
> https://bugzilla.kernel.org/show_bug.cgi?id=198053 .
> 
> Can my fix go in first so that there is still opportunity to backport it?

Sure, makes sense.--b.

> 
> 
> > Signed-off-by: Anna Schumaker <Anna.Schumaker@xxxxxxxxxx>
> > ---
> > fs/nfsd/nfs4xdr.c | 60 ++++++++++++++++++++---------------------------
> > 1 file changed, 26 insertions(+), 34 deletions(-)
> > 
> > diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
> > index 9761512674a0..45f0623f6488 100644
> > --- a/fs/nfsd/nfs4xdr.c
> > +++ b/fs/nfsd/nfs4xdr.c
> > @@ -3521,23 +3521,22 @@ nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struc
> > 
> > static __be32 nfsd4_encode_splice_read(
> > 				struct nfsd4_compoundres *resp,
> > -				struct nfsd4_read *read,
> > -				struct file *file, unsigned long maxcount)
> > +				struct nfsd4_read *read, struct file *file,
> > +				unsigned long *maxcount, u32 *eof)
> > {
> > 	struct xdr_stream *xdr = &resp->xdr;
> > 	struct xdr_buf *buf = xdr->buf;
> > -	u32 eof;
> > +	long len;
> > 	int space_left;
> > 	__be32 nfserr;
> > -	__be32 *p = xdr->p - 2;
> > 
> > 	/* Make sure there will be room for padding if needed */
> > 	if (xdr->end - xdr->p < 1)
> > 		return nfserr_resource;
> > 
> > +	len = *maxcount;
> > 	nfserr = nfsd_splice_read(read->rd_rqstp, read->rd_fhp,
> > -				  file, read->rd_offset, &maxcount, &eof);
> > -	read->rd_length = maxcount;
> > +				  file, read->rd_offset, maxcount, eof);
> > 	if (nfserr) {
> > 		/*
> > 		 * nfsd_splice_actor may have already messed with the
> > @@ -3548,24 +3547,21 @@ static __be32 nfsd4_encode_splice_read(
> > 		return nfserr;
> > 	}
> > 
> > -	*(p++) = htonl(eof);
> > -	*(p++) = htonl(maxcount);
> > -
> > -	buf->page_len = maxcount;
> > -	buf->len += maxcount;
> > -	xdr->page_ptr += (buf->page_base + maxcount + PAGE_SIZE - 1)
> > +	buf->page_len = *maxcount;
> > +	buf->len += *maxcount;
> > +	xdr->page_ptr += (buf->page_base + *maxcount + PAGE_SIZE - 1)
> > 							/ PAGE_SIZE;
> > 
> > 	/* Use rest of head for padding and remaining ops: */
> > 	buf->tail[0].iov_base = xdr->p;
> > 	buf->tail[0].iov_len = 0;
> > 	xdr->iov = buf->tail;
> > -	if (maxcount&3) {
> > -		int pad = 4 - (maxcount&3);
> > +	if (*maxcount&3) {
> > +		int pad = 4 - (*maxcount&3);
> > 
> > 		*(xdr->p++) = 0;
> > 
> > -		buf->tail[0].iov_base += maxcount&3;
> > +		buf->tail[0].iov_base += *maxcount&3;
> > 		buf->tail[0].iov_len = pad;
> > 		buf->len += pad;
> > 	}
> > @@ -3579,22 +3575,20 @@ static __be32 nfsd4_encode_splice_read(
> > }
> > 
> > static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp,
> > -				 struct nfsd4_read *read,
> > -				 struct file *file, unsigned long maxcount)
> > +				 struct nfsd4_read *read, struct file *file,
> > +				 unsigned long *maxcount, u32 *eof)
> > {
> > 	struct xdr_stream *xdr = &resp->xdr;
> > -	u32 eof;
> > 	int v;
> > 	int starting_len = xdr->buf->len - 8;
> > 	long len;
> > 	int thislen;
> > 	__be32 nfserr;
> > -	__be32 tmp;
> > 	__be32 *p;
> > 	u32 zzz = 0;
> > 	int pad;
> > 
> > -	len = maxcount;
> > +	len = *maxcount;
> > 	v = 0;
> > 
> > 	thislen = min_t(long, len, ((void *)xdr->end - (void *)xdr->p));
> > @@ -3616,22 +3610,15 @@ static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp,
> > 	}
> > 	read->rd_vlen = v;
> > 
> > -	len = maxcount;
> > +	len = *maxcount;
> > 	nfserr = nfsd_readv(resp->rqstp, read->rd_fhp, file, read->rd_offset,
> > -			    resp->rqstp->rq_vec, read->rd_vlen, &maxcount,
> > -			    &eof);
> > -	read->rd_length = maxcount;
> > +			    resp->rqstp->rq_vec, read->rd_vlen, maxcount, eof);
> > 	if (nfserr)
> > 		return nfserr;
> > -	xdr_truncate_encode(xdr, starting_len + 8 + ((maxcount+3)&~3));
> > +	xdr_truncate_encode(xdr, starting_len + 8 + ((*maxcount+3)&~3));
> > 
> > -	tmp = htonl(eof);
> > -	write_bytes_to_xdr_buf(xdr->buf, starting_len    , &tmp, 4);
> > -	tmp = htonl(maxcount);
> > -	write_bytes_to_xdr_buf(xdr->buf, starting_len + 4, &tmp, 4);
> > -
> > -	pad = (maxcount&3) ? 4 - (maxcount&3) : 0;
> > -	write_bytes_to_xdr_buf(xdr->buf, starting_len + 8 + maxcount,
> > +	pad = (*maxcount&3) ? 4 - (*maxcount&3) : 0;
> > +	write_bytes_to_xdr_buf(xdr->buf, starting_len + 8 + *maxcount,
> > 								&zzz, pad);
> > 	return 0;
> > 
> > @@ -3642,6 +3629,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
> > 		  struct nfsd4_read *read)
> > {
> > 	unsigned long maxcount;
> > +	u32 eof;
> > 	struct xdr_stream *xdr = &resp->xdr;
> > 	struct file *file;
> > 	int starting_len = xdr->buf->len;
> > @@ -3670,13 +3658,17 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
> > 
> > 	if (file->f_op->splice_read &&
> > 	    test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags))
> > -		nfserr = nfsd4_encode_splice_read(resp, read, file, maxcount);
> > +		nfserr = nfsd4_encode_splice_read(resp, read, file, &maxcount, &eof);
> > 	else
> > -		nfserr = nfsd4_encode_readv(resp, read, file, maxcount);
> > +		nfserr = nfsd4_encode_readv(resp, read, file, &maxcount, &eof);
> > 
> > 	if (nfserr)
> > 		xdr_truncate_encode(xdr, starting_len);
> > 
> > +	read->rd_length = maxcount;
> > +	*p++ = htonl(eof);
> > +	*p++ = htonl(maxcount);
> > +
> > 	return nfserr;
> > }
> > 
> > -- 
> > 2.25.0
> > 
> 
> --
> Chuck Lever
> 
> 
> 




[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