xref: /linux/fs/xfs/libxfs/xfs_parent.c (revision bde5d79d00255db609fe9d859eef8c7b6d38b137)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2022-2024 Oracle.
4  * All rights reserved.
5  */
6 #include "xfs.h"
7 #include "xfs_fs.h"
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"
20 #include "xfs_attr.h"
21 #include "xfs_dir2.h"
22 #include "xfs_dir2_priv.h"
23 #include "xfs_attr_sf.h"
24 #include "xfs_bmap.h"
25 #include "xfs_defer.h"
26 #include "xfs_log.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"
32 
33 struct kmem_cache		*xfs_parent_args_cache;
34 
35 /*
36  * Parent pointer attribute handling.
37  *
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.
41  *
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).
45  *
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
51  * occurring.
52  */
53 
54 /* Return true if parent pointer attr name is valid. */
55 bool
56 xfs_parent_namecheck(
57 	unsigned int			attr_flags,
58 	const void			*name,
59 	size_t				length)
60 {
61 	/*
62 	 * Parent pointers always use logged operations, so there should never
63 	 * be incomplete xattrs.
64 	 */
65 	if (attr_flags & XFS_ATTR_INCOMPLETE)
66 		return false;
67 
68 	return xfs_dir2_namecheck(name, length);
69 }
70 
71 /* Return true if parent pointer attr value is valid. */
72 bool
73 xfs_parent_valuecheck(
74 	struct xfs_mount		*mp,
75 	const void			*value,
76 	size_t				valuelen)
77 {
78 	const struct xfs_parent_rec	*rec = value;
79 
80 	if (!xfs_has_parent(mp))
81 		return false;
82 
83 	/* The xattr value must be a parent record. */
84 	if (valuelen != sizeof(struct xfs_parent_rec))
85 		return false;
86 
87 	/* The parent record must be local. */
88 	if (value == NULL)
89 		return false;
90 
91 	/* The parent inumber must be valid. */
92 	if (!xfs_verify_dir_ino(mp, be64_to_cpu(rec->p_ino)))
93 		return false;
94 
95 	return true;
96 }
97 
98 /* Compute the attribute name hash for a parent pointer. */
99 xfs_dahash_t
100 xfs_parent_hashval(
101 	struct xfs_mount		*mp,
102 	const uint8_t			*name,
103 	int				namelen,
104 	xfs_ino_t			parent_ino)
105 {
106 	struct xfs_name			xname = {
107 		.name			= name,
108 		.len			= namelen,
109 	};
110 
111 	/*
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.
115 	 */
116 	return xfs_dir2_hashname(mp, &xname) ^
117 		upper_32_bits(parent_ino) ^ lower_32_bits(parent_ino);
118 }
119 
120 /* Compute the attribute name hash from the xattr components. */
121 xfs_dahash_t
122 xfs_parent_hashattr(
123 	struct xfs_mount		*mp,
124 	const uint8_t			*name,
125 	int				namelen,
126 	const void			*value,
127 	int				valuelen)
128 {
129 	const struct xfs_parent_rec	*rec = value;
130 
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));
134 		return 0;
135 	}
136 
137 	if (!value) {
138 		ASSERT(value != NULL);
139 		return 0;
140 	}
141 
142 	return xfs_parent_hashval(mp, name, namelen, be64_to_cpu(rec->p_ino));
143 }
144 
145 /*
146  * Initialize the parent pointer arguments structure.  Caller must have zeroed
147  * the contents of @args.  @tp is only required for updates.
148  */
149 static void
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,
155 	xfs_ino_t		owner,
156 	const struct xfs_name	*parent_name)
157 {
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;
162 	args->trans = tp;
163 	args->dp = child;
164 	args->owner = owner;
165 	args->name = parent_name->name;
166 	args->namelen = parent_name->len;
167 	args->value = rec;
168 	args->valuelen = sizeof(struct xfs_parent_rec);
169 	xfs_attr_sethash(args);
170 }
171 
172 /* Make sure the incore state is ready for a parent pointer query/update. */
173 static inline int
174 xfs_parent_iread_extents(
175 	struct xfs_trans	*tp,
176 	struct xfs_inode	*child)
177 {
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;
182 	}
183 
184 	return xfs_iread_extents(tp, child, XFS_ATTR_FORK);
185 }
186 
187 /* Add a parent pointer to reflect a dirent addition. */
188 int
189 xfs_parent_addname(
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)
195 {
196 	int			error;
197 
198 	error = xfs_parent_iread_extents(tp, child);
199 	if (error)
200 		return error;
201 
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);
206 	return 0;
207 }
208 
209 /* Remove a parent pointer to reflect a dirent removal. */
210 int
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)
217 {
218 	int			error;
219 
220 	error = xfs_parent_iread_extents(tp, child);
221 	if (error)
222 		return error;
223 
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);
228 	return 0;
229 }
230 
231 /* Replace one parent pointer with another to reflect a rename. */
232 int
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)
241 {
242 	int			error;
243 
244 	error = xfs_parent_iread_extents(tp, child);
245 	if (error)
246 		return error;
247 
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);
251 
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);
258 	return 0;
259 }
260 
261 /*
262  * Extract parent pointer information from any parent pointer xattr into
263  * @parent_ino/gen.  The last two parameters can be NULL pointers.
264  *
265  * Returns 0 if this is not a parent pointer xattr at all; or -EFSCORRUPTED for
266  * garbage.
267  */
268 int
269 xfs_parent_from_attr(
270 	struct xfs_mount	*mp,
271 	unsigned int		attr_flags,
272 	const unsigned char	*name,
273 	unsigned int		namelen,
274 	const void		*value,
275 	unsigned int		valuelen,
276 	xfs_ino_t		*parent_ino,
277 	uint32_t		*parent_gen)
278 {
279 	const struct xfs_parent_rec	*rec = value;
280 
281 	ASSERT(attr_flags & XFS_ATTR_PARENT);
282 
283 	if (!xfs_parent_namecheck(attr_flags, name, namelen))
284 		return -EFSCORRUPTED;
285 	if (!xfs_parent_valuecheck(mp, value, valuelen))
286 		return -EFSCORRUPTED;
287 
288 	if (parent_ino)
289 		*parent_ino = be64_to_cpu(rec->p_ino);
290 	if (parent_gen)
291 		*parent_gen = be32_to_cpu(rec->p_gen);
292 	return 0;
293 }
294 
295 /*
296  * Look up a parent pointer record (@parent_name -> @pptr) of @ip.
297  *
298  * Caller must hold at least ILOCK_SHARED.  The scratchpad need not be
299  * initialized.
300  *
301  * Returns 0 if the pointer is found, -ENOATTR if there is no match, or a
302  * negative errno.
303  */
304 int
305 xfs_parent_lookup(
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)
311 {
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);
315 }
316 
317 /* Sanity-check a parent pointer before we try to perform repairs. */
318 static inline bool
319 xfs_parent_sanity_check(
320 	struct xfs_mount		*mp,
321 	const struct xfs_name		*parent_name,
322 	const struct xfs_parent_rec	*pptr)
323 {
324 	if (!xfs_parent_namecheck(XFS_ATTR_PARENT, parent_name->name,
325 				parent_name->len))
326 		return false;
327 
328 	if (!xfs_parent_valuecheck(mp, pptr, sizeof(*pptr)))
329 		return false;
330 
331 	return true;
332 }
333 
334 
335 /*
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.
339  */
340 int
341 xfs_parent_set(
342 	struct xfs_inode	*ip,
343 	xfs_ino_t		owner,
344 	const struct xfs_name	*parent_name,
345 	struct xfs_parent_rec	*pptr,
346 	struct xfs_da_args	*scratch)
347 {
348 	if (!xfs_parent_sanity_check(ip->i_mount, parent_name, pptr)) {
349 		ASSERT(0);
350 		return -EFSCORRUPTED;
351 	}
352 
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);
356 }
357 
358 /*
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.
362  */
363 int
364 xfs_parent_unset(
365 	struct xfs_inode		*ip,
366 	xfs_ino_t			owner,
367 	const struct xfs_name		*parent_name,
368 	struct xfs_parent_rec		*pptr,
369 	struct xfs_da_args		*scratch)
370 {
371 	if (!xfs_parent_sanity_check(ip->i_mount, parent_name, pptr)) {
372 		ASSERT(0);
373 		return -EFSCORRUPTED;
374 	}
375 
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);
379 }
380