NFSv4: Express delegation limit in units of pages
authorTrond Myklebust <trond.myklebust@primarydata.com>
Sat, 5 Sep 2015 23:06:57 +0000 (19:06 -0400)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Mon, 7 Sep 2015 16:36:13 +0000 (12:36 -0400)
Since we're tracking modifications to the page cache on a per-page
basis, it makes sense to express the limit to how much we may cache
in units of pages.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
fs/nfs/delegation.c
fs/nfs/delegation.h
fs/nfs/nfs4xdr.c
include/linux/nfs_xdr.h

index 029d688a969f4427e57ccf6f19b0dca9035c3d71..cd503cc2251cf2955aa0f7d5034a4334d2d3fbaa 100644 (file)
@@ -175,7 +175,7 @@ void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred,
                if (delegation->inode != NULL) {
                        nfs4_stateid_copy(&delegation->stateid, &res->delegation);
                        delegation->type = res->delegation_type;
-                       delegation->maxsize = res->maxsize;
+                       delegation->pagemod_limit = res->pagemod_limit;
                        oldcred = delegation->cred;
                        delegation->cred = get_rpccred(cred);
                        clear_bit(NFS_DELEGATION_NEED_RECLAIM,
@@ -337,7 +337,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
                return -ENOMEM;
        nfs4_stateid_copy(&delegation->stateid, &res->delegation);
        delegation->type = res->delegation_type;
-       delegation->maxsize = res->maxsize;
+       delegation->pagemod_limit = res->pagemod_limit;
        delegation->change_attr = inode->i_version;
        delegation->cred = get_rpccred(cred);
        delegation->inode = inode;
index e3c20a3ccc937453b678e9bb02d1a46827f11be0..554178a17376616be9b1bebed792e7afcea2e748 100644 (file)
@@ -18,7 +18,7 @@ struct nfs_delegation {
        struct inode *inode;
        nfs4_stateid stateid;
        fmode_t type;
-       loff_t maxsize;
+       unsigned long pagemod_limit;
        __u64 change_attr;
        unsigned long flags;
        spinlock_t lock;
index ff4784c54e04f6dab3b7e41150c5670f57af6595..788adf3897c74f2cfee16e8584807dc7ddbd127d 100644 (file)
@@ -4932,24 +4932,28 @@ static int decode_lookup(struct xdr_stream *xdr)
 }
 
 /* This is too sick! */
-static int decode_space_limit(struct xdr_stream *xdr, u64 *maxsize)
+static int decode_space_limit(struct xdr_stream *xdr,
+               unsigned long *pagemod_limit)
 {
        __be32 *p;
        uint32_t limit_type, nblocks, blocksize;
+       u64 maxsize = 0;
 
        p = xdr_inline_decode(xdr, 12);
        if (unlikely(!p))
                goto out_overflow;
        limit_type = be32_to_cpup(p++);
        switch (limit_type) {
-       case 1:
-               xdr_decode_hyper(p, maxsize);
+       case NFS4_LIMIT_SIZE:
+               xdr_decode_hyper(p, &maxsize);
                break;
-       case 2:
+       case NFS4_LIMIT_BLOCKS:
                nblocks = be32_to_cpup(p++);
                blocksize = be32_to_cpup(p);
-               *maxsize = (uint64_t)nblocks * (uint64_t)blocksize;
+               maxsize = (uint64_t)nblocks * (uint64_t)blocksize;
        }
+       maxsize >>= PAGE_CACHE_SHIFT;
+       *pagemod_limit = min_t(u64, maxsize, ULONG_MAX);
        return 0;
 out_overflow:
        print_overflow_msg(__func__, xdr);
@@ -4977,7 +4981,7 @@ static int decode_rw_delegation(struct xdr_stream *xdr,
                break;
        case NFS4_OPEN_DELEGATE_WRITE:
                res->delegation_type = FMODE_WRITE|FMODE_READ;
-               if (decode_space_limit(xdr, &res->maxsize) < 0)
+               if (decode_space_limit(xdr, &res->pagemod_limit) < 0)
                                return -EIO;
        }
        return decode_ace(xdr, NULL, res->server->nfs_client);
index b4392d86d157a36cebb78a353400baed312b6e66..52faf7e96c65db03f57777b63ce0428fac912e25 100644 (file)
@@ -406,8 +406,8 @@ struct nfs_openres {
        const struct nfs_server *server;
        fmode_t                 delegation_type;
        nfs4_stateid            delegation;
+       unsigned long           pagemod_limit;
        __u32                   do_recall;
-       __u64                   maxsize;
        __u32                   attrset[NFS4_BITMAP_SIZE];
        struct nfs4_string      *owner;
        struct nfs4_string      *group_owner;