1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2008 Christoph Hellwig.
4 * Portions Copyright (C) 2000-2008 Silicon Graphics, Inc.
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"
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.
29 xfs_attr_grab_log_assist(
34 /* xattr update log intent items are already enabled */
35 if (xfs_is_using_logged_xattrs(mp
))
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
))
47 /* Enable log-assisted xattrs. */
48 error
= xfs_add_incompat_log_feature(mp
,
49 XFS_SB_FEAT_INCOMPAT_LOG_XATTRS
);
52 xfs_set_using_logged_xattrs(mp
);
54 xfs_warn_experimental(mp
, XFS_EXPERIMENTAL_LARP
);
60 xfs_attr_want_log_assist(
64 /* Logged xattrs require a V5 super for log_incompat */
65 return xfs_has_crc(mp
) && xfs_globals
.larp
;
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
79 struct xfs_da_args
*args
,
80 enum xfs_attr_update op
)
82 struct xfs_mount
*mp
= args
->dp
->i_mount
;
85 if (xfs_is_shutdown(mp
))
88 error
= xfs_qm_dqattach(args
->dp
);
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
);
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
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
));
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
= {
139 .attr_filter
= handler
->flags
,
141 .namelen
= strlen(name
),
147 if (xfs_ifork_zapped(XFS_I(inode
), XFS_ATTR_FORK
))
150 error
= xfs_attr_get(&args
);
153 return args
.valuelen
;
156 static inline enum xfs_attr_update
157 xfs_xattr_flags_to_op(
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
;
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
= {
178 .attr_filter
= handler
->flags
,
180 .namelen
= strlen(name
),
181 .value
= (void *)value
,
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
);
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
,
221 __xfs_xattr_put_listent(
222 struct xfs_attr_list_context
*context
,
231 if (context
->count
< 0 || context
->seen_enough
)
234 if (!context
->buffer
)
237 arraytop
= context
->count
+ prefix_len
+ namelen
+ 1;
238 if (arraytop
> context
->firstu
) {
239 context
->count
= -1; /* insufficient space */
240 context
->seen_enough
= 1;
243 offset
= context
->buffer
+ context
->count
;
244 memcpy(offset
, prefix
, prefix_len
);
245 offset
+= prefix_len
;
246 strncpy(offset
, (char *)name
, namelen
); /* real name */
251 context
->count
+= prefix_len
+ namelen
+ 1;
256 xfs_xattr_put_listent(
257 struct xfs_attr_list_context
*context
,
267 ASSERT(context
->count
>= 0);
269 /* Don't expose private xattr namespaces. */
270 if (flags
& XFS_ATTR_PRIVATE_NSP_MASK
)
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
));
295 * Only show root namespace entries if we are actually allowed to
298 if (!capable(CAP_SYS_ADMIN
))
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
;
307 prefix
= XATTR_USER_PREFIX
;
308 prefix_len
= XATTR_USER_PREFIX_LEN
;
311 __xfs_xattr_put_listent(context
, prefix
, prefix_len
, name
,
318 struct dentry
*dentry
,
322 struct xfs_attr_list_context context
;
323 struct inode
*inode
= d_inode(dentry
);
326 if (xfs_ifork_zapped(XFS_I(inode
), XFS_ATTR_FORK
))
330 * First read the regular on-disk attributes.
332 memset(&context
, 0, sizeof(context
));
333 context
.dp
= XFS_I(inode
);
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
);
343 if (context
.count
< 0)
346 return context
.count
;