summaryrefslogtreecommitdiff
path: root/include/linux/sunrpc
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2026-05-19 09:34:22 -0400
committerChuck Lever <cel@kernel.org>2026-06-09 16:32:59 -0400
commit18c1cc69886192e33536498289d26dba6894e3d5 (patch)
treecfe9a01bad08608596e8cc87c4a36bbe0416dd33 /include/linux/sunrpc
parent42f5b80dda6b86e424054baf1475df686c403d5c (diff)
downloadlwn-18c1cc69886192e33536498289d26dba6894e3d5.tar.gz
lwn-18c1cc69886192e33536498289d26dba6894e3d5.zip
SUNRPC: Return an error from xdr_buf_to_bvec() on overflow
xdr_buf_to_bvec() returns a slot count even when the caller's bvec budget is exhausted partway through the xdr_buf. Callers feed that count into iov_iter_bvec() and continue as if the conversion had succeeded, silently sending or writing fewer bytes than the data length declares. For an NFS WRITE the server reports the truncated transfer to the client as full success. The overflow represents an internal invariant violation: a higher layer reserved a bvec budget too small for the xdr_buf it then asked the encoder to convert. That is a server-side fault, not a media I/O failure and not a malformed client argument. Change xdr_buf_to_bvec() to return a signed int and have the overflow label return -ESERVERFAULT. Update the three callers to detect the negative return and fail the request: nfsd_vfs_write() folds the error into host_err, which nfserrno() translates to nfserr_serverfault for the WRITE reply; svc_udp_sendto() and svc_tcp_sendmsg() propagate the error out of the send path. Reported-by: Chris Mason <clm@meta.com> Fixes: 2eb2b9358181 ("SUNRPC: Convert svc_tcp_sendmsg to use bio_vecs directly") Cc: stable@vger.kernel.org Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Diffstat (limited to 'include/linux/sunrpc')
-rw-r--r--include/linux/sunrpc/xdr.h4
1 files changed, 2 insertions, 2 deletions
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index 31971b01d962..b102b4f21e6b 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -138,8 +138,8 @@ void xdr_terminate_string(const struct xdr_buf *, const u32);
size_t xdr_buf_pagecount(const struct xdr_buf *buf);
int xdr_alloc_bvec(struct xdr_buf *buf, gfp_t gfp);
void xdr_free_bvec(struct xdr_buf *buf);
-unsigned int xdr_buf_to_bvec(struct bio_vec *bvec, unsigned int bvec_size,
- const struct xdr_buf *xdr);
+int xdr_buf_to_bvec(struct bio_vec *bvec, unsigned int bvec_size,
+ const struct xdr_buf *xdr);
int xdr_buf_to_sg(const struct xdr_buf *buf, unsigned int offset,
unsigned int len, struct scatterlist *sg, unsigned int nsg);
int xdr_buf_to_sg_alloc(const struct xdr_buf *buf, unsigned int offset,