xref: /linux/fs/xfs/libxfs/xfs_parent.c (revision 6f7e6393d1ce636bb7ec77a7fe7b77458fddf701)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2022-2024 Oracle.
4  * All rights reserved.
5  */
6 #include "xfs_platform.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 #include "xfs_attr_leaf.h"
33 
34 struct kmem_cache		*xfs_parent_args_cache;
35 
36 /*
37  * Parent pointer attribute handling.
38  *
39  * Because the attribute name is a filename component, it will never be longer
40  * than 255 bytes and must not contain nulls or slashes.  These are roughly the
41  * same constraints that apply to attribute names.
42  *
43  * The attribute value must always be a struct xfs_parent_rec.  This means the
44  * attribute will never be in remote format because 12 bytes is nowhere near
45  * xfs_attr_leaf_entsize_local_max() (~75% of block size).
46  *
47  * Creating a new parent attribute will always create a new attribute - there
48  * should never, ever be an existing attribute in the tree for a new inode.
49  * ENOSPC behavior is problematic - creating the inode without the parent
50  * pointer is effectively a corruption, so we allow parent attribute creation
51  * to dip into the reserve block pool to avoid unexpected ENOSPC errors from
52  * occurring.
53  */
54 
55 /* Return true if parent pointer attr name is valid. */
56 bool
57 xfs_parent_namecheck(
58 	unsigned int			attr_flags,
59 	const void			*name,
60 	size_t				length)
61 {
62 	/*
63 	 * Parent pointers always use logged operations, so there should never
64 	 * be incomplete xattrs.
65 	 */
66 	if (attr_flags & XFS_ATTR_INCOMPLETE)
67 		return false;
68 
69 	return xfs_dir2_namecheck(name, length);
70 }
71 
72 /* Return true if parent pointer attr value is valid. */
73 bool
74 xfs_parent_valuecheck(
75 	struct xfs_mount		*mp,
76 	const void			*value,
77 	size_t				valuelen)
78 {
79 	const struct xfs_parent_rec	*rec = value;
80 
81 	if (!xfs_has_parent(mp))
82 		return false;
83 
84 	/* The xattr value must be a parent record. */
85 	if (valuelen != sizeof(struct xfs_parent_rec))
86 		return false;
87 
88 	/* The parent record must be local. */
89 	if (value == NULL)
90 		return false;
91 
92 	/* The parent inumber must be valid. */
93 	if (!xfs_verify_dir_ino(mp, be64_to_cpu(rec->p_ino)))
94 		return false;
95 
96 	return true;
97 }
98 
99 /* Compute the attribute name hash for a parent pointer. */
100 xfs_dahash_t
101 xfs_parent_hashval(
102 	struct xfs_mount		*mp,
103 	const uint8_t			*name,
104 	int				namelen,
105 	xfs_ino_t			parent_ino)
106 {
107 	struct xfs_name			xname = {
108 		.name			= name,
109 		.len			= namelen,
110 	};
111 
112 	/*
113 	 * Use the same dirent name hash as would be used on the directory, but
114 	 * mix in the parent inode number to avoid collisions on hardlinked
115 	 * files with identical names but different parents.
116 	 */
117 	return xfs_dir2_hashname(mp, &xname) ^
118 		upper_32_bits(parent_ino) ^ lower_32_bits(parent_ino);
119 }
120 
121 /* Compute the attribute name hash from the xattr components. */
122 xfs_dahash_t
123 xfs_parent_hashattr(
124 	struct xfs_mount		*mp,
125 	const uint8_t			*name,
126 	int				namelen,
127 	const void			*value,
128 	int				valuelen)
129 {
130 	const struct xfs_parent_rec	*rec = value;
131 
132 	/* Requires a local attr value in xfs_parent_rec format */
133 	if (valuelen != sizeof(struct xfs_parent_rec)) {
134 		ASSERT(valuelen == sizeof(struct xfs_parent_rec));
135 		return 0;
136 	}
137 
138 	if (!value) {
139 		ASSERT(value != NULL);
140 		return 0;
141 	}
142 
143 	return xfs_parent_hashval(mp, name, namelen, be64_to_cpu(rec->p_ino));
144 }
145 
146 /*
147  * Initialize the parent pointer arguments structure.  Caller must have zeroed
148  * the contents of @args.  @tp is only required for updates.
149  */
150 static void
151 xfs_parent_da_args_init(
152 	struct xfs_da_args	*args,
153 	struct xfs_trans	*tp,
154 	struct xfs_parent_rec	*rec,
155 	struct xfs_inode	*child,
156 	xfs_ino_t		owner,
157 	const struct xfs_name	*parent_name)
158 {
159 	args->geo = child->i_mount->m_attr_geo;
160 	args->whichfork = XFS_ATTR_FORK;
161 	args->attr_filter = XFS_ATTR_PARENT;
162 	args->op_flags = XFS_DA_OP_LOGGED | XFS_DA_OP_OKNOENT;
163 	args->trans = tp;
164 	args->dp = child;
165 	args->owner = owner;
166 	args->name = parent_name->name;
167 	args->namelen = parent_name->len;
168 	args->value = rec;
169 	args->valuelen = sizeof(struct xfs_parent_rec);
170 	xfs_attr_sethash(args);
171 }
172 
173 /* Make sure the incore state is ready for a parent pointer query/update. */
174 static inline int
175 xfs_parent_iread_extents(
176 	struct xfs_trans	*tp,
177 	struct xfs_inode	*child)
178 {
179 	/* Parent pointers require that the attr fork must exist. */
180 	if (XFS_IS_CORRUPT(child->i_mount, !xfs_inode_has_attr_fork(child))) {
181 		xfs_inode_mark_sick(child, XFS_SICK_INO_PARENT);
182 		return -EFSCORRUPTED;
183 	}
184 
185 	return xfs_iread_extents(tp, child, XFS_ATTR_FORK);
186 }
187 
188 /* Add a parent pointer to reflect a dirent addition. */
189 int
190 xfs_parent_addname(
191 	struct xfs_trans	*tp,
192 	struct xfs_parent_args	*ppargs,
193 	struct xfs_inode	*dp,
194 	const struct xfs_name	*parent_name,
195 	struct xfs_inode	*child)
196 {
197 	int			error;
198 
199 	error = xfs_parent_iread_extents(tp, child);
200 	if (error)
201 		return error;
202 
203 	xfs_inode_to_parent_rec(&ppargs->rec, dp);
204 	xfs_parent_da_args_init(&ppargs->args, tp, &ppargs->rec, child,
205 			child->i_ino, parent_name);
206 
207 	return xfs_attr_setname(&ppargs->args, 0);
208 }
209 
210 /* Remove a parent pointer to reflect a dirent removal. */
211 int
212 xfs_parent_removename(
213 	struct xfs_trans	*tp,
214 	struct xfs_parent_args	*ppargs,
215 	struct xfs_inode	*dp,
216 	const struct xfs_name	*parent_name,
217 	struct xfs_inode	*child)
218 {
219 	int			error;
220 
221 	error = xfs_parent_iread_extents(tp, child);
222 	if (error)
223 		return error;
224 
225 	xfs_inode_to_parent_rec(&ppargs->rec, dp);
226 	xfs_parent_da_args_init(&ppargs->args, tp, &ppargs->rec, child,
227 			child->i_ino, parent_name);
228 
229 	return xfs_attr_removename(&ppargs->args);
230 }
231 
232 /* Replace one parent pointer with another to reflect a rename. */
233 int
234 xfs_parent_replacename(
235 	struct xfs_trans	*tp,
236 	struct xfs_parent_args	*ppargs,
237 	struct xfs_inode	*old_dp,
238 	const struct xfs_name	*old_name,
239 	struct xfs_inode	*new_dp,
240 	const struct xfs_name	*new_name,
241 	struct xfs_inode	*child)
242 {
243 	int			error;
244 
245 	error = xfs_parent_iread_extents(tp, child);
246 	if (error)
247 		return error;
248 
249 	xfs_inode_to_parent_rec(&ppargs->rec, old_dp);
250 	xfs_parent_da_args_init(&ppargs->args, tp, &ppargs->rec, child,
251 			child->i_ino, old_name);
252 
253 	xfs_inode_to_parent_rec(&ppargs->new_rec, new_dp);
254 
255 	ppargs->args.new_name = new_name->name;
256 	ppargs->args.new_namelen = new_name->len;
257 	ppargs->args.new_value = &ppargs->new_rec;
258 	ppargs->args.new_valuelen = sizeof(struct xfs_parent_rec);
259 
260 	return xfs_attr_replacename(&ppargs->args, 0);
261 }
262 
263 /*
264  * Extract parent pointer information from any parent pointer xattr into
265  * @parent_ino/gen.  The last two parameters can be NULL pointers.
266  *
267  * Returns 0 if this is not a parent pointer xattr at all; or -EFSCORRUPTED for
268  * garbage.
269  */
270 int
271 xfs_parent_from_attr(
272 	struct xfs_mount	*mp,
273 	unsigned int		attr_flags,
274 	const unsigned char	*name,
275 	unsigned int		namelen,
276 	const void		*value,
277 	unsigned int		valuelen,
278 	xfs_ino_t		*parent_ino,
279 	uint32_t		*parent_gen)
280 {
281 	const struct xfs_parent_rec	*rec = value;
282 
283 	ASSERT(attr_flags & XFS_ATTR_PARENT);
284 
285 	if (!xfs_parent_namecheck(attr_flags, name, namelen))
286 		return -EFSCORRUPTED;
287 	if (!xfs_parent_valuecheck(mp, value, valuelen))
288 		return -EFSCORRUPTED;
289 
290 	if (parent_ino)
291 		*parent_ino = be64_to_cpu(rec->p_ino);
292 	if (parent_gen)
293 		*parent_gen = be32_to_cpu(rec->p_gen);
294 	return 0;
295 }
296 
297 /*
298  * Look up a parent pointer record (@parent_name -> @pptr) of @ip.
299  *
300  * Caller must hold at least ILOCK_SHARED.  The scratchpad need not be
301  * initialized.
302  *
303  * Returns 0 if the pointer is found, -ENOATTR if there is no match, or a
304  * negative errno.
305  */
306 int
307 xfs_parent_lookup(
308 	struct xfs_trans		*tp,
309 	struct xfs_inode		*ip,
310 	const struct xfs_name		*parent_name,
311 	struct xfs_parent_rec		*pptr,
312 	struct xfs_da_args		*scratch)
313 {
314 	memset(scratch, 0, sizeof(struct xfs_da_args));
315 	xfs_parent_da_args_init(scratch, tp, pptr, ip, ip->i_ino, parent_name);
316 	return xfs_attr_get_ilocked(scratch);
317 }
318 
319 /* Sanity-check a parent pointer before we try to perform repairs. */
320 static inline bool
321 xfs_parent_sanity_check(
322 	struct xfs_mount		*mp,
323 	const struct xfs_name		*parent_name,
324 	const struct xfs_parent_rec	*pptr)
325 {
326 	if (!xfs_parent_namecheck(XFS_ATTR_PARENT, parent_name->name,
327 				parent_name->len))
328 		return false;
329 
330 	if (!xfs_parent_valuecheck(mp, pptr, sizeof(*pptr)))
331 		return false;
332 
333 	return true;
334 }
335 
336 
337 /*
338  * Attach the parent pointer (@parent_name -> @pptr) to @ip immediately.
339  * Caller must not have a transaction or hold the ILOCK.  This is for
340  * specialized repair functions only.  The scratchpad need not be initialized.
341  */
342 int
343 xfs_parent_set(
344 	struct xfs_inode	*ip,
345 	xfs_ino_t		owner,
346 	const struct xfs_name	*parent_name,
347 	struct xfs_parent_rec	*pptr,
348 	struct xfs_da_args	*scratch)
349 {
350 	if (!xfs_parent_sanity_check(ip->i_mount, parent_name, pptr)) {
351 		ASSERT(0);
352 		return -EFSCORRUPTED;
353 	}
354 
355 	memset(scratch, 0, sizeof(struct xfs_da_args));
356 	xfs_parent_da_args_init(scratch, NULL, pptr, ip, owner, parent_name);
357 	return xfs_attr_set(scratch, XFS_ATTRUPDATE_CREATE, false);
358 }
359 
360 /*
361  * Remove the parent pointer (@parent_name -> @pptr) from @ip immediately.
362  * Caller must not have a transaction or hold the ILOCK.  This is for
363  * specialized repair functions only.  The scratchpad need not be initialized.
364  */
365 int
366 xfs_parent_unset(
367 	struct xfs_inode		*ip,
368 	xfs_ino_t			owner,
369 	const struct xfs_name		*parent_name,
370 	struct xfs_parent_rec		*pptr,
371 	struct xfs_da_args		*scratch)
372 {
373 	if (!xfs_parent_sanity_check(ip->i_mount, parent_name, pptr)) {
374 		ASSERT(0);
375 		return -EFSCORRUPTED;
376 	}
377 
378 	memset(scratch, 0, sizeof(struct xfs_da_args));
379 	xfs_parent_da_args_init(scratch, NULL, pptr, ip, owner, parent_name);
380 	return xfs_attr_set(scratch, XFS_ATTRUPDATE_REMOVE, false);
381 }
382