diff options
author | Weston Andros Adamson <dros@primarydata.com> | 2017-02-23 14:54:21 -0500 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2017-02-23 17:23:35 -0500 |
commit | ed92d8c137b7794c2c2aa14479298b9885967607 (patch) | |
tree | 924e5d4092eda8992f4328d06c2478d382310974 | |
parent | 6682c14bbe505a8b912c57faf544f866777ee48d (diff) |
NFSv4: fix getacl ERANGE for some ACL buffer sizes
We're not taking into account that the space needed for the (variable
length) attr bitmap, with the result that we'd sometimes get a spurious
ERANGE when the ACL data got close to the end of a page.
Just add in an extra page to make sure.
Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
Cc: stable@vger.kernel.org
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
-rw-r--r-- | fs/nfs/nfs4proc.c | 8 |
1 files changed, 2 insertions, 6 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 92b2805ffb82..1b183686c6d4 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -4954,7 +4954,7 @@ out: | |||
4954 | */ | 4954 | */ |
4955 | static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen) | 4955 | static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen) |
4956 | { | 4956 | { |
4957 | struct page *pages[NFS4ACL_MAXPAGES] = {NULL, }; | 4957 | struct page *pages[NFS4ACL_MAXPAGES + 1] = {NULL, }; |
4958 | struct nfs_getaclargs args = { | 4958 | struct nfs_getaclargs args = { |
4959 | .fh = NFS_FH(inode), | 4959 | .fh = NFS_FH(inode), |
4960 | .acl_pages = pages, | 4960 | .acl_pages = pages, |
@@ -4968,13 +4968,9 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu | |||
4968 | .rpc_argp = &args, | 4968 | .rpc_argp = &args, |
4969 | .rpc_resp = &res, | 4969 | .rpc_resp = &res, |
4970 | }; | 4970 | }; |
4971 | unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE); | 4971 | unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE) + 1; |
4972 | int ret = -ENOMEM, i; | 4972 | int ret = -ENOMEM, i; |
4973 | 4973 | ||
4974 | /* As long as we're doing a round trip to the server anyway, | ||
4975 | * let's be prepared for a page of acl data. */ | ||
4976 | if (npages == 0) | ||
4977 | npages = 1; | ||
4978 | if (npages > ARRAY_SIZE(pages)) | 4974 | if (npages > ARRAY_SIZE(pages)) |
4979 | return -ERANGE; | 4975 | return -ERANGE; |
4980 | 4976 | ||