From f5e4546347bc847be30b3cf904db5fc874b3c5dc Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 1 May 2019 14:05:27 +0100 Subject: afs: Implement YFS ACL setting Implement the setting of YFS ACLs in AFS through the interface of setting the afs.yfs.acl extended attribute on the file. Signed-off-by: David Howells --- fs/afs/xattr.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'fs/afs/xattr.c') diff --git a/fs/afs/xattr.c b/fs/afs/xattr.c index a5c82b0ad539..c81f85003fc7 100644 --- a/fs/afs/xattr.c +++ b/fs/afs/xattr.c @@ -226,9 +226,58 @@ out: return ret; } +/* + * Set a file's YFS ACL. + */ +static int afs_xattr_set_yfs(const struct xattr_handler *handler, + struct dentry *dentry, + struct inode *inode, const char *name, + const void *buffer, size_t size, int flags) +{ + struct afs_fs_cursor fc; + struct afs_vnode *vnode = AFS_FS_I(inode); + struct afs_acl *acl = NULL; + struct key *key; + int ret; + + if (flags == XATTR_CREATE || + strcmp(name, "acl") != 0) + return -EINVAL; + + key = afs_request_key(vnode->volume->cell); + if (IS_ERR(key)) + return PTR_ERR(key); + + acl = kmalloc(sizeof(*acl) + size, GFP_KERNEL); + if (!acl) { + key_put(key); + return -ENOMEM; + } + + acl->size = size; + memcpy(acl->data, buffer, size); + + ret = -ERESTARTSYS; + if (afs_begin_vnode_operation(&fc, vnode, key)) { + while (afs_select_fileserver(&fc)) { + fc.cb_break = afs_calc_vnode_cb_break(vnode); + yfs_fs_store_opaque_acl2(&fc, acl); + } + + afs_check_for_remote_deletion(&fc, fc.vnode); + afs_vnode_commit_status(&fc, vnode, fc.cb_break); + ret = afs_end_vnode_operation(&fc); + } + + kfree(acl); + key_put(key); + return ret; +} + static const struct xattr_handler afs_xattr_yfs_handler = { .prefix = "afs.yfs.", .get = afs_xattr_get_yfs, + .set = afs_xattr_set_yfs, }; /* -- cgit v1.2.3