aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4xdr.c
diff options
context:
space:
mode:
authorBenjamin Coddington <bcodding@redhat.com>2016-03-22 10:28:36 -0400
committerJ. Bruce Fields <bfields@redhat.com>2016-03-23 16:02:39 -0400
commitac503e4a309a3993a069750f95c2815ee5db5aa5 (patch)
treeb96495be6e8e44829db04073c6263ac43ac97a05 /fs/nfsd/nfs4xdr.c
parent4b15da44e742871206582f6aa2997b009648f02f (diff)
nfsd: use short read as well as i_size to set eof
Use the result of a local read to determine when to set the eof flag. This allows us to return the location of the end of the file atomically at the time of the read. Signed-off-by: Benjamin Coddington <bcodding@redhat.com> [bfields: add some documentation] Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4xdr.c')
-rw-r--r--fs/nfsd/nfs4xdr.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index aa87954b4af2..9df898ba648f 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -3365,6 +3365,7 @@ static __be32 nfsd4_encode_splice_read(
3365 struct xdr_stream *xdr = &resp->xdr; 3365 struct xdr_stream *xdr = &resp->xdr;
3366 struct xdr_buf *buf = xdr->buf; 3366 struct xdr_buf *buf = xdr->buf;
3367 u32 eof; 3367 u32 eof;
3368 long len;
3368 int space_left; 3369 int space_left;
3369 __be32 nfserr; 3370 __be32 nfserr;
3370 __be32 *p = xdr->p - 2; 3371 __be32 *p = xdr->p - 2;
@@ -3373,6 +3374,7 @@ static __be32 nfsd4_encode_splice_read(
3373 if (xdr->end - xdr->p < 1) 3374 if (xdr->end - xdr->p < 1)
3374 return nfserr_resource; 3375 return nfserr_resource;
3375 3376
3377 len = maxcount;
3376 nfserr = nfsd_splice_read(read->rd_rqstp, file, 3378 nfserr = nfsd_splice_read(read->rd_rqstp, file,
3377 read->rd_offset, &maxcount); 3379 read->rd_offset, &maxcount);
3378 if (nfserr) { 3380 if (nfserr) {
@@ -3385,8 +3387,8 @@ static __be32 nfsd4_encode_splice_read(
3385 return nfserr; 3387 return nfserr;
3386 } 3388 }
3387 3389
3388 eof = (read->rd_offset + maxcount >= 3390 eof = nfsd_eof_on_read(len, maxcount, read->rd_offset,
3389 d_inode(read->rd_fhp->fh_dentry)->i_size); 3391 d_inode(read->rd_fhp->fh_dentry)->i_size);
3390 3392
3391 *(p++) = htonl(eof); 3393 *(p++) = htonl(eof);
3392 *(p++) = htonl(maxcount); 3394 *(p++) = htonl(maxcount);
@@ -3456,14 +3458,15 @@ static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp,
3456 } 3458 }
3457 read->rd_vlen = v; 3459 read->rd_vlen = v;
3458 3460
3461 len = maxcount;
3459 nfserr = nfsd_readv(file, read->rd_offset, resp->rqstp->rq_vec, 3462 nfserr = nfsd_readv(file, read->rd_offset, resp->rqstp->rq_vec,
3460 read->rd_vlen, &maxcount); 3463 read->rd_vlen, &maxcount);
3461 if (nfserr) 3464 if (nfserr)
3462 return nfserr; 3465 return nfserr;
3463 xdr_truncate_encode(xdr, starting_len + 8 + ((maxcount+3)&~3)); 3466 xdr_truncate_encode(xdr, starting_len + 8 + ((maxcount+3)&~3));
3464 3467
3465 eof = (read->rd_offset + maxcount >= 3468 eof = nfsd_eof_on_read(len, maxcount, read->rd_offset,
3466 d_inode(read->rd_fhp->fh_dentry)->i_size); 3469 d_inode(read->rd_fhp->fh_dentry)->i_size);
3467 3470
3468 tmp = htonl(eof); 3471 tmp = htonl(eof);
3469 write_bytes_to_xdr_buf(xdr->buf, starting_len , &tmp, 4); 3472 write_bytes_to_xdr_buf(xdr->buf, starting_len , &tmp, 4);