On Thu, 2016-06-30 at 15:47 +0200, Andreas Gruenbacher wrote: > Add richacl xattr handler implementing the xattr operations based on the > get_richacl and set_richacl inode operations. > > Signed-off-by: Andreas Gruenbacher <agruenba@xxxxxxxxxx> > --- > fs/richacl.c | 22 ++++++++++++++++ > fs/richacl_xattr.c | 61 +++++++++++++++++++++++++++++++++++++++++++ > include/linux/richacl.h | 1 + > include/linux/richacl_xattr.h | 2 ++ > 4 files changed, 86 insertions(+) > > diff --git a/fs/richacl.c b/fs/richacl.c > index 40e4af9..b7d7104 100644 > --- a/fs/richacl.c > +++ b/fs/richacl.c > @@ -549,6 +549,28 @@ out: > EXPORT_SYMBOL_GPL(richacl_permission); > > /** > + * set_richacl - set the richacl of an inode > + * @inode: inode whose richacl to set > + * @acl: access control list > + */ > +int > +set_richacl(struct inode *inode, struct richacl *acl) > +{ > + if (!IS_RICHACL(inode)) > + return -EOPNOTSUPP; > + if (!inode->i_op->set_richacl) > + return -EOPNOTSUPP; > + > + if (!uid_eq(current_fsuid(), inode->i_uid) && > + inode_permission(inode, MAY_CHMOD) && > + !capable(CAP_FOWNER)) > + return -EPERM; > + > + return inode->i_op->set_richacl(inode, acl); > +} > +EXPORT_SYMBOL(set_richacl); > + > +/** > * __richacl_chmod - update the file masks to reflect the new mode > * @acl: access control list > * @mode: new file permission bits including the file type > diff --git a/fs/richacl_xattr.c b/fs/richacl_xattr.c > index dc1ad36..5eb4aba 100644 > --- a/fs/richacl_xattr.c > +++ b/fs/richacl_xattr.c > @@ -18,7 +18,9 @@ > #include > #include > #include > +#include > #include > +#include > > /** > * richacl_from_xattr - convert a richacl xattr into the in-memory representation > @@ -159,3 +161,62 @@ richacl_to_xattr(struct user_namespace *user_ns, > return real_size; > } > EXPORT_SYMBOL_GPL(richacl_to_xattr); > + > +static bool > +richacl_xattr_list(struct dentry *dentry) > +{ > + return IS_RICHACL(d_backing_inode(dentry)); > +} > + > +static int > +richacl_xattr_get(const struct xattr_handler *handler, > + struct dentry *unused, struct inode *inode, > + const char *name, void *buffer, size_t buffer_size) > +{ > + struct richacl *acl; > + int error; > + > + if (*name) > + return -EINVAL; > + if (!IS_RICHACL(inode)) > + return -EOPNOTSUPP; > + if (S_ISLNK(inode->i_mode)) > + return -EOPNOTSUPP; > + acl = get_richacl(inode); > + if (IS_ERR(acl)) > + return PTR_ERR(acl); > + if (acl == NULL) > + return -ENODATA; > + error = richacl_to_xattr(current_user_ns(), acl, buffer, buffer_size); > + richacl_put(acl); > + return error; > +} > + > +static int > +richacl_xattr_set(const struct xattr_handler *handler, > + struct dentry *unused, struct inode *inode, > + const char *name, const void *value, size_t size, > + int flags) > +{ > + struct richacl *acl = NULL; > + int ret; > + > + if (value) { > + acl = richacl_from_xattr(current_user_ns(), value, size, > + -EINVAL); > + if (IS_ERR(acl)) > + return PTR_ERR(acl); > + } > + > + ret = set_richacl(inode, acl); > + richacl_put(acl); > + return ret; > +} > + > +struct xattr_handler richacl_xattr_handler = { > + .name = XATTR_NAME_RICHACL, > + .list = richacl_xattr_list, > + .get = richacl_xattr_get, > + .set = richacl_xattr_set, > +}; > +EXPORT_SYMBOL(richacl_xattr_handler); > diff --git a/include/linux/richacl.h b/include/linux/richacl.h > index a442372..e7db066 100644 > --- a/include/linux/richacl.h > +++ b/include/linux/richacl.h > @@ -206,5 +206,6 @@ extern int richacl_chmod(struct inode *, umode_t); > extern int richacl_equiv_mode(const struct richacl *, umode_t *); > extern struct richacl *richacl_inherit(const struct richacl *, int); > extern struct richacl *richacl_create(umode_t *, struct inode *); > +extern int set_richacl(struct inode *, struct richacl *); > > #endif /* __RICHACL_H */ > diff --git a/include/linux/richacl_xattr.h b/include/linux/richacl_xattr.h > index 0efa14b..6c6adb1 100644 > --- a/include/linux/richacl_xattr.h > +++ b/include/linux/richacl_xattr.h > @@ -26,4 +26,6 @@ extern size_t richacl_xattr_size(const struct richacl *); > extern int richacl_to_xattr(struct user_namespace *, const struct richacl *, > void *, size_t); > > +extern struct xattr_handler richacl_xattr_handler; > + > #endif /* __RICHACL_XATTR_H */ Cue same refrain about syscalls vs. xattrs. Otherwise: Reviewed-by: Jeff Layton <jlayton@xxxxxxxxxx> -- 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