aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@hammerspace.com>2018-09-16 00:08:20 -0400
committerTrond Myklebust <trond.myklebust@hammerspace.com>2018-09-30 15:35:16 -0400
commit431f6eb3570f286036bc8718a908a283f5d99473 (patch)
tree81117e3e64d4e6e3b847539cde5338a1e95eccca
parent79c99152a374c72c8b90c27b3d46d990641951bb (diff)
SUNRPC: Add a label for RPC calls that require allocation on receive
If the RPC call relies on the receive call allocating pages as buffers, then let's label it so that we a) Don't leak memory by allocating pages for requests that do not expect this behaviour b) Can optimise for the common case where calls do not require allocation. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
-rw-r--r--fs/nfs/nfs3xdr.c4
-rw-r--r--include/linux/sunrpc/xdr.h1
-rw-r--r--net/sunrpc/auth_gss/gss_rpc_xdr.c1
-rw-r--r--net/sunrpc/socklib.c2
4 files changed, 6 insertions, 2 deletions
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index 64e4fa33d89f..d8c4c10b15f7 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -1364,10 +1364,12 @@ static void nfs3_xdr_enc_getacl3args(struct rpc_rqst *req,
1364 1364
1365 encode_nfs_fh3(xdr, args->fh); 1365 encode_nfs_fh3(xdr, args->fh);
1366 encode_uint32(xdr, args->mask); 1366 encode_uint32(xdr, args->mask);
1367 if (args->mask & (NFS_ACL | NFS_DFACL)) 1367 if (args->mask & (NFS_ACL | NFS_DFACL)) {
1368 prepare_reply_buffer(req, args->pages, 0, 1368 prepare_reply_buffer(req, args->pages, 0,
1369 NFSACL_MAXPAGES << PAGE_SHIFT, 1369 NFSACL_MAXPAGES << PAGE_SHIFT,
1370 ACL3_getaclres_sz); 1370 ACL3_getaclres_sz);
1371 req->rq_rcv_buf.flags |= XDRBUF_SPARSE_PAGES;
1372 }
1371} 1373}
1372 1374
1373static void nfs3_xdr_enc_setacl3args(struct rpc_rqst *req, 1375static void nfs3_xdr_enc_setacl3args(struct rpc_rqst *req,
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index 2bd68177a442..431829233392 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -58,6 +58,7 @@ struct xdr_buf {
58 flags; /* Flags for data disposition */ 58 flags; /* Flags for data disposition */
59#define XDRBUF_READ 0x01 /* target of file read */ 59#define XDRBUF_READ 0x01 /* target of file read */
60#define XDRBUF_WRITE 0x02 /* source of file write */ 60#define XDRBUF_WRITE 0x02 /* source of file write */
61#define XDRBUF_SPARSE_PAGES 0x04 /* Page array is sparse */
61 62
62 unsigned int buflen, /* Total length of storage buffer */ 63 unsigned int buflen, /* Total length of storage buffer */
63 len; /* Length of XDR encoded message */ 64 len; /* Length of XDR encoded message */
diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.c b/net/sunrpc/auth_gss/gss_rpc_xdr.c
index 444380f968f1..006062ad5f58 100644
--- a/net/sunrpc/auth_gss/gss_rpc_xdr.c
+++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c
@@ -784,6 +784,7 @@ void gssx_enc_accept_sec_context(struct rpc_rqst *req,
784 xdr_inline_pages(&req->rq_rcv_buf, 784 xdr_inline_pages(&req->rq_rcv_buf,
785 PAGE_SIZE/2 /* pretty arbitrary */, 785 PAGE_SIZE/2 /* pretty arbitrary */,
786 arg->pages, 0 /* page base */, arg->npages * PAGE_SIZE); 786 arg->pages, 0 /* page base */, arg->npages * PAGE_SIZE);
787 req->rq_rcv_buf.flags |= XDRBUF_SPARSE_PAGES;
787done: 788done:
788 if (err) 789 if (err)
789 dprintk("RPC: gssx_enc_accept_sec_context: %d\n", err); 790 dprintk("RPC: gssx_enc_accept_sec_context: %d\n", err);
diff --git a/net/sunrpc/socklib.c b/net/sunrpc/socklib.c
index f217c348b341..08f00a98151f 100644
--- a/net/sunrpc/socklib.c
+++ b/net/sunrpc/socklib.c
@@ -104,7 +104,7 @@ ssize_t xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base, struct
104 104
105 /* ACL likes to be lazy in allocating pages - ACLs 105 /* ACL likes to be lazy in allocating pages - ACLs
106 * are small by default but can get huge. */ 106 * are small by default but can get huge. */
107 if (unlikely(*ppage == NULL)) { 107 if ((xdr->flags & XDRBUF_SPARSE_PAGES) && *ppage == NULL) {
108 *ppage = alloc_page(GFP_ATOMIC); 108 *ppage = alloc_page(GFP_ATOMIC);
109 if (unlikely(*ppage == NULL)) { 109 if (unlikely(*ppage == NULL)) {
110 if (copied == 0) 110 if (copied == 0)