drm/tests: Add test for drm_atomic_helper_check_modeset()
[drm/drm-misc.git] / fs / xfs / xfs_xattr.c
blob0f641a9091ecbf17a086b13ab13844639169c027
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) 2008 Christoph Hellwig.
4 * Portions Copyright (C) 2000-2008 Silicon Graphics, Inc.
5 */
7 #include "xfs.h"
8 #include "xfs_shared.h"
9 #include "xfs_format.h"
10 #include "xfs_log_format.h"
11 #include "xfs_da_format.h"
12 #include "xfs_trans_resv.h"
13 #include "xfs_mount.h"
14 #include "xfs_inode.h"
15 #include "xfs_da_btree.h"
16 #include "xfs_attr.h"
17 #include "xfs_acl.h"
18 #include "xfs_log.h"
19 #include "xfs_xattr.h"
20 #include "xfs_quota.h"
22 #include <linux/posix_acl_xattr.h>
25 * Get permission to use log-assisted atomic exchange of file extents.
26 * Callers must not be running any transactions or hold any ILOCKs.
28 static inline int
29 xfs_attr_grab_log_assist(
30 struct xfs_mount *mp)
32 int error = 0;
34 /* xattr update log intent items are already enabled */
35 if (xfs_is_using_logged_xattrs(mp))
36 return 0;
39 * Check if the filesystem featureset is new enough to set this log
40 * incompat feature bit. Strictly speaking, the minimum requirement is
41 * a V5 filesystem for the superblock field, but we'll require rmap
42 * or reflink to avoid having to deal with really old kernels.
44 if (!xfs_has_reflink(mp) && !xfs_has_rmapbt(mp))
45 return -EOPNOTSUPP;
47 /* Enable log-assisted xattrs. */
48 error = xfs_add_incompat_log_feature(mp,
49 XFS_SB_FEAT_INCOMPAT_LOG_XATTRS);
50 if (error)
51 return error;
52 xfs_set_using_logged_xattrs(mp);
54 xfs_warn_experimental(mp, XFS_EXPERIMENTAL_LARP);
56 return 0;
59 static inline bool
60 xfs_attr_want_log_assist(
61 struct xfs_mount *mp)
63 #ifdef DEBUG
64 /* Logged xattrs require a V5 super for log_incompat */
65 return xfs_has_crc(mp) && xfs_globals.larp;
66 #else
67 return false;
68 #endif
72 * Set or remove an xattr, having grabbed the appropriate logging resources
73 * prior to calling libxfs. Callers of this function are only required to
74 * initialize the inode, attr_filter, name, namelen, value, and valuelen fields
75 * of @args.
77 int
78 xfs_attr_change(
79 struct xfs_da_args *args,
80 enum xfs_attr_update op)
82 struct xfs_mount *mp = args->dp->i_mount;
83 int error;
85 if (xfs_is_shutdown(mp))
86 return -EIO;
88 error = xfs_qm_dqattach(args->dp);
89 if (error)
90 return error;
93 * We have no control over the attribute names that userspace passes us
94 * to remove, so we have to allow the name lookup prior to attribute
95 * removal to fail as well.
97 args->op_flags = XFS_DA_OP_OKNOENT;
99 if (xfs_attr_want_log_assist(mp)) {
100 error = xfs_attr_grab_log_assist(mp);
101 if (error)
102 return error;
104 args->op_flags |= XFS_DA_OP_LOGGED;
107 args->owner = args->dp->i_ino;
108 args->geo = mp->m_attr_geo;
109 args->whichfork = XFS_ATTR_FORK;
110 xfs_attr_sethash(args);
113 * Some xattrs must be resistant to allocation failure at ENOSPC, e.g.
114 * creating an inode with ACLs or security attributes requires the
115 * allocation of the xattr holding that information to succeed. Hence
116 * we allow xattrs in the VFS TRUSTED, SYSTEM, POSIX_ACL and SECURITY
117 * (LSM xattr) namespaces to dip into the reserve block pool to allow
118 * manipulation of these xattrs when at ENOSPC. These VFS xattr
119 * namespaces translate to the XFS_ATTR_ROOT and XFS_ATTR_SECURE on-disk
120 * namespaces.
122 * For most of these cases, these special xattrs will fit in the inode
123 * itself and so consume no extra space or only require temporary extra
124 * space while an overwrite is being made. Hence the use of the reserved
125 * pool is largely to avoid the worst case reservation from preventing
126 * the xattr from being created at ENOSPC.
128 return xfs_attr_set(args, op,
129 args->attr_filter & (XFS_ATTR_ROOT | XFS_ATTR_SECURE));
133 static int
134 xfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused,
135 struct inode *inode, const char *name, void *value, size_t size)
137 struct xfs_da_args args = {
138 .dp = XFS_I(inode),
139 .attr_filter = handler->flags,
140 .name = name,
141 .namelen = strlen(name),
142 .value = value,
143 .valuelen = size,
145 int error;
147 if (xfs_ifork_zapped(XFS_I(inode), XFS_ATTR_FORK))
148 return -EIO;
150 error = xfs_attr_get(&args);
151 if (error)
152 return error;
153 return args.valuelen;
156 static inline enum xfs_attr_update
157 xfs_xattr_flags_to_op(
158 int flags,
159 const void *value)
161 if (!value)
162 return XFS_ATTRUPDATE_REMOVE;
163 if (flags & XATTR_CREATE)
164 return XFS_ATTRUPDATE_CREATE;
165 if (flags & XATTR_REPLACE)
166 return XFS_ATTRUPDATE_REPLACE;
167 return XFS_ATTRUPDATE_UPSERT;
170 static int
171 xfs_xattr_set(const struct xattr_handler *handler,
172 struct mnt_idmap *idmap, struct dentry *unused,
173 struct inode *inode, const char *name, const void *value,
174 size_t size, int flags)
176 struct xfs_da_args args = {
177 .dp = XFS_I(inode),
178 .attr_filter = handler->flags,
179 .name = name,
180 .namelen = strlen(name),
181 .value = (void *)value,
182 .valuelen = size,
184 int error;
186 error = xfs_attr_change(&args, xfs_xattr_flags_to_op(flags, value));
187 if (!error && (handler->flags & XFS_ATTR_ROOT))
188 xfs_forget_acl(inode, name);
189 return error;
192 static const struct xattr_handler xfs_xattr_user_handler = {
193 .prefix = XATTR_USER_PREFIX,
194 .flags = 0, /* no flags implies user namespace */
195 .get = xfs_xattr_get,
196 .set = xfs_xattr_set,
199 static const struct xattr_handler xfs_xattr_trusted_handler = {
200 .prefix = XATTR_TRUSTED_PREFIX,
201 .flags = XFS_ATTR_ROOT,
202 .get = xfs_xattr_get,
203 .set = xfs_xattr_set,
206 static const struct xattr_handler xfs_xattr_security_handler = {
207 .prefix = XATTR_SECURITY_PREFIX,
208 .flags = XFS_ATTR_SECURE,
209 .get = xfs_xattr_get,
210 .set = xfs_xattr_set,
213 const struct xattr_handler * const xfs_xattr_handlers[] = {
214 &xfs_xattr_user_handler,
215 &xfs_xattr_trusted_handler,
216 &xfs_xattr_security_handler,
217 NULL
220 static void
221 __xfs_xattr_put_listent(
222 struct xfs_attr_list_context *context,
223 char *prefix,
224 int prefix_len,
225 unsigned char *name,
226 int namelen)
228 char *offset;
229 int arraytop;
231 if (context->count < 0 || context->seen_enough)
232 return;
234 if (!context->buffer)
235 goto compute_size;
237 arraytop = context->count + prefix_len + namelen + 1;
238 if (arraytop > context->firstu) {
239 context->count = -1; /* insufficient space */
240 context->seen_enough = 1;
241 return;
243 offset = context->buffer + context->count;
244 memcpy(offset, prefix, prefix_len);
245 offset += prefix_len;
246 strncpy(offset, (char *)name, namelen); /* real name */
247 offset += namelen;
248 *offset = '\0';
250 compute_size:
251 context->count += prefix_len + namelen + 1;
252 return;
255 static void
256 xfs_xattr_put_listent(
257 struct xfs_attr_list_context *context,
258 int flags,
259 unsigned char *name,
260 int namelen,
261 void *value,
262 int valuelen)
264 char *prefix;
265 int prefix_len;
267 ASSERT(context->count >= 0);
269 /* Don't expose private xattr namespaces. */
270 if (flags & XFS_ATTR_PRIVATE_NSP_MASK)
271 return;
273 if (flags & XFS_ATTR_ROOT) {
274 #ifdef CONFIG_XFS_POSIX_ACL
275 if (namelen == SGI_ACL_FILE_SIZE &&
276 strncmp(name, SGI_ACL_FILE,
277 SGI_ACL_FILE_SIZE) == 0) {
278 __xfs_xattr_put_listent(
279 context, XATTR_SYSTEM_PREFIX,
280 XATTR_SYSTEM_PREFIX_LEN,
281 XATTR_POSIX_ACL_ACCESS,
282 strlen(XATTR_POSIX_ACL_ACCESS));
283 } else if (namelen == SGI_ACL_DEFAULT_SIZE &&
284 strncmp(name, SGI_ACL_DEFAULT,
285 SGI_ACL_DEFAULT_SIZE) == 0) {
286 __xfs_xattr_put_listent(
287 context, XATTR_SYSTEM_PREFIX,
288 XATTR_SYSTEM_PREFIX_LEN,
289 XATTR_POSIX_ACL_DEFAULT,
290 strlen(XATTR_POSIX_ACL_DEFAULT));
292 #endif
295 * Only show root namespace entries if we are actually allowed to
296 * see them.
298 if (!capable(CAP_SYS_ADMIN))
299 return;
301 prefix = XATTR_TRUSTED_PREFIX;
302 prefix_len = XATTR_TRUSTED_PREFIX_LEN;
303 } else if (flags & XFS_ATTR_SECURE) {
304 prefix = XATTR_SECURITY_PREFIX;
305 prefix_len = XATTR_SECURITY_PREFIX_LEN;
306 } else {
307 prefix = XATTR_USER_PREFIX;
308 prefix_len = XATTR_USER_PREFIX_LEN;
311 __xfs_xattr_put_listent(context, prefix, prefix_len, name,
312 namelen);
313 return;
316 ssize_t
317 xfs_vn_listxattr(
318 struct dentry *dentry,
319 char *data,
320 size_t size)
322 struct xfs_attr_list_context context;
323 struct inode *inode = d_inode(dentry);
324 int error;
326 if (xfs_ifork_zapped(XFS_I(inode), XFS_ATTR_FORK))
327 return -EIO;
330 * First read the regular on-disk attributes.
332 memset(&context, 0, sizeof(context));
333 context.dp = XFS_I(inode);
334 context.resynch = 1;
335 context.buffer = size ? data : NULL;
336 context.bufsize = size;
337 context.firstu = context.bufsize;
338 context.put_listent = xfs_xattr_put_listent;
340 error = xfs_attr_list(&context);
341 if (error)
342 return error;
343 if (context.count < 0)
344 return -ERANGE;
346 return context.count;