Re: [PATCH v5 39/39] nfs: Add support for the v4.1 dacl attribute

2015-07-22 Thread Andreas Grünbacher
Hi Anna,

2015-07-22 17:57 GMT+02:00 Anna Schumaker :
> Discussions around deprecating or removing the minorversion= argument have 
> come up recently.
> The preferred way of mounting NFS v4.1 these days is with: "-o vers=4.1".  
> Can you update your
> patch description so we don't confuse people? :)

sure, that was easy :)

Thanks,
Andreas
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v5 39/39] nfs: Add support for the v4.1 dacl attribute

2015-07-22 Thread Anna Schumaker
Hi Andreas,

On 07/22/2015 09:03 AM, Andreas Gruenbacher wrote:
> From: Andreas Gruenbacher 
> 
> The dacl attribute includes Automatic Inheritance flags not supported by the
> acl attribute.  it is only supported in NFS version 4.1 and higher.  On 
> systems
> where NFS version 4.0 is still the default, an additional mount option is
> needed:
> 
> mount -t nfs4 -o minorversion=1 [...]

Discussions around deprecating or removing the minorversion= argument have come 
up recently.  The preferred way of mounting NFS v4.1 these days is with: "-o 
vers=4.1".  Can you update your patch description so we don't confuse people? :)

Thanks,
Anna

> 
> Signed-off-by: Andreas Gruenbacher 
> ---
>  fs/nfs/nfs4proc.c   |  2 +-
>  fs/nfs/nfs4xdr.c| 55 
> ++---
>  include/linux/nfs_xdr.h |  2 +-
>  3 files changed, 50 insertions(+), 9 deletions(-)
> 
> diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
> index 5ba49c3..39f5548 100644
> --- a/fs/nfs/nfs4proc.c
> +++ b/fs/nfs/nfs4proc.c
> @@ -4469,7 +4469,7 @@ static struct richacl *__nfs4_get_acl_uncached(struct 
> inode *inode)
>   struct nfs_server *server = NFS_SERVER(inode);
>   struct page *pages[DIV_ROUND_UP(NFS4ACL_SIZE_MAX, PAGE_SIZE)] = {};
>   struct nfs_getaclargs args = {
> - .fh = NFS_FH(inode),
> + .inode = inode,
>   .acl_pages = pages,
>   .acl_len = ARRAY_SIZE(pages) * PAGE_SIZE,
>   };
> diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
> index 85270df..06f5759 100644
> --- a/fs/nfs/nfs4xdr.c
> +++ b/fs/nfs/nfs4xdr.c
> @@ -1649,9 +1649,16 @@ encode_setacl(struct xdr_stream *xdr, struct 
> nfs_setaclargs *arg, struct compoun
>   encode_nfs4_stateid(xdr, _stateid);
>  
>   /* Encode attribute bitmap. */
> - p = reserve_space(xdr, 2*4);
> - *p++ = cpu_to_be32(1);
> - *p = cpu_to_be32(FATTR4_WORD0_ACL);
> + if (arg->server->attr_bitmask[1] & FATTR4_WORD1_DACL) {
> + p = reserve_space(xdr, 3*4);
> + *p++ = cpu_to_be32(2);
> + *p++ = 0;
> + *p = cpu_to_be32(FATTR4_WORD1_DACL);
> + } else {
> + p = reserve_space(xdr, 2*4);
> + *p++ = cpu_to_be32(1);
> + *p = cpu_to_be32(FATTR4_WORD0_ACL);
> + }
>  
>   attrlen_offset = xdr->buf->len;
>   xdr_reserve_space(xdr, 4);  /* to be backfilled later */
> @@ -2486,9 +2493,12 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, 
> struct xdr_stream *xdr,
>  
>   encode_compound_hdr(xdr, req, );
>   encode_sequence(xdr, >seq_args, );
> - encode_putfh(xdr, args->fh, );
> + encode_putfh(xdr, NFS_FH(args->inode), );
>   replen = hdr.replen + op_decode_hdr_maxsz + 1;
> - encode_getattr_two(xdr, FATTR4_WORD0_ACL, FATTR4_WORD1_MODE, );
> + if (NFS_SERVER(args->inode)->attr_bitmask[1] & FATTR4_WORD1_DACL)
> + encode_getattr_two(xdr, 0, FATTR4_WORD1_MODE | 
> FATTR4_WORD1_DACL, );
> + else
> + encode_getattr_two(xdr, FATTR4_WORD0_ACL, FATTR4_WORD1_MODE, 
> );
>  
>   xdr_inline_pages(>rq_rcv_buf, replen << 2,
>   args->acl_pages, 0, args->acl_len);
> @@ -5376,14 +5386,28 @@ static int decode_getacl(struct xdr_stream *xdr, 
> struct rpc_rqst *req,
>  
>   if (unlikely(bitmap[0] & (FATTR4_WORD0_ACL - 1U)))
>   return -EIO;
> - if (likely(bitmap[0] & FATTR4_WORD0_ACL)) {
> +
> + if (bitmap[0] & FATTR4_WORD0_ACL) {
> + struct richace *ace;
> +
> + if (bitmap[1] & FATTR4_WORD1_DACL)
> + return -EIO;
> +
>   acl = decode_acl_entries(xdr, res->server);
>   status = PTR_ERR(acl);
>   if (IS_ERR(acl))
>   goto out;
> +
> + status = -EIO;
> + richacl_for_each_entry(ace, acl) {
> + if (ace->e_flags & RICHACE_INHERITED_ACE)
> + goto out;
> + }
>   bitmap[0] &= ~FATTR4_WORD0_ACL;
> - } else
> + } else if (!(bitmap[1] & FATTR4_WORD1_DACL)) {
>   status = -EOPNOTSUPP;
> + goto out;
> + }
>  
>   status = -EIO;
>   if (unlikely(bitmap[0]))
> @@ -5391,6 +5415,23 @@ static int decode_getacl(struct xdr_stream *xdr, 
> struct rpc_rqst *req,
>  
>   if ((status = decode_attr_mode(xdr, bitmap, >mode)) < 0)
>   goto out;
> + if (bitmap[1] & FATTR4_WORD1_DACL) {
> + unsigned int flags;
> + __be32 *p;
> +
> + p = xdr_inline_decode(xdr, 4);
> +status = -EIO;
> +if (unlikely(!p))
> +goto out;
> +flags = be32_to_cpup(p);
> +
> + acl = decode_acl_entries(xdr, res->server);
> + status = PTR_ERR(acl);
> + if (IS_ERR(acl))
> + goto out;
> + acl->a_flags = flags;
> + bitmap[1] &= 

[PATCH v5 39/39] nfs: Add support for the v4.1 dacl attribute

2015-07-22 Thread Andreas Gruenbacher
From: Andreas Gruenbacher 

The dacl attribute includes Automatic Inheritance flags not supported by the
acl attribute.  it is only supported in NFS version 4.1 and higher.  On systems
where NFS version 4.0 is still the default, an additional mount option is
needed:

mount -t nfs4 -o minorversion=1 [...]

Signed-off-by: Andreas Gruenbacher 
---
 fs/nfs/nfs4proc.c   |  2 +-
 fs/nfs/nfs4xdr.c| 55 ++---
 include/linux/nfs_xdr.h |  2 +-
 3 files changed, 50 insertions(+), 9 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 5ba49c3..39f5548 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -4469,7 +4469,7 @@ static struct richacl *__nfs4_get_acl_uncached(struct 
inode *inode)
struct nfs_server *server = NFS_SERVER(inode);
struct page *pages[DIV_ROUND_UP(NFS4ACL_SIZE_MAX, PAGE_SIZE)] = {};
struct nfs_getaclargs args = {
-   .fh = NFS_FH(inode),
+   .inode = inode,
.acl_pages = pages,
.acl_len = ARRAY_SIZE(pages) * PAGE_SIZE,
};
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 85270df..06f5759 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -1649,9 +1649,16 @@ encode_setacl(struct xdr_stream *xdr, struct 
nfs_setaclargs *arg, struct compoun
encode_nfs4_stateid(xdr, _stateid);
 
/* Encode attribute bitmap. */
-   p = reserve_space(xdr, 2*4);
-   *p++ = cpu_to_be32(1);
-   *p = cpu_to_be32(FATTR4_WORD0_ACL);
+   if (arg->server->attr_bitmask[1] & FATTR4_WORD1_DACL) {
+   p = reserve_space(xdr, 3*4);
+   *p++ = cpu_to_be32(2);
+   *p++ = 0;
+   *p = cpu_to_be32(FATTR4_WORD1_DACL);
+   } else {
+   p = reserve_space(xdr, 2*4);
+   *p++ = cpu_to_be32(1);
+   *p = cpu_to_be32(FATTR4_WORD0_ACL);
+   }
 
attrlen_offset = xdr->buf->len;
xdr_reserve_space(xdr, 4);  /* to be backfilled later */
@@ -2486,9 +2493,12 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, 
struct xdr_stream *xdr,
 
encode_compound_hdr(xdr, req, );
encode_sequence(xdr, >seq_args, );
-   encode_putfh(xdr, args->fh, );
+   encode_putfh(xdr, NFS_FH(args->inode), );
replen = hdr.replen + op_decode_hdr_maxsz + 1;
-   encode_getattr_two(xdr, FATTR4_WORD0_ACL, FATTR4_WORD1_MODE, );
+   if (NFS_SERVER(args->inode)->attr_bitmask[1] & FATTR4_WORD1_DACL)
+   encode_getattr_two(xdr, 0, FATTR4_WORD1_MODE | 
FATTR4_WORD1_DACL, );
+   else
+   encode_getattr_two(xdr, FATTR4_WORD0_ACL, FATTR4_WORD1_MODE, 
);
 
xdr_inline_pages(>rq_rcv_buf, replen << 2,
args->acl_pages, 0, args->acl_len);
@@ -5376,14 +5386,28 @@ static int decode_getacl(struct xdr_stream *xdr, struct 
rpc_rqst *req,
 
if (unlikely(bitmap[0] & (FATTR4_WORD0_ACL - 1U)))
return -EIO;
-   if (likely(bitmap[0] & FATTR4_WORD0_ACL)) {
+
+   if (bitmap[0] & FATTR4_WORD0_ACL) {
+   struct richace *ace;
+
+   if (bitmap[1] & FATTR4_WORD1_DACL)
+   return -EIO;
+
acl = decode_acl_entries(xdr, res->server);
status = PTR_ERR(acl);
if (IS_ERR(acl))
goto out;
+
+   status = -EIO;
+   richacl_for_each_entry(ace, acl) {
+   if (ace->e_flags & RICHACE_INHERITED_ACE)
+   goto out;
+   }
bitmap[0] &= ~FATTR4_WORD0_ACL;
-   } else
+   } else if (!(bitmap[1] & FATTR4_WORD1_DACL)) {
status = -EOPNOTSUPP;
+   goto out;
+   }
 
status = -EIO;
if (unlikely(bitmap[0]))
@@ -5391,6 +5415,23 @@ static int decode_getacl(struct xdr_stream *xdr, struct 
rpc_rqst *req,
 
if ((status = decode_attr_mode(xdr, bitmap, >mode)) < 0)
goto out;
+   if (bitmap[1] & FATTR4_WORD1_DACL) {
+   unsigned int flags;
+   __be32 *p;
+
+   p = xdr_inline_decode(xdr, 4);
+status = -EIO;
+if (unlikely(!p))
+goto out;
+flags = be32_to_cpup(p);
+
+   acl = decode_acl_entries(xdr, res->server);
+   status = PTR_ERR(acl);
+   if (IS_ERR(acl))
+   goto out;
+   acl->a_flags = flags;
+   bitmap[1] &= ~FATTR4_WORD1_DACL;
+   }
status = 0;
 
 out:
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index f1c8f93..abe0b66 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -695,7 +695,7 @@ struct nfs_setaclres {
 
 struct nfs_getaclargs {
struct nfs4_sequence_args   seq_args;
-   struct nfs_fh * fh;
+   struct inode *  inode;

Re: [PATCH v5 39/39] nfs: Add support for the v4.1 dacl attribute

2015-07-22 Thread Andreas Grünbacher
Hi Anna,

2015-07-22 17:57 GMT+02:00 Anna Schumaker anna.schuma...@netapp.com:
 Discussions around deprecating or removing the minorversion= argument have 
 come up recently.
 The preferred way of mounting NFS v4.1 these days is with: -o vers=4.1.  
 Can you update your
 patch description so we don't confuse people? :)

sure, that was easy :)

Thanks,
Andreas
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v5 39/39] nfs: Add support for the v4.1 dacl attribute

2015-07-22 Thread Anna Schumaker
Hi Andreas,

On 07/22/2015 09:03 AM, Andreas Gruenbacher wrote:
 From: Andreas Gruenbacher agrue...@redhat.com
 
 The dacl attribute includes Automatic Inheritance flags not supported by the
 acl attribute.  it is only supported in NFS version 4.1 and higher.  On 
 systems
 where NFS version 4.0 is still the default, an additional mount option is
 needed:
 
 mount -t nfs4 -o minorversion=1 [...]

Discussions around deprecating or removing the minorversion= argument have come 
up recently.  The preferred way of mounting NFS v4.1 these days is with: -o 
vers=4.1.  Can you update your patch description so we don't confuse people? :)

Thanks,
Anna

 
 Signed-off-by: Andreas Gruenbacher agrue...@redhat.com
 ---
  fs/nfs/nfs4proc.c   |  2 +-
  fs/nfs/nfs4xdr.c| 55 
 ++---
  include/linux/nfs_xdr.h |  2 +-
  3 files changed, 50 insertions(+), 9 deletions(-)
 
 diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
 index 5ba49c3..39f5548 100644
 --- a/fs/nfs/nfs4proc.c
 +++ b/fs/nfs/nfs4proc.c
 @@ -4469,7 +4469,7 @@ static struct richacl *__nfs4_get_acl_uncached(struct 
 inode *inode)
   struct nfs_server *server = NFS_SERVER(inode);
   struct page *pages[DIV_ROUND_UP(NFS4ACL_SIZE_MAX, PAGE_SIZE)] = {};
   struct nfs_getaclargs args = {
 - .fh = NFS_FH(inode),
 + .inode = inode,
   .acl_pages = pages,
   .acl_len = ARRAY_SIZE(pages) * PAGE_SIZE,
   };
 diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
 index 85270df..06f5759 100644
 --- a/fs/nfs/nfs4xdr.c
 +++ b/fs/nfs/nfs4xdr.c
 @@ -1649,9 +1649,16 @@ encode_setacl(struct xdr_stream *xdr, struct 
 nfs_setaclargs *arg, struct compoun
   encode_nfs4_stateid(xdr, zero_stateid);
  
   /* Encode attribute bitmap. */
 - p = reserve_space(xdr, 2*4);
 - *p++ = cpu_to_be32(1);
 - *p = cpu_to_be32(FATTR4_WORD0_ACL);
 + if (arg-server-attr_bitmask[1]  FATTR4_WORD1_DACL) {
 + p = reserve_space(xdr, 3*4);
 + *p++ = cpu_to_be32(2);
 + *p++ = 0;
 + *p = cpu_to_be32(FATTR4_WORD1_DACL);
 + } else {
 + p = reserve_space(xdr, 2*4);
 + *p++ = cpu_to_be32(1);
 + *p = cpu_to_be32(FATTR4_WORD0_ACL);
 + }
  
   attrlen_offset = xdr-buf-len;
   xdr_reserve_space(xdr, 4);  /* to be backfilled later */
 @@ -2486,9 +2493,12 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, 
 struct xdr_stream *xdr,
  
   encode_compound_hdr(xdr, req, hdr);
   encode_sequence(xdr, args-seq_args, hdr);
 - encode_putfh(xdr, args-fh, hdr);
 + encode_putfh(xdr, NFS_FH(args-inode), hdr);
   replen = hdr.replen + op_decode_hdr_maxsz + 1;
 - encode_getattr_two(xdr, FATTR4_WORD0_ACL, FATTR4_WORD1_MODE, hdr);
 + if (NFS_SERVER(args-inode)-attr_bitmask[1]  FATTR4_WORD1_DACL)
 + encode_getattr_two(xdr, 0, FATTR4_WORD1_MODE | 
 FATTR4_WORD1_DACL, hdr);
 + else
 + encode_getattr_two(xdr, FATTR4_WORD0_ACL, FATTR4_WORD1_MODE, 
 hdr);
  
   xdr_inline_pages(req-rq_rcv_buf, replen  2,
   args-acl_pages, 0, args-acl_len);
 @@ -5376,14 +5386,28 @@ static int decode_getacl(struct xdr_stream *xdr, 
 struct rpc_rqst *req,
  
   if (unlikely(bitmap[0]  (FATTR4_WORD0_ACL - 1U)))
   return -EIO;
 - if (likely(bitmap[0]  FATTR4_WORD0_ACL)) {
 +
 + if (bitmap[0]  FATTR4_WORD0_ACL) {
 + struct richace *ace;
 +
 + if (bitmap[1]  FATTR4_WORD1_DACL)
 + return -EIO;
 +
   acl = decode_acl_entries(xdr, res-server);
   status = PTR_ERR(acl);
   if (IS_ERR(acl))
   goto out;
 +
 + status = -EIO;
 + richacl_for_each_entry(ace, acl) {
 + if (ace-e_flags  RICHACE_INHERITED_ACE)
 + goto out;
 + }
   bitmap[0] = ~FATTR4_WORD0_ACL;
 - } else
 + } else if (!(bitmap[1]  FATTR4_WORD1_DACL)) {
   status = -EOPNOTSUPP;
 + goto out;
 + }
  
   status = -EIO;
   if (unlikely(bitmap[0]))
 @@ -5391,6 +5415,23 @@ static int decode_getacl(struct xdr_stream *xdr, 
 struct rpc_rqst *req,
  
   if ((status = decode_attr_mode(xdr, bitmap, res-mode))  0)
   goto out;
 + if (bitmap[1]  FATTR4_WORD1_DACL) {
 + unsigned int flags;
 + __be32 *p;
 +
 + p = xdr_inline_decode(xdr, 4);
 +status = -EIO;
 +if (unlikely(!p))
 +goto out;
 +flags = be32_to_cpup(p);
 +
 + acl = decode_acl_entries(xdr, res-server);
 + status = PTR_ERR(acl);
 + if (IS_ERR(acl))
 + goto out;
 + acl-a_flags = flags;
 + bitmap[1] = ~FATTR4_WORD1_DACL;
 + }
   status = 0;
  
  out:
 diff --git 

[PATCH v5 39/39] nfs: Add support for the v4.1 dacl attribute

2015-07-22 Thread Andreas Gruenbacher
From: Andreas Gruenbacher agrue...@redhat.com

The dacl attribute includes Automatic Inheritance flags not supported by the
acl attribute.  it is only supported in NFS version 4.1 and higher.  On systems
where NFS version 4.0 is still the default, an additional mount option is
needed:

mount -t nfs4 -o minorversion=1 [...]

Signed-off-by: Andreas Gruenbacher agrue...@redhat.com
---
 fs/nfs/nfs4proc.c   |  2 +-
 fs/nfs/nfs4xdr.c| 55 ++---
 include/linux/nfs_xdr.h |  2 +-
 3 files changed, 50 insertions(+), 9 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 5ba49c3..39f5548 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -4469,7 +4469,7 @@ static struct richacl *__nfs4_get_acl_uncached(struct 
inode *inode)
struct nfs_server *server = NFS_SERVER(inode);
struct page *pages[DIV_ROUND_UP(NFS4ACL_SIZE_MAX, PAGE_SIZE)] = {};
struct nfs_getaclargs args = {
-   .fh = NFS_FH(inode),
+   .inode = inode,
.acl_pages = pages,
.acl_len = ARRAY_SIZE(pages) * PAGE_SIZE,
};
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 85270df..06f5759 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -1649,9 +1649,16 @@ encode_setacl(struct xdr_stream *xdr, struct 
nfs_setaclargs *arg, struct compoun
encode_nfs4_stateid(xdr, zero_stateid);
 
/* Encode attribute bitmap. */
-   p = reserve_space(xdr, 2*4);
-   *p++ = cpu_to_be32(1);
-   *p = cpu_to_be32(FATTR4_WORD0_ACL);
+   if (arg-server-attr_bitmask[1]  FATTR4_WORD1_DACL) {
+   p = reserve_space(xdr, 3*4);
+   *p++ = cpu_to_be32(2);
+   *p++ = 0;
+   *p = cpu_to_be32(FATTR4_WORD1_DACL);
+   } else {
+   p = reserve_space(xdr, 2*4);
+   *p++ = cpu_to_be32(1);
+   *p = cpu_to_be32(FATTR4_WORD0_ACL);
+   }
 
attrlen_offset = xdr-buf-len;
xdr_reserve_space(xdr, 4);  /* to be backfilled later */
@@ -2486,9 +2493,12 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, 
struct xdr_stream *xdr,
 
encode_compound_hdr(xdr, req, hdr);
encode_sequence(xdr, args-seq_args, hdr);
-   encode_putfh(xdr, args-fh, hdr);
+   encode_putfh(xdr, NFS_FH(args-inode), hdr);
replen = hdr.replen + op_decode_hdr_maxsz + 1;
-   encode_getattr_two(xdr, FATTR4_WORD0_ACL, FATTR4_WORD1_MODE, hdr);
+   if (NFS_SERVER(args-inode)-attr_bitmask[1]  FATTR4_WORD1_DACL)
+   encode_getattr_two(xdr, 0, FATTR4_WORD1_MODE | 
FATTR4_WORD1_DACL, hdr);
+   else
+   encode_getattr_two(xdr, FATTR4_WORD0_ACL, FATTR4_WORD1_MODE, 
hdr);
 
xdr_inline_pages(req-rq_rcv_buf, replen  2,
args-acl_pages, 0, args-acl_len);
@@ -5376,14 +5386,28 @@ static int decode_getacl(struct xdr_stream *xdr, struct 
rpc_rqst *req,
 
if (unlikely(bitmap[0]  (FATTR4_WORD0_ACL - 1U)))
return -EIO;
-   if (likely(bitmap[0]  FATTR4_WORD0_ACL)) {
+
+   if (bitmap[0]  FATTR4_WORD0_ACL) {
+   struct richace *ace;
+
+   if (bitmap[1]  FATTR4_WORD1_DACL)
+   return -EIO;
+
acl = decode_acl_entries(xdr, res-server);
status = PTR_ERR(acl);
if (IS_ERR(acl))
goto out;
+
+   status = -EIO;
+   richacl_for_each_entry(ace, acl) {
+   if (ace-e_flags  RICHACE_INHERITED_ACE)
+   goto out;
+   }
bitmap[0] = ~FATTR4_WORD0_ACL;
-   } else
+   } else if (!(bitmap[1]  FATTR4_WORD1_DACL)) {
status = -EOPNOTSUPP;
+   goto out;
+   }
 
status = -EIO;
if (unlikely(bitmap[0]))
@@ -5391,6 +5415,23 @@ static int decode_getacl(struct xdr_stream *xdr, struct 
rpc_rqst *req,
 
if ((status = decode_attr_mode(xdr, bitmap, res-mode))  0)
goto out;
+   if (bitmap[1]  FATTR4_WORD1_DACL) {
+   unsigned int flags;
+   __be32 *p;
+
+   p = xdr_inline_decode(xdr, 4);
+status = -EIO;
+if (unlikely(!p))
+goto out;
+flags = be32_to_cpup(p);
+
+   acl = decode_acl_entries(xdr, res-server);
+   status = PTR_ERR(acl);
+   if (IS_ERR(acl))
+   goto out;
+   acl-a_flags = flags;
+   bitmap[1] = ~FATTR4_WORD1_DACL;
+   }
status = 0;
 
 out:
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index f1c8f93..abe0b66 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -695,7 +695,7 @@ struct nfs_setaclres {
 
 struct nfs_getaclargs {
struct nfs4_sequence_args   seq_args;
-   struct nfs_fh * fh;
+   struct