diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-09-05 19:06:57 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-09-07 12:36:13 -0400 |
commit | 7d160a6c462c2c690e074c173b43aad7204049ad (patch) | |
tree | 6967b9cffa27592690259622031e87e27919d61b | |
parent | 4eae50143bcbfda819c650b7ed6739f3b6338ffc (diff) |
NFSv4: Express delegation limit in units of pages
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>
-rw-r--r-- | fs/nfs/delegation.c | 4 | ||||
-rw-r--r-- | fs/nfs/delegation.h | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4xdr.c | 16 | ||||
-rw-r--r-- | include/linux/nfs_xdr.h | 2 |
4 files changed, 14 insertions, 10 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 029d688a969f..cd503cc2251c 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
@@ -175,7 +175,7 @@ void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, | |||
175 | if (delegation->inode != NULL) { | 175 | if (delegation->inode != NULL) { |
176 | nfs4_stateid_copy(&delegation->stateid, &res->delegation); | 176 | nfs4_stateid_copy(&delegation->stateid, &res->delegation); |
177 | delegation->type = res->delegation_type; | 177 | delegation->type = res->delegation_type; |
178 | delegation->maxsize = res->maxsize; | 178 | delegation->pagemod_limit = res->pagemod_limit; |
179 | oldcred = delegation->cred; | 179 | oldcred = delegation->cred; |
180 | delegation->cred = get_rpccred(cred); | 180 | delegation->cred = get_rpccred(cred); |
181 | clear_bit(NFS_DELEGATION_NEED_RECLAIM, | 181 | clear_bit(NFS_DELEGATION_NEED_RECLAIM, |
@@ -337,7 +337,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct | |||
337 | return -ENOMEM; | 337 | return -ENOMEM; |
338 | nfs4_stateid_copy(&delegation->stateid, &res->delegation); | 338 | nfs4_stateid_copy(&delegation->stateid, &res->delegation); |
339 | delegation->type = res->delegation_type; | 339 | delegation->type = res->delegation_type; |
340 | delegation->maxsize = res->maxsize; | 340 | delegation->pagemod_limit = res->pagemod_limit; |
341 | delegation->change_attr = inode->i_version; | 341 | delegation->change_attr = inode->i_version; |
342 | delegation->cred = get_rpccred(cred); | 342 | delegation->cred = get_rpccred(cred); |
343 | delegation->inode = inode; | 343 | delegation->inode = inode; |
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h index e3c20a3ccc93..554178a17376 100644 --- a/fs/nfs/delegation.h +++ b/fs/nfs/delegation.h | |||
@@ -18,7 +18,7 @@ struct nfs_delegation { | |||
18 | struct inode *inode; | 18 | struct inode *inode; |
19 | nfs4_stateid stateid; | 19 | nfs4_stateid stateid; |
20 | fmode_t type; | 20 | fmode_t type; |
21 | loff_t maxsize; | 21 | unsigned long pagemod_limit; |
22 | __u64 change_attr; | 22 | __u64 change_attr; |
23 | unsigned long flags; | 23 | unsigned long flags; |
24 | spinlock_t lock; | 24 | spinlock_t lock; |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index ff4784c54e04..788adf3897c7 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -4932,24 +4932,28 @@ static int decode_lookup(struct xdr_stream *xdr) | |||
4932 | } | 4932 | } |
4933 | 4933 | ||
4934 | /* This is too sick! */ | 4934 | /* This is too sick! */ |
4935 | static int decode_space_limit(struct xdr_stream *xdr, u64 *maxsize) | 4935 | static int decode_space_limit(struct xdr_stream *xdr, |
4936 | unsigned long *pagemod_limit) | ||
4936 | { | 4937 | { |
4937 | __be32 *p; | 4938 | __be32 *p; |
4938 | uint32_t limit_type, nblocks, blocksize; | 4939 | uint32_t limit_type, nblocks, blocksize; |
4940 | u64 maxsize = 0; | ||
4939 | 4941 | ||
4940 | p = xdr_inline_decode(xdr, 12); | 4942 | p = xdr_inline_decode(xdr, 12); |
4941 | if (unlikely(!p)) | 4943 | if (unlikely(!p)) |
4942 | goto out_overflow; | 4944 | goto out_overflow; |
4943 | limit_type = be32_to_cpup(p++); | 4945 | limit_type = be32_to_cpup(p++); |
4944 | switch (limit_type) { | 4946 | switch (limit_type) { |
4945 | case 1: | 4947 | case NFS4_LIMIT_SIZE: |
4946 | xdr_decode_hyper(p, maxsize); | 4948 | xdr_decode_hyper(p, &maxsize); |
4947 | break; | 4949 | break; |
4948 | case 2: | 4950 | case NFS4_LIMIT_BLOCKS: |
4949 | nblocks = be32_to_cpup(p++); | 4951 | nblocks = be32_to_cpup(p++); |
4950 | blocksize = be32_to_cpup(p); | 4952 | blocksize = be32_to_cpup(p); |
4951 | *maxsize = (uint64_t)nblocks * (uint64_t)blocksize; | 4953 | maxsize = (uint64_t)nblocks * (uint64_t)blocksize; |
4952 | } | 4954 | } |
4955 | maxsize >>= PAGE_CACHE_SHIFT; | ||
4956 | *pagemod_limit = min_t(u64, maxsize, ULONG_MAX); | ||
4953 | return 0; | 4957 | return 0; |
4954 | out_overflow: | 4958 | out_overflow: |
4955 | print_overflow_msg(__func__, xdr); | 4959 | print_overflow_msg(__func__, xdr); |
@@ -4977,7 +4981,7 @@ static int decode_rw_delegation(struct xdr_stream *xdr, | |||
4977 | break; | 4981 | break; |
4978 | case NFS4_OPEN_DELEGATE_WRITE: | 4982 | case NFS4_OPEN_DELEGATE_WRITE: |
4979 | res->delegation_type = FMODE_WRITE|FMODE_READ; | 4983 | res->delegation_type = FMODE_WRITE|FMODE_READ; |
4980 | if (decode_space_limit(xdr, &res->maxsize) < 0) | 4984 | if (decode_space_limit(xdr, &res->pagemod_limit) < 0) |
4981 | return -EIO; | 4985 | return -EIO; |
4982 | } | 4986 | } |
4983 | return decode_ace(xdr, NULL, res->server->nfs_client); | 4987 | return decode_ace(xdr, NULL, res->server->nfs_client); |
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index b4392d86d157..52faf7e96c65 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
@@ -406,8 +406,8 @@ struct nfs_openres { | |||
406 | const struct nfs_server *server; | 406 | const struct nfs_server *server; |
407 | fmode_t delegation_type; | 407 | fmode_t delegation_type; |
408 | nfs4_stateid delegation; | 408 | nfs4_stateid delegation; |
409 | unsigned long pagemod_limit; | ||
409 | __u32 do_recall; | 410 | __u32 do_recall; |
410 | __u64 maxsize; | ||
411 | __u32 attrset[NFS4_BITMAP_SIZE]; | 411 | __u32 attrset[NFS4_BITMAP_SIZE]; |
412 | struct nfs4_string *owner; | 412 | struct nfs4_string *owner; |
413 | struct nfs4_string *group_owner; | 413 | struct nfs4_string *group_owner; |