summaryrefslogtreecommitdiff
path: root/fs/nfs/nfs42xdr.c
diff options
context:
space:
mode:
authorFrank van der Linden <fllinden@amazon.com>2020-12-02 00:34:11 +0000
committerTrond Myklebust <trond.myklebust@hammerspace.com>2020-12-14 06:51:07 -0500
commita1f26739ccdcc6967617998bd200dd907f7ff80a (patch)
tree4f7304d98c8e71b2a039c8090453cd5f7d3655e4 /fs/nfs/nfs42xdr.c
parentac9645c87380e39a8fa87a1b51721efcdea89dbf (diff)
NFSv4.2: improve page handling for GETXATTR
XDRBUF_SPARSE_PAGES can cause problems for the RDMA transport, and it's easy enough to allocate enough pages for the request up front, so do that. Also, since we've allocated the pages anyway, use the full page aligned length for the receive buffer. This will allow caching of valid replies that are too large for the caller, but that still fit in the allocated pages. Signed-off-by: Frank van der Linden <fllinden@amazon.com> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Diffstat (limited to 'fs/nfs/nfs42xdr.c')
-rw-r--r--fs/nfs/nfs42xdr.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c
index 103978ff76c9..c0b8fcd266c9 100644
--- a/fs/nfs/nfs42xdr.c
+++ b/fs/nfs/nfs42xdr.c
@@ -489,6 +489,12 @@ static int decode_getxattr(struct xdr_stream *xdr,
return -EIO;
len = be32_to_cpup(p);
+
+ /*
+ * Only check against the page length here. The actual
+ * requested length may be smaller, but that is only
+ * checked against after possibly caching a valid reply.
+ */
if (len > req->rq_rcv_buf.page_len)
return -ERANGE;
@@ -1477,7 +1483,6 @@ static void nfs4_xdr_enc_getxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
.minorversion = nfs4_xdr_minorversion(&args->seq_args),
};
uint32_t replen;
- size_t plen;
encode_compound_hdr(xdr, req, &hdr);
encode_sequence(xdr, &args->seq_args, &hdr);
@@ -1485,10 +1490,8 @@ static void nfs4_xdr_enc_getxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
replen = hdr.replen + op_decode_hdr_maxsz + 1;
encode_getxattr(xdr, args->xattr_name, &hdr);
- plen = args->xattr_len ? args->xattr_len : XATTR_SIZE_MAX;
-
- rpc_prepare_reply_pages(req, args->xattr_pages, 0, plen, replen);
- req->rq_rcv_buf.flags |= XDRBUF_SPARSE_PAGES;
+ rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->xattr_len,
+ replen);
encode_nops(&hdr);
}