1 // SPDX-License-Identifier: LGPL-2.1
3 * Copyright IBM Corporation, 2010
4 * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
7 #include <linux/module.h>
9 #include <linux/sched.h>
10 #include <linux/uio.h>
11 #include <linux/posix_acl_xattr.h>
12 #include <net/9p/9p.h>
13 #include <net/9p/client.h>
18 ssize_t
v9fs_fid_xattr_get(struct p9_fid
*fid
, const char *name
,
19 void *buffer
, size_t buffer_size
)
23 struct p9_fid
*attr_fid
;
24 struct kvec kvec
= {.iov_base
= buffer
, .iov_len
= buffer_size
};
28 iov_iter_kvec(&to
, ITER_DEST
, &kvec
, 1, buffer_size
);
30 attr_fid
= p9_client_xattrwalk(fid
, name
, &attr_size
);
31 if (IS_ERR(attr_fid
)) {
32 retval
= PTR_ERR(attr_fid
);
33 p9_debug(P9_DEBUG_VFS
, "p9_client_attrwalk failed %zd\n",
37 if (attr_size
> buffer_size
) {
40 else if (attr_size
> SSIZE_MAX
)
42 else /* request to get the attr_size */
45 iov_iter_truncate(&to
, attr_size
);
46 retval
= p9_client_read(attr_fid
, 0, &to
, &err
);
58 * Copy an extended attribute into the buffer
59 * provided, or compute the buffer size required.
60 * Buffer is NULL to compute the size of the buffer required.
62 * Returns a negative error number on failure, or the number of bytes
63 * used / required on success.
65 ssize_t
v9fs_xattr_get(struct dentry
*dentry
, const char *name
,
66 void *buffer
, size_t buffer_size
)
71 p9_debug(P9_DEBUG_VFS
, "name = '%s' value_len = %zu\n",
73 fid
= v9fs_fid_lookup(dentry
);
76 ret
= v9fs_fid_xattr_get(fid
, name
, buffer
, buffer_size
);
85 * Create, replace or remove an extended attribute for this inode. Buffer
86 * is NULL to remove an existing extended attribute, and non-NULL to
87 * either replace an existing extended attribute, or create a new extended
88 * attribute. The flags XATTR_REPLACE and XATTR_CREATE
89 * specify that an extended attribute must exist and must not exist
90 * previous to the call, respectively.
92 * Returns 0, or a negative error number on failure.
94 int v9fs_xattr_set(struct dentry
*dentry
, const char *name
,
95 const void *value
, size_t value_len
, int flags
)
100 fid
= v9fs_fid_lookup(dentry
);
103 ret
= v9fs_fid_xattr_set(fid
, name
, value
, value_len
, flags
);
108 int v9fs_fid_xattr_set(struct p9_fid
*fid
, const char *name
,
109 const void *value
, size_t value_len
, int flags
)
111 struct kvec kvec
= {.iov_base
= (void *)value
, .iov_len
= value_len
};
112 struct iov_iter from
;
115 iov_iter_kvec(&from
, ITER_SOURCE
, &kvec
, 1, value_len
);
117 p9_debug(P9_DEBUG_VFS
, "name = %s value_len = %zu flags = %d\n",
118 name
, value_len
, flags
);
121 fid
= clone_fid(fid
);
126 * On success fid points to xattr
128 retval
= p9_client_xattrcreate(fid
, name
, value_len
, flags
);
130 p9_debug(P9_DEBUG_VFS
, "p9_client_xattrcreate failed %d\n",
133 p9_client_write(fid
, 0, &from
, &retval
);
134 err
= p9_fid_put(fid
);
140 ssize_t
v9fs_listxattr(struct dentry
*dentry
, char *buffer
, size_t buffer_size
)
142 /* Txattrwalk with an empty string lists xattrs instead */
143 return v9fs_xattr_get(dentry
, "", buffer
, buffer_size
);
146 static int v9fs_xattr_handler_get(const struct xattr_handler
*handler
,
147 struct dentry
*dentry
, struct inode
*inode
,
148 const char *name
, void *buffer
, size_t size
)
150 const char *full_name
= xattr_full_name(handler
, name
);
152 return v9fs_xattr_get(dentry
, full_name
, buffer
, size
);
155 static int v9fs_xattr_handler_set(const struct xattr_handler
*handler
,
156 struct mnt_idmap
*idmap
,
157 struct dentry
*dentry
, struct inode
*inode
,
158 const char *name
, const void *value
,
159 size_t size
, int flags
)
161 const char *full_name
= xattr_full_name(handler
, name
);
163 return v9fs_xattr_set(dentry
, full_name
, value
, size
, flags
);
166 static const struct xattr_handler v9fs_xattr_user_handler
= {
167 .prefix
= XATTR_USER_PREFIX
,
168 .get
= v9fs_xattr_handler_get
,
169 .set
= v9fs_xattr_handler_set
,
172 static const struct xattr_handler v9fs_xattr_trusted_handler
= {
173 .prefix
= XATTR_TRUSTED_PREFIX
,
174 .get
= v9fs_xattr_handler_get
,
175 .set
= v9fs_xattr_handler_set
,
178 #ifdef CONFIG_9P_FS_SECURITY
179 static const struct xattr_handler v9fs_xattr_security_handler
= {
180 .prefix
= XATTR_SECURITY_PREFIX
,
181 .get
= v9fs_xattr_handler_get
,
182 .set
= v9fs_xattr_handler_set
,
186 const struct xattr_handler
* const v9fs_xattr_handlers
[] = {
187 &v9fs_xattr_user_handler
,
188 &v9fs_xattr_trusted_handler
,
189 #ifdef CONFIG_9P_FS_SECURITY
190 &v9fs_xattr_security_handler
,