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. 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 d2dc4c0e22e8..812e82097879 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -3446,23 +3446,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 @@ -3473,24 +3472,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; } @@ -3504,22 +3500,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)); @@ -3541,22 +3535,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)); - - 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); + xdr_truncate_encode(xdr, starting_len + 8 + ((*maxcount+3)&~3)); - 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; @@ -3567,6 +3554,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; @@ -3595,13 +3583,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.24.1