^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Copyright IBM Corporation, 2010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This program is free software; you can redistribute it and/or modify it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * under the terms of version 2.1 of the GNU Lesser General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * as published by the Free Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * This program is distributed in the hope that it would be useful, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/uio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <net/9p/9p.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <net/9p/client.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "fid.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "xattr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) ssize_t v9fs_fid_xattr_get(struct p9_fid *fid, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) void *buffer, size_t buffer_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) ssize_t retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) u64 attr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct p9_fid *attr_fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct kvec kvec = {.iov_base = buffer, .iov_len = buffer_size};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct iov_iter to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) iov_iter_kvec(&to, READ, &kvec, 1, buffer_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) attr_fid = p9_client_xattrwalk(fid, name, &attr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if (IS_ERR(attr_fid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) retval = PTR_ERR(attr_fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) p9_debug(P9_DEBUG_VFS, "p9_client_attrwalk failed %zd\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (attr_size > buffer_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (!buffer_size) /* request to get the attr_size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) retval = attr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) retval = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) iov_iter_truncate(&to, attr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) retval = p9_client_read(attr_fid, 0, &to, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) retval = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) p9_client_clunk(attr_fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * v9fs_xattr_get()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * Copy an extended attribute into the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * provided, or compute the buffer size required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * Buffer is NULL to compute the size of the buffer required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * Returns a negative error number on failure, or the number of bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * used / required on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) ssize_t v9fs_xattr_get(struct dentry *dentry, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) void *buffer, size_t buffer_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct p9_fid *fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) p9_debug(P9_DEBUG_VFS, "name = %s value_len = %zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) name, buffer_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) fid = v9fs_fid_lookup(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (IS_ERR(fid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return PTR_ERR(fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return v9fs_fid_xattr_get(fid, name, buffer, buffer_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * v9fs_xattr_set()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * Create, replace or remove an extended attribute for this inode. Buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * is NULL to remove an existing extended attribute, and non-NULL to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * either replace an existing extended attribute, or create a new extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * attribute. The flags XATTR_REPLACE and XATTR_CREATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * specify that an extended attribute must exist and must not exist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * previous to the call, respectively.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * Returns 0, or a negative error number on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int v9fs_xattr_set(struct dentry *dentry, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) const void *value, size_t value_len, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct p9_fid *fid = v9fs_fid_lookup(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return v9fs_fid_xattr_set(fid, name, value, value_len, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) int v9fs_fid_xattr_set(struct p9_fid *fid, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) const void *value, size_t value_len, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct kvec kvec = {.iov_base = (void *)value, .iov_len = value_len};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct iov_iter from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) int retval, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) iov_iter_kvec(&from, WRITE, &kvec, 1, value_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) p9_debug(P9_DEBUG_VFS, "name = %s value_len = %zu flags = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) name, value_len, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /* Clone it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) fid = clone_fid(fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (IS_ERR(fid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return PTR_ERR(fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * On success fid points to xattr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) retval = p9_client_xattrcreate(fid, name, value_len, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) p9_debug(P9_DEBUG_VFS, "p9_client_xattrcreate failed %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) p9_client_write(fid, 0, &from, &retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) err = p9_client_clunk(fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (!retval && err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) retval = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) ssize_t v9fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return v9fs_xattr_get(dentry, NULL, buffer, buffer_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static int v9fs_xattr_handler_get(const struct xattr_handler *handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct dentry *dentry, struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) const char *name, void *buffer, size_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) const char *full_name = xattr_full_name(handler, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return v9fs_xattr_get(dentry, full_name, buffer, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static int v9fs_xattr_handler_set(const struct xattr_handler *handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct dentry *dentry, struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) const char *name, const void *value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) size_t size, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) const char *full_name = xattr_full_name(handler, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return v9fs_xattr_set(dentry, full_name, value, size, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static struct xattr_handler v9fs_xattr_user_handler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) .prefix = XATTR_USER_PREFIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) .get = v9fs_xattr_handler_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .set = v9fs_xattr_handler_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static struct xattr_handler v9fs_xattr_trusted_handler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) .prefix = XATTR_TRUSTED_PREFIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) .get = v9fs_xattr_handler_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) .set = v9fs_xattr_handler_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #ifdef CONFIG_9P_FS_SECURITY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static struct xattr_handler v9fs_xattr_security_handler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) .prefix = XATTR_SECURITY_PREFIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) .get = v9fs_xattr_handler_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) .set = v9fs_xattr_handler_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) const struct xattr_handler *v9fs_xattr_handlers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) &v9fs_xattr_user_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) &v9fs_xattr_trusted_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #ifdef CONFIG_9P_FS_POSIX_ACL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) &v9fs_xattr_acl_access_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) &v9fs_xattr_acl_default_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) #ifdef CONFIG_9P_FS_SECURITY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) &v9fs_xattr_security_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) };