@@ -747,3 +747,38 @@ richacl_apply_masks(struct richacl **acl)
return retval;
}
EXPORT_SYMBOL_GPL(richacl_apply_masks);
+
+/**
+ * richacl_from_mode - create an acl which corresponds to @mode
+ * @mode: file mode including the file type
+ */
+struct richacl *
+richacl_from_mode(mode_t mode)
+{
+ struct richacl *acl;
+ struct richace *ace;
+
+ acl = richacl_alloc(1, GFP_KERNEL);
+ if (!acl)
+ return NULL;
+ acl->a_flags = RICHACL_MASKED;
+ acl->a_owner_mask = richacl_mode_to_mask(mode >> 6) |
+ RICHACE_POSIX_OWNER_ALLOWED;
+ acl->a_group_mask = richacl_mode_to_mask(mode >> 3);
+ acl->a_other_mask = richacl_mode_to_mask(mode);
+
+ ace = acl->a_entries;
+ ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE;
+ ace->e_flags = RICHACE_SPECIAL_WHO;
+ ace->e_mask = RICHACE_POSIX_ALWAYS_ALLOWED |
+ RICHACE_POSIX_MODE_ALL |
+ RICHACE_POSIX_OWNER_ALLOWED;
+ /* RICHACE_DELETE_CHILD is meaningless for non-directories. */
+ if (!S_ISDIR(mode))
+ ace->e_mask &= ~RICHACE_DELETE_CHILD;
+ ace->e_id.special = RICHACE_EVERYONE_SPECIAL_ID;
+
+ return acl;
+
+}
+EXPORT_SYMBOL_GPL(richacl_from_mode);
@@ -325,5 +325,6 @@ extern struct richacl *richacl_create(struct inode *, struct inode *);
/* richacl_compat.c */
extern int richacl_apply_masks(struct richacl **);
+extern struct richacl *richacl_from_mode(mode_t);
#endif /* __RICHACL_H */
Create a richacl that corresponds to given file mode permission bits. Signed-off-by: Andreas Gruenbacher <agruen@kernel.org> --- fs/richacl_compat.c | 35 +++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 1 + 2 files changed, 36 insertions(+)