Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

NFSD: Relocate the xdr_reserve_space_vec() call site

In order to detect when a direct READ is possible, we need the send
buffer's .page_len to be zero when there is nothing in the buffer's
.pages array yet.

However, when xdr_reserve_space_vec() extends the size of the
xdr_stream to accommodate a READ payload, it adds to the send
buffer's .page_len.

It should be safe to reserve the stream space /after/ the VFS read
operation completes. This is, for example, how an NFSv3 READ works:
the VFS read goes into the rq_bvec, and is then added to the send
xdr_stream later by svcxdr_encode_opaque_pages().

Now that xdr_reserve_space_vec() uses the number of bytes actually
read, the xdr_truncate_encode() call is no longer necessary.

Reviewed-by: NeilBrown <neil@brown.name>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>

+16 -4
+16 -4
fs/nfsd/nfs4xdr.c
··· 4480 4480 __be32 zero = xdr_zero; 4481 4481 __be32 nfserr; 4482 4482 4483 - if (xdr_reserve_space_vec(xdr, maxcount) < 0) 4484 - return nfserr_resource; 4485 - 4486 4483 nfserr = nfsd_iter_read(resp->rqstp, read->rd_fhp, read->rd_nf, 4487 4484 read->rd_offset, &maxcount, base, 4488 4485 &read->rd_eof); 4489 4486 read->rd_length = maxcount; 4490 4487 if (nfserr) 4491 4488 return nfserr; 4489 + 4490 + /* 4491 + * svcxdr_encode_opaque_pages() is not used here because 4492 + * we don't want to encode subsequent results in this 4493 + * COMPOUND into the xdr->buf's tail, but rather those 4494 + * results should follow the NFS READ payload in the 4495 + * buf's pages. 4496 + */ 4497 + if (xdr_reserve_space_vec(xdr, maxcount) < 0) 4498 + return nfserr_resource; 4499 + 4500 + /* 4501 + * Mark the buffer location of the NFS READ payload so that 4502 + * direct placement-capable transports send only the 4503 + * payload bytes out-of-band. 4504 + */ 4492 4505 if (svc_encode_result_payload(resp->rqstp, starting_len, maxcount)) 4493 4506 return nfserr_io; 4494 - xdr_truncate_encode(xdr, starting_len + xdr_align_size(maxcount)); 4495 4507 4496 4508 write_bytes_to_xdr_buf(xdr->buf, starting_len + maxcount, &zero, 4497 4509 xdr_pad_size(maxcount));