diff options
author | Frank van der Linden <fllinden@amazon.com> | 2020-12-02 00:34:11 +0000 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@hammerspace.com> | 2020-12-14 06:51:07 -0500 |
commit | a1f26739ccdcc6967617998bd200dd907f7ff80a (patch) | |
tree | 4f7304d98c8e71b2a039c8090453cd5f7d3655e4 /fs/nfs/nfs42xdr.c | |
parent | ac9645c87380e39a8fa87a1b51721efcdea89dbf (diff) | |
download | linux-a1f26739ccdcc6967617998bd200dd907f7ff80a.tar.bz2 |
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.c | 13 |
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); } |