summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWeston Andros Adamson <dros@primarydata.com>2017-02-23 14:54:21 -0500
committerJiri Slaby <jslaby@suse.cz>2017-03-13 21:40:38 +0100
commitf4880e923d940840fd646890207c0fa749ea0864 (patch)
tree7e1715a1ae8e85c100a4b2b6f2cdacf61f801ea3
parent668a400e42817e53a203b7b7efafe9755ec4efa6 (diff)
NFSv4: fix getacl ERANGE for some ACL buffer sizes
commit ed92d8c137b7794c2c2aa14479298b9885967607 upstream. 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> Signed-off-by: J. Bruce Fields <bfields@redhat.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
-rw-r--r--fs/nfs/nfs4proc.c8
1 files changed, 2 insertions, 6 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 907d363337eb..5ffa56fd634a 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -4418,7 +4418,7 @@ out:
*/
static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
{
- struct page *pages[NFS4ACL_MAXPAGES] = {NULL, };
+ struct page *pages[NFS4ACL_MAXPAGES + 1] = {NULL, };
struct nfs_getaclargs args = {
.fh = NFS_FH(inode),
.acl_pages = pages,
@@ -4432,13 +4432,9 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
.rpc_argp = &args,
.rpc_resp = &res,
};
- unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE);
+ unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE) + 1;
int ret = -ENOMEM, i;
- /* As long as we're doing a round trip to the server anyway,
- * let's be prepared for a page of acl data. */
- if (npages == 0)
- npages = 1;
if (npages > ARRAY_SIZE(pages))
return -ERANGE;