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@xxxxxxxxxxxxxxxxxx> --- fs/nfsd/nfs4acl.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++ include/linux/nfs4_acl.h | 4 ++ 2 files changed, 76 insertions(+), 0 deletions(-) diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 8815068..6724235 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c @@ -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; +} diff --git a/include/linux/nfs4_acl.h b/include/linux/nfs4_acl.h index c9c05a7..e14b03f 100644 --- a/include/linux/nfs4_acl.h +++ b/include/linux/nfs4_acl.h @@ -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 */ -- 1.7.0.rc0.48.gdace5 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html