]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/commitdiff
SUNRPC: Add a label for RPC calls that require allocation on receive
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Sun, 16 Sep 2018 04:08:20 +0000 (00:08 -0400)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Sun, 30 Sep 2018 19:35:16 +0000 (15:35 -0400)
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>
fs/nfs/nfs3xdr.c
include/linux/sunrpc/xdr.h
net/sunrpc/auth_gss/gss_rpc_xdr.c
net/sunrpc/socklib.c

index 64e4fa33d89f0e347155db74507862ec6f09fcc8..d8c4c10b15f7979ba221d822e63d76ba35997de6 100644 (file)
@@ -1364,10 +1364,12 @@ static void nfs3_xdr_enc_getacl3args(struct rpc_rqst *req,
 
        encode_nfs_fh3(xdr, args->fh);
        encode_uint32(xdr, args->mask);
-       if (args->mask & (NFS_ACL | NFS_DFACL))
+       if (args->mask & (NFS_ACL | NFS_DFACL)) {
                prepare_reply_buffer(req, args->pages, 0,
                                        NFSACL_MAXPAGES << PAGE_SHIFT,
                                        ACL3_getaclres_sz);
+               req->rq_rcv_buf.flags |= XDRBUF_SPARSE_PAGES;
+       }
 }
 
 static void nfs3_xdr_enc_setacl3args(struct rpc_rqst *req,
index 2bd68177a442e5402f7b015d16ac6047c14c5b0e..43182923339239b22defcd77f959d33d95d72389 100644 (file)
@@ -58,6 +58,7 @@ struct xdr_buf {
                        flags;          /* Flags for data disposition */
 #define XDRBUF_READ            0x01            /* target of file read */
 #define XDRBUF_WRITE           0x02            /* source of file write */
+#define XDRBUF_SPARSE_PAGES    0x04            /* Page array is sparse */
 
        unsigned int    buflen,         /* Total length of storage buffer */
                        len;            /* Length of XDR encoded message */
index 444380f968f1158660f6a01a10cd8223c9db6081..006062ad5f583adf07c30f13f1310ea85a3d729b 100644 (file)
@@ -784,6 +784,7 @@ void gssx_enc_accept_sec_context(struct rpc_rqst *req,
        xdr_inline_pages(&req->rq_rcv_buf,
                PAGE_SIZE/2 /* pretty arbitrary */,
                arg->pages, 0 /* page base */, arg->npages * PAGE_SIZE);
+       req->rq_rcv_buf.flags |= XDRBUF_SPARSE_PAGES;
 done:
        if (err)
                dprintk("RPC:       gssx_enc_accept_sec_context: %d\n", err);
index f217c348b34100b4cd47e4864b22cb648c4fc141..08f00a98151fd4e8517b89459c559f937298b5b8 100644 (file)
@@ -104,7 +104,7 @@ ssize_t xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base, struct
 
                /* ACL likes to be lazy in allocating pages - ACLs
                 * are small by default but can get huge. */
-               if (unlikely(*ppage == NULL)) {
+               if ((xdr->flags & XDRBUF_SPARSE_PAGES) && *ppage == NULL) {
                        *ppage = alloc_page(GFP_ATOMIC);
                        if (unlikely(*ppage == NULL)) {
                                if (copied == 0)