NFSD: Fix zero NFSv4 READ results when RQ_SPLICE_OK is not set
authorChuck Lever <chuck.lever@oracle.com>
Wed, 27 Sep 2023 17:16:48 +0000 (13:16 -0400)
committerChuck Lever <chuck.lever@oracle.com>
Thu, 28 Sep 2023 14:34:28 +0000 (10:34 -0400)
commit0d32a6bbb8e7bf503855f2990f1ccce0922db87b
tree9ec0ac2c208c25273505f04448b782b0a8ab862f
parent88956eabfdea7d01d550535af120d4ef265b1d02
NFSD: Fix zero NFSv4 READ results when RQ_SPLICE_OK is not set

nfsd4_encode_readv() uses xdr->buf->page_len as a starting point for
the nfsd_iter_read() sink buffer -- page_len is going to be offset
by the parts of the COMPOUND that have already been encoded into
xdr->buf->pages.

However, that value must be captured /before/
xdr_reserve_space_vec() advances page_len by the expected size of
the read payload. Otherwise, the whole front part of the first
page of the payload in the reply will be uninitialized.

Mantas hit this because sec=krb5i forces RQ_SPLICE_OK off, which
invokes the readv part of the nfsd4_encode_read() path. Also,
older Linux NFS clients appear to send shorter READ requests
for files smaller than a page, whereas newer clients just send
page-sized requests and let the server send as many bytes as
are in the file.

Reported-by: Mantas Mikulėnas <grawity@gmail.com>
Closes: https://lore.kernel.org/linux-nfs/f1d0b234-e650-0f6e-0f5d-126b3d51d1eb@gmail.com/
Fixes: 703d75215555 ("NFSD: Hoist rq_vec preparation into nfsd_read() [step two]")
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
fs/nfsd/nfs4xdr.c