VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   33 Branches   55 Tags
b4d0d230ccfb5 (Thomas Gleixner   2019-05-20 19:08:01 +0200   1) // SPDX-License-Identifier: GPL-2.0-or-later
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100   2) /* Extended attribute handling for AFS.  We use xattrs to get and set metadata
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100   3)  * instead of providing pioctl().
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100   4)  *
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100   5)  * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved.
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100   6)  * Written by David Howells (dhowells@redhat.com)
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100   7)  */
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100   8) 
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100   9) #include <linux/slab.h>
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100  10) #include <linux/fs.h>
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100  11) #include <linux/xattr.h>
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100  12) #include "internal.h"
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100  13) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  14) /*
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  15)  * Deal with the result of a successful fetch ACL operation.
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  16)  */
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  17) static void afs_acl_success(struct afs_operation *op)
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  18) {
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  19) 	afs_vnode_commit_status(op, &op->file[0]);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  20) }
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  21) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  22) static void afs_acl_put(struct afs_operation *op)
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  23) {
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  24) 	kfree(op->acl);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  25) }
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  26) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  27) static const struct afs_operation_ops afs_fetch_acl_operation = {
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  28) 	.issue_afs_rpc	= afs_fs_fetch_acl,
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  29) 	.success	= afs_acl_success,
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  30) 	.put		= afs_acl_put,
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  31) };
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  32) 
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100  33) /*
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100  34)  * Get a file's ACL.
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100  35)  */
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100  36) static int afs_xattr_get_acl(const struct xattr_handler *handler,
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100  37) 			     struct dentry *dentry,
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100  38) 			     struct inode *inode, const char *name,
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100  39) 			     void *buffer, size_t size)
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100  40) {
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  41) 	struct afs_operation *op;
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100  42) 	struct afs_vnode *vnode = AFS_FS_I(inode);
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100  43) 	struct afs_acl *acl = NULL;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  44) 	int ret;
a58823ac45896 (David Howells     2019-05-09 15:16:10 +0100  45) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  46) 	op = afs_alloc_operation(NULL, vnode->volume);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  47) 	if (IS_ERR(op))
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  48) 		return -ENOMEM;
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100  49) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  50) 	afs_op_set_vnode(op, 0, vnode);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  51) 	op->ops = &afs_fetch_acl_operation;
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100  52) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  53) 	afs_begin_vnode_operation(op);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  54) 	afs_wait_for_operation(op);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  55) 	acl = op->acl;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  56) 	op->acl = NULL;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  57) 	ret = afs_put_operation(op);
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100  58) 
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100  59) 	if (ret == 0) {
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100  60) 		ret = acl->size;
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100  61) 		if (size > 0) {
cc1dd5c85cb70 (David Howells     2019-05-12 08:05:10 +0100  62) 			if (acl->size <= size)
cc1dd5c85cb70 (David Howells     2019-05-12 08:05:10 +0100  63) 				memcpy(buffer, acl->data, acl->size);
cc1dd5c85cb70 (David Howells     2019-05-12 08:05:10 +0100  64) 			else
248c944e2159d (Dan Carpenter     2020-08-24 11:58:12 +0300  65) 				ret = -ERANGE;
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100  66) 		}
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100  67) 	}
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100  68) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  69) 	kfree(acl);
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100  70) 	return ret;
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100  71) }
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100  72) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  73) static bool afs_make_acl(struct afs_operation *op,
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  74) 			 const void *buffer, size_t size)
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  75) {
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  76) 	struct afs_acl *acl;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  77) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  78) 	acl = kmalloc(sizeof(*acl) + size, GFP_KERNEL);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  79) 	if (!acl) {
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  80) 		afs_op_nomem(op);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  81) 		return false;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  82) 	}
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  83) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  84) 	acl->size = size;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  85) 	memcpy(acl->data, buffer, size);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  86) 	op->acl = acl;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  87) 	return true;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  88) }
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  89) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  90) static const struct afs_operation_ops afs_store_acl_operation = {
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  91) 	.issue_afs_rpc	= afs_fs_store_acl,
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  92) 	.success	= afs_acl_success,
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  93) 	.put		= afs_acl_put,
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  94) };
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  95) 
b10494af4989d (Joe Gorse         2019-04-25 14:26:52 +0100  96) /*
b10494af4989d (Joe Gorse         2019-04-25 14:26:52 +0100  97)  * Set a file's AFS3 ACL.
b10494af4989d (Joe Gorse         2019-04-25 14:26:52 +0100  98)  */
b10494af4989d (Joe Gorse         2019-04-25 14:26:52 +0100  99) static int afs_xattr_set_acl(const struct xattr_handler *handler,
e65ce2a50cf6a (Christian Brauner 2021-01-21 14:19:27 +0100 100) 			     struct user_namespace *mnt_userns,
b10494af4989d (Joe Gorse         2019-04-25 14:26:52 +0100 101)                              struct dentry *dentry,
b10494af4989d (Joe Gorse         2019-04-25 14:26:52 +0100 102)                              struct inode *inode, const char *name,
b10494af4989d (Joe Gorse         2019-04-25 14:26:52 +0100 103)                              const void *buffer, size_t size, int flags)
b10494af4989d (Joe Gorse         2019-04-25 14:26:52 +0100 104) {
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 105) 	struct afs_operation *op;
b10494af4989d (Joe Gorse         2019-04-25 14:26:52 +0100 106) 	struct afs_vnode *vnode = AFS_FS_I(inode);
b10494af4989d (Joe Gorse         2019-04-25 14:26:52 +0100 107) 
b10494af4989d (Joe Gorse         2019-04-25 14:26:52 +0100 108) 	if (flags == XATTR_CREATE)
b10494af4989d (Joe Gorse         2019-04-25 14:26:52 +0100 109) 		return -EINVAL;
b10494af4989d (Joe Gorse         2019-04-25 14:26:52 +0100 110) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 111) 	op = afs_alloc_operation(NULL, vnode->volume);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 112) 	if (IS_ERR(op))
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 113) 		return -ENOMEM;
a58823ac45896 (David Howells     2019-05-09 15:16:10 +0100 114) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 115) 	afs_op_set_vnode(op, 0, vnode);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 116) 	if (!afs_make_acl(op, buffer, size))
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 117) 		return afs_put_operation(op);
b10494af4989d (Joe Gorse         2019-04-25 14:26:52 +0100 118) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 119) 	op->ops = &afs_store_acl_operation;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 120) 	return afs_do_sync_operation(op);
b10494af4989d (Joe Gorse         2019-04-25 14:26:52 +0100 121) }
b10494af4989d (Joe Gorse         2019-04-25 14:26:52 +0100 122) 
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100 123) static const struct xattr_handler afs_xattr_afs_acl_handler = {
b10494af4989d (Joe Gorse         2019-04-25 14:26:52 +0100 124) 	.name   = "afs.acl",
b10494af4989d (Joe Gorse         2019-04-25 14:26:52 +0100 125) 	.get    = afs_xattr_get_acl,
b10494af4989d (Joe Gorse         2019-04-25 14:26:52 +0100 126) 	.set    = afs_xattr_set_acl,
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100 127) };
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100 128) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 129) static const struct afs_operation_ops yfs_fetch_opaque_acl_operation = {
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 130) 	.issue_yfs_rpc	= yfs_fs_fetch_opaque_acl,
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 131) 	.success	= afs_acl_success,
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 132) 	/* Don't free op->yacl in .put here */
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 133) };
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 134) 
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 135) /*
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 136)  * Get a file's YFS ACL.
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 137)  */
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 138) static int afs_xattr_get_yfs(const struct xattr_handler *handler,
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 139) 			     struct dentry *dentry,
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 140) 			     struct inode *inode, const char *name,
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 141) 			     void *buffer, size_t size)
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 142) {
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 143) 	struct afs_operation *op;
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 144) 	struct afs_vnode *vnode = AFS_FS_I(inode);
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 145) 	struct yfs_acl *yacl = NULL;
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 146) 	char buf[16], *data;
773e0c4025344 (David Howells     2019-05-12 08:31:23 +0100 147) 	int which = 0, dsize, ret = -ENOMEM;
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 148) 
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 149) 	if (strcmp(name, "acl") == 0)
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 150) 		which = 0;
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 151) 	else if (strcmp(name, "acl_inherited") == 0)
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 152) 		which = 1;
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 153) 	else if (strcmp(name, "acl_num_cleaned") == 0)
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 154) 		which = 2;
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 155) 	else if (strcmp(name, "vol_acl") == 0)
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 156) 		which = 3;
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 157) 	else
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 158) 		return -EOPNOTSUPP;
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 159) 
773e0c4025344 (David Howells     2019-05-12 08:31:23 +0100 160) 	yacl = kzalloc(sizeof(struct yfs_acl), GFP_KERNEL);
773e0c4025344 (David Howells     2019-05-12 08:31:23 +0100 161) 	if (!yacl)
773e0c4025344 (David Howells     2019-05-12 08:31:23 +0100 162) 		goto error;
773e0c4025344 (David Howells     2019-05-12 08:31:23 +0100 163) 
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 164) 	if (which == 0)
773e0c4025344 (David Howells     2019-05-12 08:31:23 +0100 165) 		yacl->flags |= YFS_ACL_WANT_ACL;
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 166) 	else if (which == 3)
773e0c4025344 (David Howells     2019-05-12 08:31:23 +0100 167) 		yacl->flags |= YFS_ACL_WANT_VOL_ACL;
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 168) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 169) 	op = afs_alloc_operation(NULL, vnode->volume);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 170) 	if (IS_ERR(op))
a58823ac45896 (David Howells     2019-05-09 15:16:10 +0100 171) 		goto error_yacl;
a58823ac45896 (David Howells     2019-05-09 15:16:10 +0100 172) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 173) 	afs_op_set_vnode(op, 0, vnode);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 174) 	op->yacl = yacl;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 175) 	op->ops = &yfs_fetch_opaque_acl_operation;
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 176) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 177) 	afs_begin_vnode_operation(op);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 178) 	afs_wait_for_operation(op);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 179) 	ret = afs_put_operation(op);
a58823ac45896 (David Howells     2019-05-09 15:16:10 +0100 180) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 181) 	if (ret == 0) {
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 182) 		switch (which) {
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 183) 		case 0:
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 184) 			data = yacl->acl->data;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 185) 			dsize = yacl->acl->size;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 186) 			break;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 187) 		case 1:
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 188) 			data = buf;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 189) 			dsize = scnprintf(buf, sizeof(buf), "%u", yacl->inherit_flag);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 190) 			break;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 191) 		case 2:
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 192) 			data = buf;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 193) 			dsize = scnprintf(buf, sizeof(buf), "%u", yacl->num_cleaned);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 194) 			break;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 195) 		case 3:
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 196) 			data = yacl->vol_acl->data;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 197) 			dsize = yacl->vol_acl->size;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 198) 			break;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 199) 		default:
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 200) 			ret = -EOPNOTSUPP;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 201) 			goto error_yacl;
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 202) 		}
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 203) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 204) 		ret = dsize;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 205) 		if (size > 0) {
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 206) 			if (dsize <= size)
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 207) 				memcpy(buffer, data, dsize);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 208) 			else
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 209) 				ret = -ERANGE;
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 210) 		}
64fcbb6158ecc (David Howells     2021-03-02 10:26:45 +0000 211) 	} else if (ret == -ENOTSUPP) {
64fcbb6158ecc (David Howells     2021-03-02 10:26:45 +0000 212) 		ret = -ENODATA;
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 213) 	}
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 214) 
773e0c4025344 (David Howells     2019-05-12 08:31:23 +0100 215) error_yacl:
773e0c4025344 (David Howells     2019-05-12 08:31:23 +0100 216) 	yfs_free_opaque_acl(yacl);
773e0c4025344 (David Howells     2019-05-12 08:31:23 +0100 217) error:
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 218) 	return ret;
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 219) }
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 220) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 221) static const struct afs_operation_ops yfs_store_opaque_acl2_operation = {
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 222) 	.issue_yfs_rpc	= yfs_fs_store_opaque_acl2,
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 223) 	.success	= afs_acl_success,
f4c79144edd8a (David Howells     2020-11-03 16:33:07 +0000 224) 	.put		= afs_acl_put,
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 225) };
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 226) 
f5e4546347bc8 (David Howells     2019-05-01 14:05:27 +0100 227) /*
f5e4546347bc8 (David Howells     2019-05-01 14:05:27 +0100 228)  * Set a file's YFS ACL.
f5e4546347bc8 (David Howells     2019-05-01 14:05:27 +0100 229)  */
f5e4546347bc8 (David Howells     2019-05-01 14:05:27 +0100 230) static int afs_xattr_set_yfs(const struct xattr_handler *handler,
e65ce2a50cf6a (Christian Brauner 2021-01-21 14:19:27 +0100 231) 			     struct user_namespace *mnt_userns,
f5e4546347bc8 (David Howells     2019-05-01 14:05:27 +0100 232)                              struct dentry *dentry,
f5e4546347bc8 (David Howells     2019-05-01 14:05:27 +0100 233)                              struct inode *inode, const char *name,
f5e4546347bc8 (David Howells     2019-05-01 14:05:27 +0100 234)                              const void *buffer, size_t size, int flags)
f5e4546347bc8 (David Howells     2019-05-01 14:05:27 +0100 235) {
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 236) 	struct afs_operation *op;
f5e4546347bc8 (David Howells     2019-05-01 14:05:27 +0100 237) 	struct afs_vnode *vnode = AFS_FS_I(inode);
64fcbb6158ecc (David Howells     2021-03-02 10:26:45 +0000 238) 	int ret;
f5e4546347bc8 (David Howells     2019-05-01 14:05:27 +0100 239) 
f5e4546347bc8 (David Howells     2019-05-01 14:05:27 +0100 240) 	if (flags == XATTR_CREATE ||
f5e4546347bc8 (David Howells     2019-05-01 14:05:27 +0100 241) 	    strcmp(name, "acl") != 0)
f5e4546347bc8 (David Howells     2019-05-01 14:05:27 +0100 242) 		return -EINVAL;
f5e4546347bc8 (David Howells     2019-05-01 14:05:27 +0100 243) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 244) 	op = afs_alloc_operation(NULL, vnode->volume);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 245) 	if (IS_ERR(op))
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 246) 		return -ENOMEM;
f5e4546347bc8 (David Howells     2019-05-01 14:05:27 +0100 247) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 248) 	afs_op_set_vnode(op, 0, vnode);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 249) 	if (!afs_make_acl(op, buffer, size))
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 250) 		return afs_put_operation(op);
f5e4546347bc8 (David Howells     2019-05-01 14:05:27 +0100 251) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 252) 	op->ops = &yfs_store_opaque_acl2_operation;
64fcbb6158ecc (David Howells     2021-03-02 10:26:45 +0000 253) 	ret = afs_do_sync_operation(op);
64fcbb6158ecc (David Howells     2021-03-02 10:26:45 +0000 254) 	if (ret == -ENOTSUPP)
64fcbb6158ecc (David Howells     2021-03-02 10:26:45 +0000 255) 		ret = -ENODATA;
64fcbb6158ecc (David Howells     2021-03-02 10:26:45 +0000 256) 	return ret;
f5e4546347bc8 (David Howells     2019-05-01 14:05:27 +0100 257) }
f5e4546347bc8 (David Howells     2019-05-01 14:05:27 +0100 258) 
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 259) static const struct xattr_handler afs_xattr_yfs_handler = {
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 260) 	.prefix	= "afs.yfs.",
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 261) 	.get	= afs_xattr_get_yfs,
f5e4546347bc8 (David Howells     2019-05-01 14:05:27 +0100 262) 	.set	= afs_xattr_set_yfs,
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 263) };
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 264) 
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 265) /*
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 266)  * Get the name of the cell on which a file resides.
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 267)  */
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 268) static int afs_xattr_get_cell(const struct xattr_handler *handler,
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 269) 			      struct dentry *dentry,
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 270) 			      struct inode *inode, const char *name,
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 271) 			      void *buffer, size_t size)
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 272) {
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 273) 	struct afs_vnode *vnode = AFS_FS_I(inode);
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 274) 	struct afs_cell *cell = vnode->volume->cell;
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 275) 	size_t namelen;
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 276) 
989782dcdc91a (David Howells     2017-11-02 15:27:50 +0000 277) 	namelen = cell->name_len;
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 278) 	if (size == 0)
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 279) 		return namelen;
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 280) 	if (namelen > size)
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 281) 		return -ERANGE;
c73aa4102f5b9 (David Howells     2019-05-01 13:27:09 +0100 282) 	memcpy(buffer, cell->name, namelen);
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 283) 	return namelen;
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 284) }
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 285) 
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 286) static const struct xattr_handler afs_xattr_afs_cell_handler = {
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 287) 	.name	= "afs.cell",
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 288) 	.get	= afs_xattr_get_cell,
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 289) };
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 290) 
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 291) /*
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 292)  * Get the volume ID, vnode ID and vnode uniquifier of a file as a sequence of
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 293)  * hex numbers separated by colons.
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 294)  */
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 295) static int afs_xattr_get_fid(const struct xattr_handler *handler,
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 296) 			     struct dentry *dentry,
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 297) 			     struct inode *inode, const char *name,
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 298) 			     void *buffer, size_t size)
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 299) {
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 300) 	struct afs_vnode *vnode = AFS_FS_I(inode);
a2f611a3dc317 (David Howells     2019-05-01 15:58:24 +0100 301) 	char text[16 + 1 + 24 + 1 + 8 + 1];
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 302) 	size_t len;
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 303) 
a2f611a3dc317 (David Howells     2019-05-01 15:58:24 +0100 304) 	/* The volume ID is 64-bit, the vnode ID is 96-bit and the
a2f611a3dc317 (David Howells     2019-05-01 15:58:24 +0100 305) 	 * uniquifier is 32-bit.
a2f611a3dc317 (David Howells     2019-05-01 15:58:24 +0100 306) 	 */
2e2fae99d1f30 (Mark Salyzyn      2019-11-21 09:12:17 +0000 307) 	len = scnprintf(text, sizeof(text), "%llx:", vnode->fid.vid);
a2f611a3dc317 (David Howells     2019-05-01 15:58:24 +0100 308) 	if (vnode->fid.vnode_hi)
2e2fae99d1f30 (Mark Salyzyn      2019-11-21 09:12:17 +0000 309) 		len += scnprintf(text + len, sizeof(text) - len, "%x%016llx",
2e2fae99d1f30 (Mark Salyzyn      2019-11-21 09:12:17 +0000 310) 				vnode->fid.vnode_hi, vnode->fid.vnode);
a2f611a3dc317 (David Howells     2019-05-01 15:58:24 +0100 311) 	else
2e2fae99d1f30 (Mark Salyzyn      2019-11-21 09:12:17 +0000 312) 		len += scnprintf(text + len, sizeof(text) - len, "%llx",
2e2fae99d1f30 (Mark Salyzyn      2019-11-21 09:12:17 +0000 313) 				 vnode->fid.vnode);
2e2fae99d1f30 (Mark Salyzyn      2019-11-21 09:12:17 +0000 314) 	len += scnprintf(text + len, sizeof(text) - len, ":%x",
2e2fae99d1f30 (Mark Salyzyn      2019-11-21 09:12:17 +0000 315) 			 vnode->fid.unique);
a2f611a3dc317 (David Howells     2019-05-01 15:58:24 +0100 316) 
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 317) 	if (size == 0)
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 318) 		return len;
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 319) 	if (len > size)
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 320) 		return -ERANGE;
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 321) 	memcpy(buffer, text, len);
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 322) 	return len;
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 323) }
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 324) 
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 325) static const struct xattr_handler afs_xattr_afs_fid_handler = {
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 326) 	.name	= "afs.fid",
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 327) 	.get	= afs_xattr_get_fid,
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 328) };
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 329) 
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 330) /*
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 331)  * Get the name of the volume on which a file resides.
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 332)  */
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 333) static int afs_xattr_get_volume(const struct xattr_handler *handler,
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 334) 			      struct dentry *dentry,
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 335) 			      struct inode *inode, const char *name,
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 336) 			      void *buffer, size_t size)
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 337) {
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 338) 	struct afs_vnode *vnode = AFS_FS_I(inode);
d2ddc776a4581 (David Howells     2017-11-02 15:27:50 +0000 339) 	const char *volname = vnode->volume->name;
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 340) 	size_t namelen;
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 341) 
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 342) 	namelen = strlen(volname);
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 343) 	if (size == 0)
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 344) 		return namelen;
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 345) 	if (namelen > size)
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 346) 		return -ERANGE;
c73aa4102f5b9 (David Howells     2019-05-01 13:27:09 +0100 347) 	memcpy(buffer, volname, namelen);
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 348) 	return namelen;
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 349) }
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 350) 
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 351) static const struct xattr_handler afs_xattr_afs_volume_handler = {
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 352) 	.name	= "afs.volume",
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 353) 	.get	= afs_xattr_get_volume,
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 354) };
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 355) 
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 356) const struct xattr_handler *afs_xattr_handlers[] = {
260f082bae6dc (David Howells     2019-04-25 14:26:52 +0100 357) 	&afs_xattr_afs_acl_handler,
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 358) 	&afs_xattr_afs_cell_handler,
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 359) 	&afs_xattr_afs_fid_handler,
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 360) 	&afs_xattr_afs_volume_handler,
ae46578b963f6 (David Howells     2019-04-30 18:30:21 +0100 361) 	&afs_xattr_yfs_handler,		/* afs.yfs. prefix */
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 362) 	NULL
d3e3b7eac886f (David Howells     2017-07-06 15:50:27 +0100 363) };