1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2022-2024 Oracle.
8 #include "xfs_format.h"
9 #include "xfs_da_format.h"
10 #include "xfs_log_format.h"
11 #include "xfs_shared.h"
12 #include "xfs_trans_resv.h"
13 #include "xfs_mount.h"
14 #include "xfs_bmap_btree.h"
15 #include "xfs_inode.h"
16 #include "xfs_error.h"
17 #include "xfs_trace.h"
18 #include "xfs_trans.h"
19 #include "xfs_da_btree.h"
22 #include "xfs_dir2_priv.h"
23 #include "xfs_attr_sf.h"
25 #include "xfs_defer.h"
27 #include "xfs_xattr.h"
28 #include "xfs_parent.h"
29 #include "xfs_trans_space.h"
30 #include "xfs_attr_item.h"
31 #include "xfs_health.h"
33 struct kmem_cache *xfs_parent_args_cache;
36 * Parent pointer attribute handling.
38 * Because the attribute name is a filename component, it will never be longer
39 * than 255 bytes and must not contain nulls or slashes. These are roughly the
40 * same constraints that apply to attribute names.
42 * The attribute value must always be a struct xfs_parent_rec. This means the
43 * attribute will never be in remote format because 12 bytes is nowhere near
44 * xfs_attr_leaf_entsize_local_max() (~75% of block size).
46 * Creating a new parent attribute will always create a new attribute - there
47 * should never, ever be an existing attribute in the tree for a new inode.
48 * ENOSPC behavior is problematic - creating the inode without the parent
49 * pointer is effectively a corruption, so we allow parent attribute creation
50 * to dip into the reserve block pool to avoid unexpected ENOSPC errors from
54 /* Return true if parent pointer attr name is valid. */
57 unsigned int attr_flags,
62 * Parent pointers always use logged operations, so there should never
63 * be incomplete xattrs.
65 if (attr_flags & XFS_ATTR_INCOMPLETE)
68 return xfs_dir2_namecheck(name, length);
71 /* Return true if parent pointer attr value is valid. */
73 xfs_parent_valuecheck(
78 const struct xfs_parent_rec *rec = value;
80 if (!xfs_has_parent(mp))
83 /* The xattr value must be a parent record. */
84 if (valuelen != sizeof(struct xfs_parent_rec))
87 /* The parent record must be local. */
91 /* The parent inumber must be valid. */
92 if (!xfs_verify_dir_ino(mp, be64_to_cpu(rec->p_ino)))
98 /* Compute the attribute name hash for a parent pointer. */
101 struct xfs_mount *mp,
104 xfs_ino_t parent_ino)
106 struct xfs_name xname = {
112 * Use the same dirent name hash as would be used on the directory, but
113 * mix in the parent inode number to avoid collisions on hardlinked
114 * files with identical names but different parents.
116 return xfs_dir2_hashname(mp, &xname) ^
117 upper_32_bits(parent_ino) ^ lower_32_bits(parent_ino);
120 /* Compute the attribute name hash from the xattr components. */
123 struct xfs_mount *mp,
129 const struct xfs_parent_rec *rec = value;
131 /* Requires a local attr value in xfs_parent_rec format */
132 if (valuelen != sizeof(struct xfs_parent_rec)) {
133 ASSERT(valuelen == sizeof(struct xfs_parent_rec));
138 ASSERT(value != NULL);
142 return xfs_parent_hashval(mp, name, namelen, be64_to_cpu(rec->p_ino));
146 * Initialize the parent pointer arguments structure. Caller must have zeroed
147 * the contents of @args. @tp is only required for updates.
150 xfs_parent_da_args_init(
151 struct xfs_da_args *args,
152 struct xfs_trans *tp,
153 struct xfs_parent_rec *rec,
154 struct xfs_inode *child,
156 const struct xfs_name *parent_name)
158 args->geo = child->i_mount->m_attr_geo;
159 args->whichfork = XFS_ATTR_FORK;
160 args->attr_filter = XFS_ATTR_PARENT;
161 args->op_flags = XFS_DA_OP_LOGGED | XFS_DA_OP_OKNOENT;
165 args->name = parent_name->name;
166 args->namelen = parent_name->len;
168 args->valuelen = sizeof(struct xfs_parent_rec);
169 xfs_attr_sethash(args);
172 /* Make sure the incore state is ready for a parent pointer query/update. */
174 xfs_parent_iread_extents(
175 struct xfs_trans *tp,
176 struct xfs_inode *child)
178 /* Parent pointers require that the attr fork must exist. */
179 if (XFS_IS_CORRUPT(child->i_mount, !xfs_inode_has_attr_fork(child))) {
180 xfs_inode_mark_sick(child, XFS_SICK_INO_PARENT);
181 return -EFSCORRUPTED;
184 return xfs_iread_extents(tp, child, XFS_ATTR_FORK);
187 /* Add a parent pointer to reflect a dirent addition. */
190 struct xfs_trans *tp,
191 struct xfs_parent_args *ppargs,
192 struct xfs_inode *dp,
193 const struct xfs_name *parent_name,
194 struct xfs_inode *child)
198 error = xfs_parent_iread_extents(tp, child);
202 xfs_inode_to_parent_rec(&ppargs->rec, dp);
203 xfs_parent_da_args_init(&ppargs->args, tp, &ppargs->rec, child,
204 child->i_ino, parent_name);
205 xfs_attr_defer_add(&ppargs->args, XFS_ATTR_DEFER_SET);
209 /* Remove a parent pointer to reflect a dirent removal. */
211 xfs_parent_removename(
212 struct xfs_trans *tp,
213 struct xfs_parent_args *ppargs,
214 struct xfs_inode *dp,
215 const struct xfs_name *parent_name,
216 struct xfs_inode *child)
220 error = xfs_parent_iread_extents(tp, child);
224 xfs_inode_to_parent_rec(&ppargs->rec, dp);
225 xfs_parent_da_args_init(&ppargs->args, tp, &ppargs->rec, child,
226 child->i_ino, parent_name);
227 xfs_attr_defer_add(&ppargs->args, XFS_ATTR_DEFER_REMOVE);
231 /* Replace one parent pointer with another to reflect a rename. */
233 xfs_parent_replacename(
234 struct xfs_trans *tp,
235 struct xfs_parent_args *ppargs,
236 struct xfs_inode *old_dp,
237 const struct xfs_name *old_name,
238 struct xfs_inode *new_dp,
239 const struct xfs_name *new_name,
240 struct xfs_inode *child)
244 error = xfs_parent_iread_extents(tp, child);
248 xfs_inode_to_parent_rec(&ppargs->rec, old_dp);
249 xfs_parent_da_args_init(&ppargs->args, tp, &ppargs->rec, child,
250 child->i_ino, old_name);
252 xfs_inode_to_parent_rec(&ppargs->new_rec, new_dp);
253 ppargs->args.new_name = new_name->name;
254 ppargs->args.new_namelen = new_name->len;
255 ppargs->args.new_value = &ppargs->new_rec;
256 ppargs->args.new_valuelen = sizeof(struct xfs_parent_rec);
257 xfs_attr_defer_add(&ppargs->args, XFS_ATTR_DEFER_REPLACE);
262 * Extract parent pointer information from any parent pointer xattr into
263 * @parent_ino/gen. The last two parameters can be NULL pointers.
265 * Returns 0 if this is not a parent pointer xattr at all; or -EFSCORRUPTED for
269 xfs_parent_from_attr(
270 struct xfs_mount *mp,
271 unsigned int attr_flags,
272 const unsigned char *name,
273 unsigned int namelen,
275 unsigned int valuelen,
276 xfs_ino_t *parent_ino,
277 uint32_t *parent_gen)
279 const struct xfs_parent_rec *rec = value;
281 ASSERT(attr_flags & XFS_ATTR_PARENT);
283 if (!xfs_parent_namecheck(attr_flags, name, namelen))
284 return -EFSCORRUPTED;
285 if (!xfs_parent_valuecheck(mp, value, valuelen))
286 return -EFSCORRUPTED;
289 *parent_ino = be64_to_cpu(rec->p_ino);
291 *parent_gen = be32_to_cpu(rec->p_gen);
296 * Look up a parent pointer record (@parent_name -> @pptr) of @ip.
298 * Caller must hold at least ILOCK_SHARED. The scratchpad need not be
301 * Returns 0 if the pointer is found, -ENOATTR if there is no match, or a
306 struct xfs_trans *tp,
307 struct xfs_inode *ip,
308 const struct xfs_name *parent_name,
309 struct xfs_parent_rec *pptr,
310 struct xfs_da_args *scratch)
312 memset(scratch, 0, sizeof(struct xfs_da_args));
313 xfs_parent_da_args_init(scratch, tp, pptr, ip, ip->i_ino, parent_name);
314 return xfs_attr_get_ilocked(scratch);
317 /* Sanity-check a parent pointer before we try to perform repairs. */
319 xfs_parent_sanity_check(
320 struct xfs_mount *mp,
321 const struct xfs_name *parent_name,
322 const struct xfs_parent_rec *pptr)
324 if (!xfs_parent_namecheck(XFS_ATTR_PARENT, parent_name->name,
328 if (!xfs_parent_valuecheck(mp, pptr, sizeof(*pptr)))
336 * Attach the parent pointer (@parent_name -> @pptr) to @ip immediately.
337 * Caller must not have a transaction or hold the ILOCK. This is for
338 * specialized repair functions only. The scratchpad need not be initialized.
342 struct xfs_inode *ip,
344 const struct xfs_name *parent_name,
345 struct xfs_parent_rec *pptr,
346 struct xfs_da_args *scratch)
348 if (!xfs_parent_sanity_check(ip->i_mount, parent_name, pptr)) {
350 return -EFSCORRUPTED;
353 memset(scratch, 0, sizeof(struct xfs_da_args));
354 xfs_parent_da_args_init(scratch, NULL, pptr, ip, owner, parent_name);
355 return xfs_attr_set(scratch, XFS_ATTRUPDATE_CREATE, false);
359 * Remove the parent pointer (@parent_name -> @pptr) from @ip immediately.
360 * Caller must not have a transaction or hold the ILOCK. This is for
361 * specialized repair functions only. The scratchpad need not be initialized.
365 struct xfs_inode *ip,
367 const struct xfs_name *parent_name,
368 struct xfs_parent_rec *pptr,
369 struct xfs_da_args *scratch)
371 if (!xfs_parent_sanity_check(ip->i_mount, parent_name, pptr)) {
373 return -EFSCORRUPTED;
376 memset(scratch, 0, sizeof(struct xfs_da_args));
377 xfs_parent_da_args_init(scratch, NULL, pptr, ip, owner, parent_name);
378 return xfs_attr_set(scratch, XFS_ATTRUPDATE_REMOVE, false);