@@ -835,3 +835,75 @@ nfs4_acl_write_who(int who, char *p)
EXPORT_SYMBOL(nfs4_acl_new);
EXPORT_SYMBOL(nfs4_acl_get_whotype);
EXPORT_SYMBOL(nfs4_acl_write_who);
+
+struct nfs4_acl *
+nfs4_acl_richacl_to_nfsv4(struct richacl *racl)
+{
+ int error;
+ struct nfs4_acl *acl;
+ struct richace *race;
+ struct nfs4_ace *ace;
+
+ error = richacl_apply_masks(&racl);
+ if (error)
+ ERR_PTR(error);
+
+ acl = nfs4_acl_new(racl->a_count);
+ if (acl == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ ace = acl->aces;
+ richacl_for_each_entry(race, racl) {
+ ace->type = race->e_type;
+ ace->access_mask = race->e_mask;
+ ace->flag = race->e_flags & ~ACE4_SPECIAL_WHO;
+ if (richace_is_owner(race))
+ ace->whotype = NFS4_ACL_WHO_OWNER;
+ else if (richace_is_group(race))
+ ace->whotype = NFS4_ACL_WHO_GROUP;
+ else if (richace_is_everyone(race))
+ ace->whotype = NFS4_ACL_WHO_EVERYONE;
+ else {
+ ace->whotype = NFS4_ACL_WHO_NAMED;
+ ace->who = race->u.e_id;
+ }
+ ace++;
+ acl->naces++;
+ }
+ return acl;
+}
+
+int nfs4_acl_nfsv4_to_richacl(struct nfs4_acl *acl, struct richacl **racl)
+{
+ struct richace *race;
+ struct nfs4_ace *ace;
+
+ *racl = richacl_alloc(acl->naces);
+ if (*racl == NULL)
+ return -ENOMEM;
+ race = (*racl)->a_entries;
+ for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) {
+ race->e_type = ace->type;
+ race->e_flags = ace->flag;
+ race->e_mask = ace->access_mask;
+ switch (ace->whotype) {
+ case NFS4_ACL_WHO_OWNER:
+ richace_set_who(race, richace_owner_who);
+ break;
+ case NFS4_ACL_WHO_GROUP:
+ richace_set_who(race, richace_group_who);
+ break;
+ case NFS4_ACL_WHO_EVERYONE:
+ richace_set_who(race, richace_everyone_who);
+ break;
+ case NFS4_ACL_WHO_NAMED:
+ race->u.e_id = ace->who;
+ break;
+ default:
+ richacl_put(*racl);
+ return -EINVAL;
+ }
+ race++;
+ }
+ return 0;
+}
@@ -38,6 +38,7 @@
#define LINUX_NFS4_ACL_H
#include <linux/posix_acl.h>
+#include <linux/richacl.h>
/* Maximum ACL we'll accept from client; chosen (somewhat arbitrarily) to
* fit in a page: */
@@ -58,4 +59,7 @@ struct nfs4_acl *nfs4_acl_posix_to_nfsv4(struct posix_acl *,
int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *, struct posix_acl **,
struct posix_acl **, unsigned int flags);
+struct nfs4_acl *nfs4_acl_richacl_to_nfsv4(struct richacl *racl);
+int nfs4_acl_nfsv4_to_richacl(struct nfs4_acl *acl, struct richacl **racl);
+
#endif /* LINUX_NFS4_ACL_H */
Add helper function for mapping NFSv4acl to richacl and vice versa Using richacl as the ondisk format ensures that we can map NFSv4acl better to richacl. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> --- fs/nfsd/nfs4acl.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++ include/linux/nfs4_acl.h | 4 ++ 2 files changed, 76 insertions(+), 0 deletions(-)