On Sat, Sep 05, 2015 at 12:27:24PM +0200, Andreas Gruenbacher wrote:
> When converting from NFSv4 ACLs to POSIX ACLs, nfsd so far was using
> struct nfs4_acl as its internal representation. This representation is a
> subset of richacls, so get rid of struct nfs4_acl. Richacls even have a
> more compact in-memory representation, so a few more ACL entries can
> easily be supported.

Looks good to me, ACK.

--b.

> 
> Signed-off-by: Andreas Gruenbacher <agrue...@redhat.com>
> ---
>  fs/Kconfig              |   6 +
>  fs/nfs_common/Makefile  |   1 +
>  fs/nfs_common/nfs4acl.c |  44 ++++++
>  fs/nfsd/Kconfig         |   1 +
>  fs/nfsd/acl.h           |  24 ++--
>  fs/nfsd/nfs4acl.c       | 367 
> ++++++++++++++++++++++--------------------------
>  fs/nfsd/nfs4proc.c      |  15 +-
>  fs/nfsd/nfs4xdr.c       |  64 +++------
>  fs/nfsd/xdr4.h          |   6 +-
>  include/linux/nfs4.h    |  23 ---
>  include/linux/nfs4acl.h |   7 +
>  11 files changed, 273 insertions(+), 285 deletions(-)
>  create mode 100644 fs/nfs_common/nfs4acl.c
>  create mode 100644 include/linux/nfs4acl.h
> 
> diff --git a/fs/Kconfig b/fs/Kconfig
> index 3e09c06..dd3f2d6 100644
> --- a/fs/Kconfig
> +++ b/fs/Kconfig
> @@ -268,6 +268,12 @@ config NFS_COMMON
>       depends on NFSD || NFS_FS || LOCKD
>       default y
>  
> +config NFS_RICHACL
> +     bool
> +     depends on NFSD_V4 || NFS_V4
> +     select FS_RICHACL
> +     default y
> +
>  source "net/sunrpc/Kconfig"
>  source "fs/ceph/Kconfig"
>  source "fs/cifs/Kconfig"
> diff --git a/fs/nfs_common/Makefile b/fs/nfs_common/Makefile
> index d153ca3..e055139 100644
> --- a/fs/nfs_common/Makefile
> +++ b/fs/nfs_common/Makefile
> @@ -4,5 +4,6 @@
>  
>  obj-$(CONFIG_NFS_ACL_SUPPORT) += nfs_acl.o
>  nfs_acl-objs := nfsacl.o
> +obj-$(CONFIG_NFS_RICHACL) += nfs4acl.o
>  
>  obj-$(CONFIG_GRACE_PERIOD) += grace.o
> diff --git a/fs/nfs_common/nfs4acl.c b/fs/nfs_common/nfs4acl.c
> new file mode 100644
> index 0000000..02df064
> --- /dev/null
> +++ b/fs/nfs_common/nfs4acl.c
> @@ -0,0 +1,44 @@
> +#include <linux/fs.h>
> +#include <linux/richacl.h>
> +#include <linux/nfs4acl.h>
> +
> +static struct special_id {
> +     char *who;
> +     int   len;
> +} special_who_map[] = {
> +     [RICHACE_OWNER_SPECIAL_ID] = {
> +             .who = "OWNER@",
> +             .len = sizeof("OWNER@") - 1 },
> +     [RICHACE_GROUP_SPECIAL_ID] = {
> +             .who = "GROUP@",
> +             .len = sizeof("GROUP@") - 1 },
> +     [RICHACE_EVERYONE_SPECIAL_ID] = {
> +             .who = "EVERYONE@",
> +             .len = sizeof("EVERYONE@") - 1 }
> +};
> +
> +int nfs4acl_who_to_special_id(const char *who, u32 len)
> +{
> +     int n;
> +
> +     for (n = 0; n < ARRAY_SIZE(special_who_map); n++) {
> +             if (len == special_who_map[n].len &&
> +                 !memcmp(who, special_who_map[n].who, len))
> +                     return n;
> +     }
> +     return -1;
> +}
> +EXPORT_SYMBOL(nfs4acl_who_to_special_id);
> +
> +bool nfs4acl_special_id_to_who(unsigned int special_who,
> +                            const char **who, unsigned int *len)
> +{
> +     struct special_id *special = &special_who_map[special_who];
> +
> +     if (special_who > ARRAY_SIZE(special_who_map) || !special->len)
> +             return false;
> +     *who = special->who;
> +     *len = special->len;
> +     return true;
> +}
> +EXPORT_SYMBOL(nfs4acl_special_id_to_who);
> diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig
> index a0b77fc..811379a 100644
> --- a/fs/nfsd/Kconfig
> +++ b/fs/nfsd/Kconfig
> @@ -70,6 +70,7 @@ config NFSD_V4
>       depends on NFSD && PROC_FS
>       select NFSD_V3
>       select FS_POSIX_ACL
> +     select FS_RICHACL
>       select SUNRPC_GSS
>       select CRYPTO
>       select GRACE_PERIOD
> diff --git a/fs/nfsd/acl.h b/fs/nfsd/acl.h
> index 4cd7c69..1c5deb5 100644
> --- a/fs/nfsd/acl.h
> +++ b/fs/nfsd/acl.h
> @@ -35,25 +35,27 @@
>  #ifndef LINUX_NFS4_ACL_H
>  #define LINUX_NFS4_ACL_H
>  
> -struct nfs4_acl;
> +struct richacl;
> +struct richace;
>  struct svc_fh;
>  struct svc_rqst;
>  
>  /*
>   * Maximum ACL we'll accept from a client; chosen (somewhat
>   * arbitrarily) so that kmalloc'ing the ACL shouldn't require a
> - * high-order allocation.  This allows 204 ACEs on x86_64:
> + * high-order allocation.  This allows 339 ACEs on x86_64:
>   */
> -#define NFS4_ACL_MAX ((PAGE_SIZE - sizeof(struct nfs4_acl)) \
> -                     / sizeof(struct nfs4_ace))
> +#define NFSD4_ACL_MAX ((PAGE_SIZE - sizeof(struct richacl)) \
> +                     / sizeof(struct richace))
>  
> -int nfs4_acl_bytes(int entries);
> -int nfs4_acl_get_whotype(char *, u32);
> -__be32 nfs4_acl_write_who(struct xdr_stream *xdr, int who);
> +__be32 nfsd4_decode_ace_who(struct richace *ace, struct svc_rqst *rqstp,
> +                         char *who, u32 len);
> +__be32 nfsd4_encode_ace_who(struct xdr_stream *xdr, struct svc_rqst *rqstp,
> +                         struct richace *ace);
>  
> -int nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry,
> -             struct nfs4_acl **acl);
> -__be32 nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
> -             struct nfs4_acl *acl);
> +int nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry,
> +               struct richacl **acl);
> +__be32 nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
> +                  struct richacl *acl);
>  
>  #endif /* LINUX_NFS4_ACL_H */
> diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c
> index eb5accf..582f772 100644
> --- a/fs/nfsd/nfs4acl.c
> +++ b/fs/nfsd/nfs4acl.c
> @@ -36,45 +36,48 @@
>  
>  #include <linux/slab.h>
>  #include <linux/nfs_fs.h>
> +#include <linux/richacl_compat.h>
> +#include <linux/nfs4acl.h>
>  #include "nfsfh.h"
>  #include "nfsd.h"
> +#include "idmap.h"
>  #include "acl.h"
>  #include "vfs.h"
>  
> -#define NFS4_ACL_TYPE_DEFAULT        0x01
> -#define NFS4_ACL_DIR         0x02
> -#define NFS4_ACL_OWNER               0x04
> +#define FLAG_DEFAULT_ACL     0x01
> +#define FLAG_DIRECTORY               0x02
> +#define FLAG_OWNER           0x04
>  
>  /* mode bit translations: */
> -#define NFS4_READ_MODE (NFS4_ACE_READ_DATA)
> -#define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA | NFS4_ACE_APPEND_DATA)
> -#define NFS4_EXECUTE_MODE NFS4_ACE_EXECUTE
> -#define NFS4_ANYONE_MODE (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL | 
> NFS4_ACE_SYNCHRONIZE)
> -#define NFS4_OWNER_MODE (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL)
> +#define RICHACE_READ_MODE (RICHACE_READ_DATA)
> +#define RICHACE_WRITE_MODE (RICHACE_WRITE_DATA | RICHACE_APPEND_DATA)
> +#define RICHACE_EXECUTE_MODE RICHACE_EXECUTE
> +#define RICHACE_ANYONE_MODE (RICHACE_READ_ATTRIBUTES | RICHACE_READ_ACL | 
> RICHACE_SYNCHRONIZE)
> +#define RICHACE_OWNER_MODE (RICHACE_WRITE_ATTRIBUTES | RICHACE_WRITE_ACL)
>  
>  /* flags used to simulate posix default ACLs */
> -#define NFS4_INHERITANCE_FLAGS (NFS4_ACE_FILE_INHERIT_ACE \
> -             | NFS4_ACE_DIRECTORY_INHERIT_ACE)
> -
> -#define NFS4_SUPPORTED_FLAGS (NFS4_INHERITANCE_FLAGS \
> -             | NFS4_ACE_INHERIT_ONLY_ACE \
> -             | NFS4_ACE_IDENTIFIER_GROUP)
> +#define RICHACE_SUPPORTED_FLAGS (            \
> +     RICHACE_FILE_INHERIT_ACE |              \
> +     RICHACE_DIRECTORY_INHERIT_ACE |         \
> +     RICHACE_INHERIT_ONLY_ACE |              \
> +     RICHACE_IDENTIFIER_GROUP |              \
> +     RICHACE_SPECIAL_WHO)
>  
>  static u32
>  mask_from_posix(unsigned short perm, unsigned int flags)
>  {
> -     int mask = NFS4_ANYONE_MODE;
> +     int mask = RICHACE_ANYONE_MODE;
>  
> -     if (flags & NFS4_ACL_OWNER)
> -             mask |= NFS4_OWNER_MODE;
> +     if (flags & FLAG_OWNER)
> +             mask |= RICHACE_OWNER_MODE;
>       if (perm & ACL_READ)
> -             mask |= NFS4_READ_MODE;
> +             mask |= RICHACE_READ_MODE;
>       if (perm & ACL_WRITE)
> -             mask |= NFS4_WRITE_MODE;
> -     if ((perm & ACL_WRITE) && (flags & NFS4_ACL_DIR))
> -             mask |= NFS4_ACE_DELETE_CHILD;
> +             mask |= RICHACE_WRITE_MODE;
> +     if ((perm & ACL_WRITE) && (flags & FLAG_DIRECTORY))
> +             mask |= RICHACE_DELETE_CHILD;
>       if (perm & ACL_EXECUTE)
> -             mask |= NFS4_EXECUTE_MODE;
> +             mask |= RICHACE_EXECUTE_MODE;
>       return mask;
>  }
>  
> @@ -84,13 +87,13 @@ deny_mask_from_posix(unsigned short perm, u32 flags)
>       u32 mask = 0;
>  
>       if (perm & ACL_READ)
> -             mask |= NFS4_READ_MODE;
> +             mask |= RICHACE_READ_MODE;
>       if (perm & ACL_WRITE)
> -             mask |= NFS4_WRITE_MODE;
> -     if ((perm & ACL_WRITE) && (flags & NFS4_ACL_DIR))
> -             mask |= NFS4_ACE_DELETE_CHILD;
> +             mask |= RICHACE_WRITE_MODE;
> +     if ((perm & ACL_WRITE) && (flags & FLAG_DIRECTORY))
> +             mask |= RICHACE_DELETE_CHILD;
>       if (perm & ACL_EXECUTE)
> -             mask |= NFS4_EXECUTE_MODE;
> +             mask |= RICHACE_EXECUTE_MODE;
>       return mask;
>  }
>  
> @@ -106,32 +109,33 @@ deny_mask_from_posix(unsigned short perm, u32 flags)
>  static void
>  low_mode_from_nfs4(u32 perm, unsigned short *mode, unsigned int flags)
>  {
> -     u32 write_mode = NFS4_WRITE_MODE;
> +     u32 write_mode = RICHACE_WRITE_MODE;
>  
> -     if (flags & NFS4_ACL_DIR)
> -             write_mode |= NFS4_ACE_DELETE_CHILD;
> +     if (flags & FLAG_DIRECTORY)
> +             write_mode |= RICHACE_DELETE_CHILD;
>       *mode = 0;
> -     if ((perm & NFS4_READ_MODE) == NFS4_READ_MODE)
> +     if ((perm & RICHACE_READ_MODE) == RICHACE_READ_MODE)
>               *mode |= ACL_READ;
>       if ((perm & write_mode) == write_mode)
>               *mode |= ACL_WRITE;
> -     if ((perm & NFS4_EXECUTE_MODE) == NFS4_EXECUTE_MODE)
> +     if ((perm & RICHACE_EXECUTE_MODE) == RICHACE_EXECUTE_MODE)
>               *mode |= ACL_EXECUTE;
>  }
>  
> -static short ace2type(struct nfs4_ace *);
> -static void _posix_to_nfsv4_one(struct posix_acl *, struct nfs4_acl *,
> +static short ace2type(struct richace *);
> +static void _posix_to_richacl_one(struct posix_acl *, struct richacl_alloc *,
>                               unsigned int);
>  
>  int
> -nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry,
> -             struct nfs4_acl **acl)
> +nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry,
> +           struct richacl **acl)
>  {
>       struct inode *inode = d_inode(dentry);
>       int error = 0;
>       struct posix_acl *pacl = NULL, *dpacl = NULL;
> +     struct richacl_alloc alloc;
>       unsigned int flags = 0;
> -     int size = 0;
> +     int count;
>  
>       pacl = get_acl(inode, ACL_TYPE_ACCESS);
>       if (!pacl)
> @@ -141,10 +145,10 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct 
> dentry *dentry,
>               return PTR_ERR(pacl);
>  
>       /* allocate for worst case: one (deny, allow) pair each: */
> -     size += 2 * pacl->a_count;
> +     count = 2 * pacl->a_count;
>  
>       if (S_ISDIR(inode->i_mode)) {
> -             flags = NFS4_ACL_DIR;
> +             flags = FLAG_DIRECTORY;
>               dpacl = get_acl(inode, ACL_TYPE_DEFAULT);
>               if (IS_ERR(dpacl)) {
>                       error = PTR_ERR(dpacl);
> @@ -152,20 +156,20 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct 
> dentry *dentry,
>               }
>  
>               if (dpacl)
> -                     size += 2 * dpacl->a_count;
> +                     count += 2 * dpacl->a_count;
>       }
>  
> -     *acl = kmalloc(nfs4_acl_bytes(size), GFP_KERNEL);
> -     if (*acl == NULL) {
> +     if (!richacl_prepare(&alloc, count)) {
>               error = -ENOMEM;
>               goto out;
>       }
> -     (*acl)->naces = 0;
>  
> -     _posix_to_nfsv4_one(pacl, *acl, flags & ~NFS4_ACL_TYPE_DEFAULT);
> +     _posix_to_richacl_one(pacl, &alloc, flags);
>  
>       if (dpacl)
> -             _posix_to_nfsv4_one(dpacl, *acl, flags | NFS4_ACL_TYPE_DEFAULT);
> +             _posix_to_richacl_one(dpacl, &alloc, flags | FLAG_DEFAULT_ACL);
> +
> +     *acl = alloc.acl;
>  
>  out:
>       posix_acl_release(dpacl);
> @@ -228,21 +232,22 @@ summarize_posix_acl(struct posix_acl *acl, struct 
> posix_acl_summary *pas)
>  
>  /* We assume the acl has been verified with posix_acl_valid. */
>  static void
> -_posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl,
> -                                             unsigned int flags)
> +_posix_to_richacl_one(struct posix_acl *pacl, struct richacl_alloc *alloc,
> +             unsigned int flags)
>  {
>       struct posix_acl_entry *pa, *group_owner_entry;
> -     struct nfs4_ace *ace;
> +     struct richace *ace;
>       struct posix_acl_summary pas;
>       unsigned short deny;
> -     int eflag = ((flags & NFS4_ACL_TYPE_DEFAULT) ?
> -             NFS4_INHERITANCE_FLAGS | NFS4_ACE_INHERIT_ONLY_ACE : 0);
> +     int e_flags = ((flags & FLAG_DEFAULT_ACL) ?
> +                    (RICHACE_FILE_INHERIT_ACE |
> +                     RICHACE_DIRECTORY_INHERIT_ACE |
> +                     RICHACE_INHERIT_ONLY_ACE) : 0);
>  
>       BUG_ON(pacl->a_count < 3);
>       summarize_posix_acl(pacl, &pas);
>  
>       pa = pacl->a_entries;
> -     ace = acl->aces + acl->naces;
>  
>       /* We could deny everything not granted by the owner: */
>       deny = ~pas.owner;
> @@ -252,42 +257,35 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct 
> nfs4_acl *acl,
>        */
>       deny &= pas.users | pas.group | pas.groups | pas.other;
>       if (deny) {
> -             ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE;
> -             ace->flag = eflag;
> -             ace->access_mask = deny_mask_from_posix(deny, flags);
> -             ace->whotype = NFS4_ACL_WHO_OWNER;
> -             ace++;
> -             acl->naces++;
> +             ace = richacl_append_entry(alloc);
> +             ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE;
> +             ace->e_flags = e_flags | RICHACE_SPECIAL_WHO;
> +             ace->e_mask = deny_mask_from_posix(deny, flags);
> +             ace->e_id.special = RICHACE_OWNER_SPECIAL_ID;
>       }
>  
> -     ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE;
> -     ace->flag = eflag;
> -     ace->access_mask = mask_from_posix(pa->e_perm, flags | NFS4_ACL_OWNER);
> -     ace->whotype = NFS4_ACL_WHO_OWNER;
> -     ace++;
> -     acl->naces++;
> +     ace = richacl_append_entry(alloc);
> +     ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE;
> +     ace->e_flags = e_flags | RICHACE_SPECIAL_WHO;
> +     ace->e_mask = mask_from_posix(pa->e_perm, flags | FLAG_OWNER);
> +     ace->e_id.special = RICHACE_OWNER_SPECIAL_ID;
>       pa++;
>  
>       while (pa->e_tag == ACL_USER) {
>               deny = ~(pa->e_perm & pas.mask);
>               deny &= pas.groups | pas.group | pas.other;
>               if (deny) {
> -                     ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE;
> -                     ace->flag = eflag;
> -                     ace->access_mask = deny_mask_from_posix(deny, flags);
> -                     ace->whotype = NFS4_ACL_WHO_NAMED;
> -                     ace->who_uid = pa->e_uid;
> -                     ace++;
> -                     acl->naces++;
> +                     ace = richacl_append_entry(alloc);
> +                     ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE;
> +                     ace->e_flags = e_flags;
> +                     ace->e_mask = deny_mask_from_posix(deny, flags);
> +                     ace->e_id.uid = pa->e_uid;
>               }
> -             ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE;
> -             ace->flag = eflag;
> -             ace->access_mask = mask_from_posix(pa->e_perm & pas.mask,
> -                                                flags);
> -             ace->whotype = NFS4_ACL_WHO_NAMED;
> -             ace->who_uid = pa->e_uid;
> -             ace++;
> -             acl->naces++;
> +             ace = richacl_append_entry(alloc);
> +             ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE;
> +             ace->e_flags = e_flags;
> +             ace->e_mask = mask_from_posix(pa->e_perm & pas.mask, flags);
> +             ace->e_id.uid = pa->e_uid;
>               pa++;
>       }
>  
> @@ -298,23 +296,19 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct 
> nfs4_acl *acl,
>  
>       group_owner_entry = pa;
>  
> -     ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE;
> -     ace->flag = eflag;
> -     ace->access_mask = mask_from_posix(pas.group, flags);
> -     ace->whotype = NFS4_ACL_WHO_GROUP;
> -     ace++;
> -     acl->naces++;
> +     ace = richacl_append_entry(alloc);
> +     ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE;
> +     ace->e_flags = e_flags | RICHACE_SPECIAL_WHO;
> +     ace->e_mask = mask_from_posix(pas.group, flags);
> +     ace->e_id.special = RICHACE_GROUP_SPECIAL_ID;
>       pa++;
>  
>       while (pa->e_tag == ACL_GROUP) {
> -             ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE;
> -             ace->flag = eflag | NFS4_ACE_IDENTIFIER_GROUP;
> -             ace->access_mask = mask_from_posix(pa->e_perm & pas.mask,
> -                                                flags);
> -             ace->whotype = NFS4_ACL_WHO_NAMED;
> -             ace->who_gid = pa->e_gid;
> -             ace++;
> -             acl->naces++;
> +             ace = richacl_append_entry(alloc);
> +             ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE;
> +             ace->e_flags = e_flags | RICHACE_IDENTIFIER_GROUP;
> +             ace->e_mask = mask_from_posix(pa->e_perm & pas.mask, flags);
> +             ace->e_id.gid = pa->e_gid;
>               pa++;
>       }
>  
> @@ -324,12 +318,11 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct 
> nfs4_acl *acl,
>  
>       deny = ~pas.group & pas.other;
>       if (deny) {
> -             ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE;
> -             ace->flag = eflag;
> -             ace->access_mask = deny_mask_from_posix(deny, flags);
> -             ace->whotype = NFS4_ACL_WHO_GROUP;
> -             ace++;
> -             acl->naces++;
> +             ace = richacl_append_entry(alloc);
> +             ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE;
> +             ace->e_flags = e_flags | RICHACE_SPECIAL_WHO;
> +             ace->e_mask = deny_mask_from_posix(deny, flags);
> +             ace->e_id.special = RICHACE_GROUP_SPECIAL_ID;
>       }
>       pa++;
>  
> @@ -337,24 +330,22 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct 
> nfs4_acl *acl,
>               deny = ~(pa->e_perm & pas.mask);
>               deny &= pas.other;
>               if (deny) {
> -                     ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE;
> -                     ace->flag = eflag | NFS4_ACE_IDENTIFIER_GROUP;
> -                     ace->access_mask = deny_mask_from_posix(deny, flags);
> -                     ace->whotype = NFS4_ACL_WHO_NAMED;
> -                     ace->who_gid = pa->e_gid;
> -                     ace++;
> -                     acl->naces++;
> +                     ace = richacl_append_entry(alloc);
> +                     ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE;
> +                     ace->e_flags = e_flags | RICHACE_IDENTIFIER_GROUP;
> +                     ace->e_mask = deny_mask_from_posix(deny, flags);
> +                     ace->e_id.gid = pa->e_gid;
>               }
>               pa++;
>       }
>  
>       if (pa->e_tag == ACL_MASK)
>               pa++;
> -     ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE;
> -     ace->flag = eflag;
> -     ace->access_mask = mask_from_posix(pa->e_perm, flags);
> -     ace->whotype = NFS4_ACL_WHO_EVERYONE;
> -     acl->naces++;
> +     ace = richacl_append_entry(alloc);
> +     ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE;
> +     ace->e_flags = e_flags | RICHACE_SPECIAL_WHO;
> +     ace->e_mask = mask_from_posix(pa->e_perm, flags);
> +     ace->e_id.special = RICHACE_EVERYONE_SPECIAL_ID;
>  }
>  
>  static bool
> @@ -498,7 +489,7 @@ posix_state_to_acl(struct posix_acl_state *state, 
> unsigned int flags)
>        * and effective cases: when there are no inheritable ACEs,
>        * calls ->set_acl with a NULL ACL structure.
>        */
> -     if (state->empty && (flags & NFS4_ACL_TYPE_DEFAULT))
> +     if (state->empty && (flags & FLAG_DEFAULT_ACL))
>               return NULL;
>  
>       /*
> @@ -617,24 +608,24 @@ static void allow_bits_array(struct 
> posix_ace_state_array *a, u32 mask)
>  }
>  
>  static void process_one_v4_ace(struct posix_acl_state *state,
> -                             struct nfs4_ace *ace)
> +                             struct richace *ace)
>  {
> -     u32 mask = ace->access_mask;
> +     u32 mask = ace->e_mask;
>       int i;
>  
>       state->empty = 0;
>  
>       switch (ace2type(ace)) {
>       case ACL_USER_OBJ:
> -             if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
> +             if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) {
>                       allow_bits(&state->owner, mask);
>               } else {
>                       deny_bits(&state->owner, mask);
>               }
>               break;
>       case ACL_USER:
> -             i = find_uid(state, ace->who_uid);
> -             if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
> +             i = find_uid(state, ace->e_id.uid);
> +             if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) {
>                       allow_bits(&state->users->aces[i].perms, mask);
>               } else {
>                       deny_bits(&state->users->aces[i].perms, mask);
> @@ -643,7 +634,7 @@ static void process_one_v4_ace(struct posix_acl_state 
> *state,
>               }
>               break;
>       case ACL_GROUP_OBJ:
> -             if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
> +             if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) {
>                       allow_bits(&state->group, mask);
>               } else {
>                       deny_bits(&state->group, mask);
> @@ -655,8 +646,8 @@ static void process_one_v4_ace(struct posix_acl_state 
> *state,
>               }
>               break;
>       case ACL_GROUP:
> -             i = find_gid(state, ace->who_gid);
> -             if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
> +             i = find_gid(state, ace->e_id.gid);
> +             if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) {
>                       allow_bits(&state->groups->aces[i].perms, mask);
>               } else {
>                       deny_bits(&state->groups->aces[i].perms, mask);
> @@ -669,7 +660,7 @@ static void process_one_v4_ace(struct posix_acl_state 
> *state,
>               }
>               break;
>       case ACL_OTHER:
> -             if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
> +             if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) {
>                       allow_bits(&state->owner, mask);
>                       allow_bits(&state->group, mask);
>                       allow_bits(&state->other, mask);
> @@ -687,32 +678,33 @@ static void process_one_v4_ace(struct posix_acl_state 
> *state,
>       }
>  }
>  
> -static int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl,
> +static int nfs4_richacl_to_posix(struct richacl *acl,
>               struct posix_acl **pacl, struct posix_acl **dpacl,
>               unsigned int flags)
>  {
>       struct posix_acl_state effective_acl_state, default_acl_state;
> -     struct nfs4_ace *ace;
> +     struct richace *ace;
>       int ret;
>  
> -     ret = init_state(&effective_acl_state, acl->naces);
> +     ret = init_state(&effective_acl_state, acl->a_count);
>       if (ret)
>               return ret;
> -     ret = init_state(&default_acl_state, acl->naces);
> +     ret = init_state(&default_acl_state, acl->a_count);
>       if (ret)
>               goto out_estate;
>       ret = -EINVAL;
> -     for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) {
> -             if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE &&
> -                 ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE)
> +     richacl_for_each_entry(ace, acl) {
> +             if (ace->e_type != RICHACE_ACCESS_ALLOWED_ACE_TYPE &&
> +                 ace->e_type != RICHACE_ACCESS_DENIED_ACE_TYPE)
>                       goto out_dstate;
> -             if (ace->flag & ~NFS4_SUPPORTED_FLAGS)
> +             if (ace->e_flags & ~RICHACE_SUPPORTED_FLAGS)
>                       goto out_dstate;
> -             if ((ace->flag & NFS4_INHERITANCE_FLAGS) == 0) {
> +             if ((ace->e_flags & (RICHACE_FILE_INHERIT_ACE |
> +                                  RICHACE_DIRECTORY_INHERIT_ACE)) == 0) {
>                       process_one_v4_ace(&effective_acl_state, ace);
>                       continue;
>               }
> -             if (!(flags & NFS4_ACL_DIR))
> +             if (!(flags & FLAG_DIRECTORY))
>                       goto out_dstate;
>               /*
>                * Note that when only one of FILE_INHERIT or DIRECTORY_INHERIT
> @@ -721,7 +713,7 @@ static int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl,
>                */
>               process_one_v4_ace(&default_acl_state, ace);
>  
> -             if (!(ace->flag & NFS4_ACE_INHERIT_ONLY_ACE))
> +             if (!(ace->e_flags & RICHACE_INHERIT_ONLY_ACE))
>                       process_one_v4_ace(&effective_acl_state, ace);
>       }
>       *pacl = posix_state_to_acl(&effective_acl_state, flags);
> @@ -731,7 +723,7 @@ static int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl,
>               goto out_dstate;
>       }
>       *dpacl = posix_state_to_acl(&default_acl_state,
> -                                             flags | NFS4_ACL_TYPE_DEFAULT);
> +                                             flags | FLAG_DEFAULT_ACL);
>       if (IS_ERR(*dpacl)) {
>               ret = PTR_ERR(*dpacl);
>               *dpacl = NULL;
> @@ -750,8 +742,7 @@ out_estate:
>  }
>  
>  __be32
> -nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
> -             struct nfs4_acl *acl)
> +nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, struct richacl 
> *acl)
>  {
>       __be32 error;
>       int host_error;
> @@ -772,9 +763,9 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh 
> *fhp,
>               return nfserr_attrnotsupp;
>  
>       if (S_ISDIR(inode->i_mode))
> -             flags = NFS4_ACL_DIR;
> +             flags = FLAG_DIRECTORY;
>  
> -     host_error = nfs4_acl_nfsv4_to_posix(acl, &pacl, &dpacl, flags);
> +     host_error = nfs4_richacl_to_posix(acl, &pacl, &dpacl, flags);
>       if (host_error == -EINVAL)
>               return nfserr_attrnotsupp;
>       if (host_error < 0)
> @@ -801,82 +792,62 @@ out_nfserr:
>  
>  
>  static short
> -ace2type(struct nfs4_ace *ace)
> +ace2type(struct richace *ace)
>  {
> -     switch (ace->whotype) {
> -             case NFS4_ACL_WHO_NAMED:
> -                     return (ace->flag & NFS4_ACE_IDENTIFIER_GROUP ?
> -                                     ACL_GROUP : ACL_USER);
> -             case NFS4_ACL_WHO_OWNER:
> +     if (ace->e_flags & RICHACE_SPECIAL_WHO) {
> +             switch (ace->e_id.special) {
> +             case RICHACE_OWNER_SPECIAL_ID:
>                       return ACL_USER_OBJ;
> -             case NFS4_ACL_WHO_GROUP:
> +             case RICHACE_GROUP_SPECIAL_ID:
>                       return ACL_GROUP_OBJ;
> -             case NFS4_ACL_WHO_EVERYONE:
> +             case RICHACE_EVERYONE_SPECIAL_ID:
>                       return ACL_OTHER;
> +             default:
> +                     BUG();
> +             }
>       }
> -     BUG();
> -     return -1;
> -}
> -
> -/*
> - * return the size of the struct nfs4_acl required to represent an acl
> - * with @entries entries.
> - */
> -int nfs4_acl_bytes(int entries)
> -{
> -     return sizeof(struct nfs4_acl) + entries * sizeof(struct nfs4_ace);
> +     return ace->e_flags & RICHACE_IDENTIFIER_GROUP ? ACL_GROUP : ACL_USER;
>  }
>  
> -static struct {
> -     char *string;
> -     int   stringlen;
> -     int type;
> -} s2t_map[] = {
> -     {
> -             .string    = "OWNER@",
> -             .stringlen = sizeof("OWNER@") - 1,
> -             .type      = NFS4_ACL_WHO_OWNER,
> -     },
> -     {
> -             .string    = "GROUP@",
> -             .stringlen = sizeof("GROUP@") - 1,
> -             .type      = NFS4_ACL_WHO_GROUP,
> -     },
> -     {
> -             .string    = "EVERYONE@",
> -             .stringlen = sizeof("EVERYONE@") - 1,
> -             .type      = NFS4_ACL_WHO_EVERYONE,
> -     },
> -};
> -
> -int
> -nfs4_acl_get_whotype(char *p, u32 len)
> +__be32 nfsd4_decode_ace_who(struct richace *ace, struct svc_rqst *rqstp,
> +                         char *who, u32 len)
>  {
> -     int i;
> -
> -     for (i = 0; i < ARRAY_SIZE(s2t_map); i++) {
> -             if (s2t_map[i].stringlen == len &&
> -                             0 == memcmp(s2t_map[i].string, p, len))
> -                     return s2t_map[i].type;
> +     int special_id;
> +
> +     special_id = nfs4acl_who_to_special_id(who, len);
> +     if (special_id >= 0) {
> +             ace->e_flags |= RICHACE_SPECIAL_WHO;
> +             ace->e_flags &= ~RICHACE_IDENTIFIER_GROUP;
> +             ace->e_id.special = special_id;
> +             return nfs_ok;
>       }
> -     return NFS4_ACL_WHO_NAMED;
> +     if (ace->e_flags & RICHACE_IDENTIFIER_GROUP)
> +             return nfsd_map_name_to_gid(rqstp, who, len, &ace->e_id.gid);
> +     else
> +             return nfsd_map_name_to_uid(rqstp, who, len, &ace->e_id.uid);
>  }
>  
> -__be32 nfs4_acl_write_who(struct xdr_stream *xdr, int who)
> +__be32 nfsd4_encode_ace_who(struct xdr_stream *xdr, struct svc_rqst *rqstp,
> +                         struct richace *ace)
>  {
> -     __be32 *p;
> -     int i;
> -
> -     for (i = 0; i < ARRAY_SIZE(s2t_map); i++) {
> -             if (s2t_map[i].type != who)
> -                     continue;
> -             p = xdr_reserve_space(xdr, s2t_map[i].stringlen + 4);
> +     if (ace->e_flags & RICHACE_SPECIAL_WHO) {
> +             unsigned int special_id = ace->e_id.special;
> +             const char *who;
> +             unsigned int len;
> +             __be32 *p;
> +
> +             if (!nfs4acl_special_id_to_who(special_id, &who, &len)) {
> +                     WARN_ON_ONCE(1);
> +                     return nfserr_serverfault;
> +             }
> +             p = xdr_reserve_space(xdr, len + 4);
>               if (!p)
>                       return nfserr_resource;
> -             p = xdr_encode_opaque(p, s2t_map[i].string,
> -                                     s2t_map[i].stringlen);
> +             p = xdr_encode_opaque(p, who, len);
>               return 0;
>       }
> -     WARN_ON_ONCE(1);
> -     return nfserr_serverfault;
> +     if (ace->e_flags & RICHACE_IDENTIFIER_GROUP)
> +             return nfsd4_encode_group(xdr, rqstp, ace->e_id.gid);
> +     else
> +             return nfsd4_encode_user(xdr, rqstp, ace->e_id.uid);
>  }
> diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
> index 90cfda7..8c2cb16 100644
> --- a/fs/nfsd/nfs4proc.c
> +++ b/fs/nfsd/nfs4proc.c
> @@ -159,12 +159,12 @@ is_create_with_attrs(struct nfsd4_open *open)
>   * in the returned attr bitmap.
>   */
>  static void
> -do_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
> -             struct nfs4_acl *acl, u32 *bmval)
> +do_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, struct richacl *acl,
> +        u32 *bmval)
>  {
>       __be32 status;
>  
> -     status = nfsd4_set_nfs4_acl(rqstp, fhp, acl);
> +     status = nfsd4_set_acl(rqstp, fhp, acl);
>       if (status)
>               /*
>                * We should probably fail the whole open at this point,
> @@ -299,7 +299,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct 
> nfsd4_compound_state *cstate, stru
>               goto out;
>  
>       if (is_create_with_attrs(open) && open->op_acl != NULL)
> -             do_set_nfs4_acl(rqstp, *resfh, open->op_acl, open->op_bmval);
> +             do_set_acl(rqstp, *resfh, open->op_acl, open->op_bmval);
>  
>       nfsd4_set_open_owner_reply_cache(cstate, open, *resfh);
>       accmode = NFSD_MAY_NOP;
> @@ -674,8 +674,7 @@ nfsd4_create(struct svc_rqst *rqstp, struct 
> nfsd4_compound_state *cstate,
>               nfsd4_security_inode_setsecctx(&resfh, &create->cr_label, 
> create->cr_bmval);
>  
>       if (create->cr_acl != NULL)
> -             do_set_nfs4_acl(rqstp, &resfh, create->cr_acl,
> -                             create->cr_bmval);
> +             do_set_acl(rqstp, &resfh, create->cr_acl, create->cr_bmval);
>  
>       fh_unlock(&cstate->current_fh);
>       set_change_info(&create->cr_cinfo, &cstate->current_fh);
> @@ -940,8 +939,8 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct 
> nfsd4_compound_state *cstate,
>               goto out;
>  
>       if (setattr->sa_acl != NULL)
> -             status = nfsd4_set_nfs4_acl(rqstp, &cstate->current_fh,
> -                                         setattr->sa_acl);
> +             status = nfsd4_set_acl(rqstp, &cstate->current_fh,
> +                                    setattr->sa_acl);
>       if (status)
>               goto out;
>       if (setattr->sa_label.len)
> diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
> index 0768251..465f82a 100644
> --- a/fs/nfsd/nfs4xdr.c
> +++ b/fs/nfsd/nfs4xdr.c
> @@ -303,7 +303,7 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 
> *bmval)
>  
>  static __be32
>  nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
> -                struct iattr *iattr, struct nfs4_acl **acl,
> +                struct iattr *iattr, struct richacl **acl,
>                  struct xdr_netobj *label)
>  {
>       int expected_len, len = 0;
> @@ -326,38 +326,31 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 
> *bmval,
>       }
>       if (bmval[0] & FATTR4_WORD0_ACL) {
>               u32 nace;
> -             struct nfs4_ace *ace;
> +             struct richace *ace;
>  
>               READ_BUF(4); len += 4;
>               nace = be32_to_cpup(p++);
>  
> -             if (nace > NFS4_ACL_MAX)
> +             if (nace > NFSD4_ACL_MAX)
>                       return nfserr_fbig;
>  
> -             *acl = svcxdr_tmpalloc(argp, nfs4_acl_bytes(nace));
> +             *acl = svcxdr_alloc_richacl(argp, nace);
>               if (*acl == NULL)
>                       return nfserr_jukebox;
>  
> -             (*acl)->naces = nace;
> -             for (ace = (*acl)->aces; ace < (*acl)->aces + nace; ace++) {
> +             richacl_for_each_entry(ace, *acl) {
>                       READ_BUF(16); len += 16;
> -                     ace->type = be32_to_cpup(p++);
> -                     ace->flag = be32_to_cpup(p++);
> -                     ace->access_mask = be32_to_cpup(p++);
> +                     ace->e_type = be32_to_cpup(p++);
> +                     ace->e_flags = be32_to_cpup(p++);
> +                     ace->e_mask = be32_to_cpup(p++);
> +                     if (ace->e_flags & RICHACE_SPECIAL_WHO)
> +                             return nfserr_inval;
>                       dummy32 = be32_to_cpup(p++);
>                       READ_BUF(dummy32);
>                       len += XDR_QUADLEN(dummy32) << 2;
>                       READMEM(buf, dummy32);
> -                     ace->whotype = nfs4_acl_get_whotype(buf, dummy32);
> -                     status = nfs_ok;
> -                     if (ace->whotype != NFS4_ACL_WHO_NAMED)
> -                             ;
> -                     else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
> -                             status = nfsd_map_name_to_gid(argp->rqstp,
> -                                             buf, dummy32, &ace->who_gid);
> -                     else
> -                             status = nfsd_map_name_to_uid(argp->rqstp,
> -                                             buf, dummy32, &ace->who_uid);
> +                     status = nfsd4_decode_ace_who(ace, argp->rqstp,
> +                                                   buf, dummy32);
>                       if (status)
>                               return status;
>               }
> @@ -2147,18 +2140,6 @@ static u32 nfs4_file_type(umode_t mode)
>       };
>  }
>  
> -static inline __be32
> -nfsd4_encode_aclname(struct xdr_stream *xdr, struct svc_rqst *rqstp,
> -                  struct nfs4_ace *ace)
> -{
> -     if (ace->whotype != NFS4_ACL_WHO_NAMED)
> -             return nfs4_acl_write_who(xdr, ace->whotype);
> -     else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
> -             return nfsd4_encode_group(xdr, rqstp, ace->who_gid);
> -     else
> -             return nfsd4_encode_user(xdr, rqstp, ace->who_uid);
> -}
> -
>  #define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID 
> | \
>                             FATTR4_WORD0_RDATTR_ERROR)
>  #define WORD1_ABSENT_FS_ATTRS FATTR4_WORD1_MOUNTED_ON_FILEID
> @@ -2249,7 +2230,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct 
> svc_fh *fhp,
>       u32 rdattr_err = 0;
>       __be32 status;
>       int err;
> -     struct nfs4_acl *acl = NULL;
> +     struct richacl *acl = NULL;
>       void *context = NULL;
>       int contextlen;
>       bool contextsupport = false;
> @@ -2295,7 +2276,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct 
> svc_fh *fhp,
>               fhp = tempfh;
>       }
>       if (bmval0 & FATTR4_WORD0_ACL) {
> -             err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl);
> +             err = nfsd4_get_acl(rqstp, dentry, &acl);
>               if (err == -EOPNOTSUPP)
>                       bmval0 &= ~FATTR4_WORD0_ACL;
>               else if (err == -EINVAL) {
> @@ -2469,7 +2450,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct 
> svc_fh *fhp,
>               *p++ = cpu_to_be32(rdattr_err);
>       }
>       if (bmval0 & FATTR4_WORD0_ACL) {
> -             struct nfs4_ace *ace;
> +             struct richace *ace;
>  
>               if (acl == NULL) {
>                       p = xdr_reserve_space(xdr, 4);
> @@ -2482,17 +2463,16 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct 
> svc_fh *fhp,
>               p = xdr_reserve_space(xdr, 4);
>               if (!p)
>                       goto out_resource;
> -             *p++ = cpu_to_be32(acl->naces);
> +             *p++ = cpu_to_be32(acl->a_count);
>  
> -             for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) {
> +             richacl_for_each_entry(ace, acl) {
>                       p = xdr_reserve_space(xdr, 4*3);
>                       if (!p)
>                               goto out_resource;
> -                     *p++ = cpu_to_be32(ace->type);
> -                     *p++ = cpu_to_be32(ace->flag);
> -                     *p++ = cpu_to_be32(ace->access_mask &
> -                                                     NFS4_ACE_MASK_ALL);
> -                     status = nfsd4_encode_aclname(xdr, rqstp, ace);
> +                     *p++ = cpu_to_be32(ace->e_type);
> +                     *p++ = cpu_to_be32(ace->e_flags & ~RICHACE_SPECIAL_WHO);
> +                     *p++ = cpu_to_be32(ace->e_mask & NFS4_ACE_MASK_ALL);
> +                     status = nfsd4_encode_ace_who(xdr, rqstp, ace);
>                       if (status)
>                               goto out;
>               }
> @@ -2755,7 +2735,7 @@ out:
>       if (context)
>               security_release_secctx(context, contextlen);
>  #endif /* CONFIG_NFSD_V4_SECURITY_LABEL */
> -     kfree(acl);
> +     richacl_put(acl);
>       if (tempfh) {
>               fh_put(tempfh);
>               kfree(tempfh);
> diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
> index b698585..c311066 100644
> --- a/fs/nfsd/xdr4.h
> +++ b/fs/nfsd/xdr4.h
> @@ -118,7 +118,7 @@ struct nfsd4_create {
>       u32             cr_bmval[3];        /* request */
>       struct iattr    cr_iattr;           /* request */
>       struct nfsd4_change_info  cr_cinfo; /* response */
> -     struct nfs4_acl *cr_acl;
> +     struct richacl *cr_acl;
>       struct xdr_netobj cr_label;
>  };
>  #define cr_datalen   u.link.datalen
> @@ -248,7 +248,7 @@ struct nfsd4_open {
>       struct nfs4_file *op_file;          /* used during processing */
>       struct nfs4_ol_stateid *op_stp;     /* used during processing */
>       struct nfs4_clnt_odstate *op_odstate; /* used during processing */
> -     struct nfs4_acl *op_acl;
> +     struct richacl *op_acl;
>       struct xdr_netobj op_label;
>  };
>  
> @@ -332,7 +332,7 @@ struct nfsd4_setattr {
>       stateid_t       sa_stateid;         /* request */
>       u32             sa_bmval[3];        /* request */
>       struct iattr    sa_iattr;           /* request */
> -     struct nfs4_acl *sa_acl;
> +     struct richacl *sa_acl;
>       struct xdr_netobj sa_label;
>  };
>  
> diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
> index b8e72aa..992ddc4 100644
> --- a/include/linux/nfs4.h
> +++ b/include/linux/nfs4.h
> @@ -16,29 +16,6 @@
>  #include <linux/uidgid.h>
>  #include <uapi/linux/nfs4.h>
>  
> -enum nfs4_acl_whotype {
> -     NFS4_ACL_WHO_NAMED = 0,
> -     NFS4_ACL_WHO_OWNER,
> -     NFS4_ACL_WHO_GROUP,
> -     NFS4_ACL_WHO_EVERYONE,
> -};
> -
> -struct nfs4_ace {
> -     uint32_t        type;
> -     uint32_t        flag;
> -     uint32_t        access_mask;
> -     int             whotype;
> -     union {
> -             kuid_t  who_uid;
> -             kgid_t  who_gid;
> -     };
> -};
> -
> -struct nfs4_acl {
> -     uint32_t        naces;
> -     struct nfs4_ace aces[0];
> -};
> -
>  #define NFS4_MAXLABELLEN     2048
>  
>  struct nfs4_label {
> diff --git a/include/linux/nfs4acl.h b/include/linux/nfs4acl.h
> new file mode 100644
> index 0000000..db9f9a6
> --- /dev/null
> +++ b/include/linux/nfs4acl.h
> @@ -0,0 +1,7 @@
> +#ifndef __LINUX_NFS4ACL_H
> +#define __LINUX_NFS4ACL_H
> +
> +int nfs4acl_who_to_special_id(const char *, u32);
> +bool nfs4acl_special_id_to_who(unsigned int, const char **, unsigned int *);
> +
> +#endif
> -- 
> 2.4.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
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/

Reply via email to