xref: /linux/fs/xfs/scrub/parent.c (revision 1113a6d6d5d1336f4415fa1367aac0f853f0892d)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2017-2023 Oracle.  All Rights Reserved.
4  * Author: Darrick J. Wong <djwong@kernel.org>
5  */
6 #include "xfs_platform.h"
7 #include "xfs_fs.h"
8 #include "xfs_shared.h"
9 #include "xfs_format.h"
10 #include "xfs_trans_resv.h"
11 #include "xfs_mount.h"
12 #include "xfs_log_format.h"
13 #include "xfs_trans.h"
14 #include "xfs_inode.h"
15 #include "xfs_icache.h"
16 #include "xfs_dir2.h"
17 #include "xfs_dir2_priv.h"
18 #include "xfs_attr.h"
19 #include "xfs_parent.h"
20 #include "scrub/scrub.h"
21 #include "scrub/common.h"
22 #include "scrub/readdir.h"
23 #include "scrub/tempfile.h"
24 #include "scrub/repair.h"
25 #include "scrub/listxattr.h"
26 #include "scrub/xfile.h"
27 #include "scrub/xfarray.h"
28 #include "scrub/xfblob.h"
29 #include "scrub/trace.h"
30 
31 /* Set us up to scrub parents. */
32 int
33 xchk_setup_parent(
34 	struct xfs_scrub	*sc)
35 {
36 	int			error;
37 
38 	if (xchk_could_repair(sc)) {
39 		error = xrep_setup_parent(sc);
40 		if (error)
41 			return error;
42 	}
43 
44 	return xchk_setup_inode_contents(sc, 0);
45 }
46 
47 /* Parent pointers */
48 
49 /* Look for an entry in a parent pointing to this inode. */
50 
51 struct xchk_parent_ctx {
52 	struct xfs_scrub	*sc;
53 	xfs_nlink_t		nlink;
54 };
55 
56 /* Look for a single entry in a directory pointing to an inode. */
57 STATIC int
58 xchk_parent_actor(
59 	struct xfs_scrub	*sc,
60 	struct xfs_inode	*dp,
61 	xfs_dir2_dataptr_t	dapos,
62 	const struct xfs_name	*name,
63 	xfs_ino_t		ino,
64 	void			*priv)
65 {
66 	struct xchk_parent_ctx	*spc = priv;
67 	int			error = 0;
68 
69 	/* Does this name make sense? */
70 	if (!xfs_dir2_namecheck(name->name, name->len))
71 		error = -EFSCORRUPTED;
72 	if (!xchk_fblock_xref_process_error(sc, XFS_DATA_FORK, 0, &error))
73 		return error;
74 
75 	if (I_INO(sc->ip) == ino)
76 		spc->nlink++;
77 
78 	if (xchk_should_terminate(spc->sc, &error))
79 		return error;
80 
81 	return 0;
82 }
83 
84 /*
85  * Try to lock a parent directory for checking dirents.  Returns the inode
86  * flags for the locks we now hold, or zero if we failed.
87  */
88 STATIC unsigned int
89 xchk_parent_ilock_dir(
90 	struct xfs_inode	*dp)
91 {
92 	if (!xfs_ilock_nowait(dp, XFS_ILOCK_SHARED))
93 		return 0;
94 
95 	if (!xfs_need_iread_extents(&dp->i_df))
96 		return XFS_ILOCK_SHARED;
97 
98 	xfs_iunlock(dp, XFS_ILOCK_SHARED);
99 
100 	if (!xfs_ilock_nowait(dp, XFS_ILOCK_EXCL))
101 		return 0;
102 
103 	return XFS_ILOCK_EXCL;
104 }
105 
106 /*
107  * Given the inode number of the alleged parent of the inode being scrubbed,
108  * try to validate that the parent has exactly one directory entry pointing
109  * back to the inode being scrubbed.  Returns -EAGAIN if we need to revalidate
110  * the dotdot entry.
111  */
112 STATIC int
113 xchk_parent_validate(
114 	struct xfs_scrub	*sc,
115 	xfs_ino_t		parent_ino)
116 {
117 	struct xchk_parent_ctx	spc = {
118 		.sc		= sc,
119 		.nlink		= 0,
120 	};
121 	struct xfs_mount	*mp = sc->mp;
122 	xfs_ino_t		ino = I_INO(sc->ip);
123 	struct xfs_inode	*dp = NULL;
124 	xfs_nlink_t		expected_nlink;
125 	unsigned int		lock_mode;
126 	int			error = 0;
127 
128 	/* Is this the root dir?  Then '..' must point to itself. */
129 	if (sc->ip == mp->m_rootip) {
130 		if (ino != mp->m_sb.sb_rootino || ino != parent_ino)
131 			xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
132 		return 0;
133 	}
134 
135 	/* Is this the metadata root dir?  Then '..' must point to itself. */
136 	if (sc->ip == mp->m_metadirip) {
137 		if (ino != mp->m_sb.sb_metadirino || ino != parent_ino)
138 			xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
139 		return 0;
140 	}
141 
142 	/* '..' must not point to ourselves. */
143 	if (ino == parent_ino) {
144 		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
145 		return 0;
146 	}
147 
148 	/*
149 	 * If we're an unlinked directory, the parent /won't/ have a link
150 	 * to us.  Otherwise, it should have one link.
151 	 */
152 	expected_nlink = VFS_I(sc->ip)->i_nlink == 0 ? 0 : 1;
153 
154 	/*
155 	 * Grab the parent directory inode.  This must be released before we
156 	 * cancel the scrub transaction.
157 	 *
158 	 * If _iget returns -EINVAL or -ENOENT then the parent inode number is
159 	 * garbage and the directory is corrupt.  If the _iget returns
160 	 * -EFSCORRUPTED or -EFSBADCRC then the parent is corrupt which is a
161 	 *  cross referencing error.  Any other error is an operational error.
162 	 */
163 	error = xchk_iget(sc, parent_ino, &dp);
164 	if (error == -EINVAL || error == -ENOENT) {
165 		error = -EFSCORRUPTED;
166 		xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error);
167 		return error;
168 	}
169 	if (!xchk_fblock_xref_process_error(sc, XFS_DATA_FORK, 0, &error))
170 		return error;
171 	if (dp == sc->ip || xrep_is_tempfile(dp) ||
172 	    !S_ISDIR(VFS_I(dp)->i_mode)) {
173 		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
174 		goto out_rele;
175 	}
176 
177 	lock_mode = xchk_parent_ilock_dir(dp);
178 	if (!lock_mode) {
179 		xchk_iunlock(sc, XFS_ILOCK_EXCL);
180 		xchk_ilock(sc, XFS_ILOCK_EXCL);
181 		error = -EAGAIN;
182 		goto out_rele;
183 	}
184 
185 	/*
186 	 * We cannot yet validate this parent pointer if the directory looks as
187 	 * though it has been zapped by the inode record repair code.
188 	 */
189 	if (xchk_dir_looks_zapped(dp)) {
190 		error = -EBUSY;
191 		xchk_set_incomplete(sc);
192 		goto out_unlock;
193 	}
194 
195 	/* Metadata and regular inodes cannot cross trees. */
196 	if (xfs_is_metadir_inode(dp) != xfs_is_metadir_inode(sc->ip)) {
197 		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
198 		goto out_unlock;
199 	}
200 
201 	/* Look for a directory entry in the parent pointing to the child. */
202 	error = xchk_dir_walk(sc, dp, xchk_parent_actor, &spc);
203 	if (!xchk_fblock_xref_process_error(sc, XFS_DATA_FORK, 0, &error))
204 		goto out_unlock;
205 
206 	/*
207 	 * Ensure that the parent has as many links to the child as the child
208 	 * thinks it has to the parent.
209 	 */
210 	if (spc.nlink != expected_nlink)
211 		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
212 
213 out_unlock:
214 	xfs_iunlock(dp, lock_mode);
215 out_rele:
216 	xchk_irele(sc, dp);
217 	return error;
218 }
219 
220 /*
221  * Checking of Parent Pointers
222  * ===========================
223  *
224  * On filesystems with directory parent pointers, we check the referential
225  * integrity by visiting each parent pointer of a child file and checking that
226  * the directory referenced by the pointer actually has a dirent pointing
227  * forward to the child file.
228  */
229 
230 /* Deferred parent pointer entry that we saved for later. */
231 struct xchk_pptr {
232 	/* Cookie for retrieval of the pptr name. */
233 	xfblob_cookie		name_cookie;
234 
235 	/* Parent pointer record. */
236 	struct xfs_parent_rec	pptr_rec;
237 
238 	/* Length of the pptr name. */
239 	uint8_t			namelen;
240 };
241 
242 struct xchk_pptrs {
243 	struct xfs_scrub	*sc;
244 
245 	/* How many parent pointers did we find at the end? */
246 	unsigned long long	pptrs_found;
247 
248 	/* Parent of this directory. */
249 	xfs_ino_t		parent_ino;
250 
251 	/* Fixed-size array of xchk_pptr structures. */
252 	struct xfarray		*pptr_entries;
253 
254 	/* Blobs containing parent pointer names. */
255 	struct xfblob		*pptr_names;
256 
257 	/* Scratch buffer for scanning pptr xattrs */
258 	struct xfs_da_args	pptr_args;
259 
260 	/* If we've cycled the ILOCK, we must revalidate all deferred pptrs. */
261 	bool			need_revalidate;
262 
263 	/* Name buffer */
264 	struct xfs_name		xname;
265 	char			namebuf[MAXNAMELEN];
266 };
267 
268 /* Does this parent pointer match the dotdot entry? */
269 STATIC int
270 xchk_parent_scan_dotdot(
271 	struct xfs_scrub		*sc,
272 	struct xfs_inode		*ip,
273 	unsigned int			attr_flags,
274 	const unsigned char		*name,
275 	unsigned int			namelen,
276 	const void			*value,
277 	unsigned int			valuelen,
278 	void				*priv)
279 {
280 	struct xchk_pptrs		*pp = priv;
281 	xfs_ino_t			parent_ino;
282 	int				error;
283 
284 	if (!(attr_flags & XFS_ATTR_PARENT))
285 		return 0;
286 
287 	error = xfs_parent_from_attr(sc->mp, attr_flags, name, namelen, value,
288 			valuelen, &parent_ino, NULL);
289 	if (error)
290 		return error;
291 
292 	if (pp->parent_ino == parent_ino)
293 		return -ECANCELED;
294 
295 	return 0;
296 }
297 
298 /* Look up the dotdot entry so that we can check it as we walk the pptrs. */
299 STATIC int
300 xchk_parent_pptr_and_dotdot(
301 	struct xchk_pptrs	*pp)
302 {
303 	struct xfs_scrub	*sc = pp->sc;
304 	int			error;
305 
306 	/* Look up '..' */
307 	error = xchk_dir_lookup(sc, sc->ip, &xfs_name_dotdot, &pp->parent_ino);
308 	if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error))
309 		return error;
310 	if (!xfs_verify_dir_ino(sc->mp, pp->parent_ino)) {
311 		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
312 		return 0;
313 	}
314 
315 	/* Is this the root dir?  Then '..' must point to itself. */
316 	if (xchk_inode_is_dirtree_root(sc->ip)) {
317 		if (I_INO(sc->ip) != pp->parent_ino)
318 			xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
319 		return 0;
320 	}
321 
322 	/*
323 	 * If this is now an unlinked directory, the dotdot value is
324 	 * meaningless as long as it points to a valid inode.
325 	 */
326 	if (VFS_I(sc->ip)->i_nlink == 0)
327 		return 0;
328 
329 	if (pp->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
330 		return 0;
331 
332 	/* Otherwise, walk the pptrs again, and check. */
333 	error = xchk_xattr_walk(sc, sc->ip, xchk_parent_scan_dotdot, NULL, pp);
334 	if (error == -ECANCELED) {
335 		/* Found a parent pointer that matches dotdot. */
336 		return 0;
337 	}
338 	if (!error || error == -EFSCORRUPTED) {
339 		/* Found a broken parent pointer or no match. */
340 		xchk_fblock_set_corrupt(sc, XFS_ATTR_FORK, 0);
341 		return 0;
342 	}
343 	return error;
344 }
345 
346 /*
347  * Try to lock a parent directory for checking dirents.  Returns the inode
348  * flags for the locks we now hold, or zero if we failed.
349  */
350 STATIC unsigned int
351 xchk_parent_lock_dir(
352 	struct xfs_scrub	*sc,
353 	struct xfs_inode	*dp)
354 {
355 	if (!xfs_ilock_nowait(dp, XFS_IOLOCK_SHARED))
356 		return 0;
357 
358 	if (!xfs_ilock_nowait(dp, XFS_ILOCK_SHARED)) {
359 		xfs_iunlock(dp, XFS_IOLOCK_SHARED);
360 		return 0;
361 	}
362 
363 	if (!xfs_need_iread_extents(&dp->i_df))
364 		return XFS_IOLOCK_SHARED | XFS_ILOCK_SHARED;
365 
366 	xfs_iunlock(dp, XFS_ILOCK_SHARED);
367 
368 	if (!xfs_ilock_nowait(dp, XFS_ILOCK_EXCL)) {
369 		xfs_iunlock(dp, XFS_IOLOCK_SHARED);
370 		return 0;
371 	}
372 
373 	return XFS_IOLOCK_SHARED | XFS_ILOCK_EXCL;
374 }
375 
376 /* Check the forward link (dirent) associated with this parent pointer. */
377 STATIC int
378 xchk_parent_dirent(
379 	struct xchk_pptrs	*pp,
380 	const struct xfs_name	*xname,
381 	struct xfs_inode	*dp)
382 {
383 	struct xfs_scrub	*sc = pp->sc;
384 	xfs_ino_t		child_ino;
385 	int			error;
386 
387 	/*
388 	 * Use the name attached to this parent pointer to look up the
389 	 * directory entry in the alleged parent.
390 	 */
391 	error = xchk_dir_lookup(sc, dp, xname, &child_ino);
392 	if (error == -ENOENT) {
393 		xchk_fblock_xref_set_corrupt(sc, XFS_ATTR_FORK, 0);
394 		return 0;
395 	}
396 	if (!xchk_fblock_xref_process_error(sc, XFS_ATTR_FORK, 0, &error))
397 		return error;
398 
399 	/* Does the inode number match? */
400 	if (child_ino != I_INO(sc->ip)) {
401 		xchk_fblock_xref_set_corrupt(sc, XFS_ATTR_FORK, 0);
402 		return 0;
403 	}
404 
405 	return 0;
406 }
407 
408 /* Try to grab a parent directory. */
409 STATIC int
410 xchk_parent_iget(
411 	struct xchk_pptrs	*pp,
412 	const struct xfs_parent_rec	*pptr,
413 	struct xfs_inode	**dpp)
414 {
415 	struct xfs_scrub	*sc = pp->sc;
416 	struct xfs_inode	*ip;
417 	xfs_ino_t		parent_ino = be64_to_cpu(pptr->p_ino);
418 	int			error;
419 
420 	/* Validate inode number. */
421 	error = xfs_dir_ino_validate(sc->mp, parent_ino);
422 	if (error) {
423 		xchk_fblock_set_corrupt(sc, XFS_ATTR_FORK, 0);
424 		return -ECANCELED;
425 	}
426 
427 	error = xchk_iget(sc, parent_ino, &ip);
428 	if (error == -EINVAL || error == -ENOENT) {
429 		xchk_fblock_set_corrupt(sc, XFS_ATTR_FORK, 0);
430 		return -ECANCELED;
431 	}
432 	if (!xchk_fblock_xref_process_error(sc, XFS_ATTR_FORK, 0, &error))
433 		return error;
434 
435 	/* The parent must be a directory. */
436 	if (!S_ISDIR(VFS_I(ip)->i_mode)) {
437 		xchk_fblock_xref_set_corrupt(sc, XFS_ATTR_FORK, 0);
438 		goto out_rele;
439 	}
440 
441 	/* Validate generation number. */
442 	if (VFS_I(ip)->i_generation != be32_to_cpu(pptr->p_gen)) {
443 		xchk_fblock_xref_set_corrupt(sc, XFS_ATTR_FORK, 0);
444 		goto out_rele;
445 	}
446 
447 	*dpp = ip;
448 	return 0;
449 out_rele:
450 	xchk_irele(sc, ip);
451 	return 0;
452 }
453 
454 /*
455  * Walk an xattr of a file.  If this xattr is a parent pointer, follow it up
456  * to a parent directory and check that the parent has a dirent pointing back
457  * to us.
458  */
459 STATIC int
460 xchk_parent_scan_attr(
461 	struct xfs_scrub	*sc,
462 	struct xfs_inode	*ip,
463 	unsigned int		attr_flags,
464 	const unsigned char	*name,
465 	unsigned int		namelen,
466 	const void		*value,
467 	unsigned int		valuelen,
468 	void			*priv)
469 {
470 	struct xfs_name		xname = {
471 		.name		= name,
472 		.len		= namelen,
473 	};
474 	struct xchk_pptrs	*pp = priv;
475 	struct xfs_inode	*dp = NULL;
476 	const struct xfs_parent_rec *pptr_rec = value;
477 	xfs_ino_t		parent_ino;
478 	unsigned int		lockmode;
479 	int			error;
480 
481 	if (!(attr_flags & XFS_ATTR_PARENT))
482 		return 0;
483 
484 	error = xfs_parent_from_attr(sc->mp, attr_flags, name, namelen, value,
485 			valuelen, &parent_ino, NULL);
486 	if (error) {
487 		xchk_fblock_set_corrupt(sc, XFS_ATTR_FORK, 0);
488 		return error;
489 	}
490 
491 	/* No self-referential parent pointers. */
492 	if (parent_ino == I_INO(sc->ip)) {
493 		xchk_fblock_set_corrupt(sc, XFS_ATTR_FORK, 0);
494 		return -ECANCELED;
495 	}
496 
497 	pp->pptrs_found++;
498 
499 	error = xchk_parent_iget(pp, pptr_rec, &dp);
500 	if (error)
501 		return error;
502 	if (!dp)
503 		return 0;
504 
505 	/* Try to lock the inode. */
506 	lockmode = xchk_parent_lock_dir(sc, dp);
507 	if (!lockmode) {
508 		struct xchk_pptr	save_pp = {
509 			.pptr_rec	= *pptr_rec, /* struct copy */
510 			.namelen	= namelen,
511 		};
512 
513 		/* Couldn't lock the inode, so save the pptr for later. */
514 		trace_xchk_parent_defer(sc->ip, &xname, I_INO(dp));
515 
516 		error = xfblob_storename(pp->pptr_names, &save_pp.name_cookie,
517 				&xname);
518 		if (!xchk_fblock_xref_process_error(sc, XFS_ATTR_FORK, 0,
519 					&error))
520 			goto out_rele;
521 
522 		error = xfarray_append(pp->pptr_entries, &save_pp);
523 		if (!xchk_fblock_xref_process_error(sc, XFS_ATTR_FORK, 0,
524 					&error))
525 			goto out_rele;
526 
527 		goto out_rele;
528 	}
529 
530 	error = xchk_parent_dirent(pp, &xname, dp);
531 	if (error)
532 		goto out_unlock;
533 
534 out_unlock:
535 	xfs_iunlock(dp, lockmode);
536 out_rele:
537 	xchk_irele(sc, dp);
538 	return error;
539 }
540 
541 /*
542  * Revalidate a parent pointer that we collected in the past but couldn't check
543  * because of lock contention.  Returns 0 if the parent pointer is still valid,
544  * -ENOENT if it has gone away on us, or a negative errno.
545  */
546 STATIC int
547 xchk_parent_revalidate_pptr(
548 	struct xchk_pptrs		*pp,
549 	const struct xfs_name		*xname,
550 	struct xfs_parent_rec		*pptr)
551 {
552 	struct xfs_scrub		*sc = pp->sc;
553 	int				error;
554 
555 	error = xfs_parent_lookup(sc->tp, sc->ip, xname, pptr, &pp->pptr_args);
556 	if (error == -ENOATTR) {
557 		/* Parent pointer went away, nothing to revalidate. */
558 		return -ENOENT;
559 	}
560 
561 	return error;
562 }
563 
564 /*
565  * Check a parent pointer the slow way, which means we cycle locks a bunch
566  * and put up with revalidation until we get it done.
567  */
568 STATIC int
569 xchk_parent_slow_pptr(
570 	struct xchk_pptrs	*pp,
571 	const struct xfs_name	*xname,
572 	struct xfs_parent_rec	*pptr)
573 {
574 	struct xfs_scrub	*sc = pp->sc;
575 	struct xfs_inode	*dp = NULL;
576 	unsigned int		lockmode;
577 	int			error;
578 
579 	/* Check that the deferred parent pointer still exists. */
580 	if (pp->need_revalidate) {
581 		error = xchk_parent_revalidate_pptr(pp, xname, pptr);
582 		if (error == -ENOENT)
583 			return 0;
584 		if (!xchk_fblock_xref_process_error(sc, XFS_ATTR_FORK, 0,
585 					&error))
586 			return error;
587 	}
588 
589 	error = xchk_parent_iget(pp, pptr, &dp);
590 	if (error)
591 		return error;
592 	if (!dp)
593 		return 0;
594 
595 	/*
596 	 * If we can grab both IOLOCK and ILOCK of the alleged parent, we
597 	 * can proceed with the validation.
598 	 */
599 	lockmode = xchk_parent_lock_dir(sc, dp);
600 	if (lockmode) {
601 		trace_xchk_parent_slowpath(sc->ip, xname, I_INO(dp));
602 		goto check_dirent;
603 	}
604 
605 	/*
606 	 * We couldn't lock the parent dir.  Drop all the locks and try to
607 	 * get them again, one at a time.
608 	 */
609 	xchk_iunlock(sc, sc->ilock_flags);
610 	pp->need_revalidate = true;
611 
612 	trace_xchk_parent_ultraslowpath(sc->ip, xname, I_INO(dp));
613 
614 	error = xchk_dir_trylock_for_pptrs(sc, dp, &lockmode);
615 	if (error)
616 		goto out_rele;
617 
618 	/* Revalidate the parent pointer now that we cycled locks. */
619 	error = xchk_parent_revalidate_pptr(pp, xname, pptr);
620 	if (error == -ENOENT) {
621 		error = 0;
622 		goto out_unlock;
623 	}
624 	if (!xchk_fblock_xref_process_error(sc, XFS_ATTR_FORK, 0, &error))
625 		goto out_unlock;
626 
627 check_dirent:
628 	error = xchk_parent_dirent(pp, xname, dp);
629 out_unlock:
630 	xfs_iunlock(dp, lockmode);
631 out_rele:
632 	xchk_irele(sc, dp);
633 	return error;
634 }
635 
636 /* Check all the parent pointers that we deferred the first time around. */
637 STATIC int
638 xchk_parent_finish_slow_pptrs(
639 	struct xchk_pptrs	*pp)
640 {
641 	xfarray_idx_t		array_cur;
642 	int			error;
643 
644 	foreach_xfarray_idx(pp->pptr_entries, array_cur) {
645 		struct xchk_pptr	pptr;
646 
647 		if (pp->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
648 			return 0;
649 
650 		error = xfarray_load(pp->pptr_entries, array_cur, &pptr);
651 		if (error)
652 			return error;
653 
654 		error = xfblob_loadname(pp->pptr_names, pptr.name_cookie,
655 				&pp->xname, pptr.namelen);
656 		if (error)
657 			return error;
658 
659 		error = xchk_parent_slow_pptr(pp, &pp->xname, &pptr.pptr_rec);
660 		if (error)
661 			return error;
662 	}
663 
664 	/* Empty out both xfiles now that we've checked everything. */
665 	xfarray_truncate(pp->pptr_entries);
666 	xfblob_truncate(pp->pptr_names);
667 	return 0;
668 }
669 
670 /* Count the number of parent pointers. */
671 STATIC int
672 xchk_parent_count_pptr(
673 	struct xfs_scrub		*sc,
674 	struct xfs_inode		*ip,
675 	unsigned int			attr_flags,
676 	const unsigned char		*name,
677 	unsigned int			namelen,
678 	const void			*value,
679 	unsigned int			valuelen,
680 	void				*priv)
681 {
682 	struct xchk_pptrs		*pp = priv;
683 	int				error;
684 
685 	if (!(attr_flags & XFS_ATTR_PARENT))
686 		return 0;
687 
688 	error = xfs_parent_from_attr(sc->mp, attr_flags, name, namelen, value,
689 			valuelen, NULL, NULL);
690 	if (error)
691 		return error;
692 
693 	pp->pptrs_found++;
694 	return 0;
695 }
696 
697 /*
698  * Compare the number of parent pointers to the link count.  For
699  * non-directories these should be the same.  For unlinked directories the
700  * count should be zero; for linked directories, it should be nonzero.
701  */
702 STATIC int
703 xchk_parent_count_pptrs(
704 	struct xchk_pptrs	*pp)
705 {
706 	struct xfs_scrub	*sc = pp->sc;
707 	int			error;
708 
709 	/*
710 	 * If we cycled the ILOCK while cross-checking parent pointers with
711 	 * dirents, then we need to recalculate the number of parent pointers.
712 	 */
713 	if (pp->need_revalidate) {
714 		pp->pptrs_found = 0;
715 		error = xchk_xattr_walk(sc, sc->ip, xchk_parent_count_pptr,
716 				NULL, pp);
717 		if (error == -EFSCORRUPTED) {
718 			/* Found a bad parent pointer */
719 			xchk_fblock_set_corrupt(sc, XFS_ATTR_FORK, 0);
720 			return 0;
721 		}
722 		if (error)
723 			return error;
724 	}
725 
726 	if (S_ISDIR(VFS_I(sc->ip)->i_mode)) {
727 		if (xchk_inode_is_dirtree_root(sc->ip))
728 			pp->pptrs_found++;
729 
730 		if (VFS_I(sc->ip)->i_nlink == 0 && pp->pptrs_found > 0)
731 			xchk_ip_set_corrupt(sc, sc->ip);
732 		else if (VFS_I(sc->ip)->i_nlink > 0 &&
733 			 pp->pptrs_found == 0)
734 			xchk_ip_set_corrupt(sc, sc->ip);
735 	} else {
736 		/*
737 		 * Starting with metadir, we allow checking of parent pointers
738 		 * of non-directory files that are children of the superblock.
739 		 * Pretend that we found a parent pointer attr.
740 		 */
741 		if (xfs_has_metadir(sc->mp) && xchk_inode_is_sb_rooted(sc->ip))
742 			pp->pptrs_found++;
743 
744 		if (VFS_I(sc->ip)->i_nlink != pp->pptrs_found)
745 			xchk_ip_set_corrupt(sc, sc->ip);
746 	}
747 
748 	return 0;
749 }
750 
751 /* Check parent pointers of a file. */
752 STATIC int
753 xchk_parent_pptr(
754 	struct xfs_scrub	*sc)
755 {
756 	struct xchk_pptrs	*pp;
757 	int			error;
758 
759 	pp = kvzalloc_obj(struct xchk_pptrs, XCHK_GFP_FLAGS);
760 	if (!pp)
761 		return -ENOMEM;
762 	pp->sc = sc;
763 	pp->xname.name = pp->namebuf;
764 
765 	/*
766 	 * Set up some staging memory for parent pointers that we can't check
767 	 * due to locking contention.
768 	 */
769 	error = xfarray_create("slow parent pointer entries", 0,
770 			sizeof(struct xchk_pptr), &pp->pptr_entries);
771 	if (error)
772 		goto out_pp;
773 
774 	error = xfblob_create("slow parent pointer names", &pp->pptr_names);
775 	if (error)
776 		goto out_entries;
777 
778 	error = xchk_xattr_walk(sc, sc->ip, xchk_parent_scan_attr, NULL, pp);
779 	if (error == -ECANCELED) {
780 		error = 0;
781 		goto out_names;
782 	}
783 	if (error)
784 		goto out_names;
785 
786 	error = xchk_parent_finish_slow_pptrs(pp);
787 	if (error == -ETIMEDOUT) {
788 		/* Couldn't grab a lock, scrub was marked incomplete */
789 		error = 0;
790 		goto out_names;
791 	}
792 	if (error)
793 		goto out_names;
794 
795 	if (pp->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
796 		goto out_names;
797 
798 	/*
799 	 * For subdirectories, make sure the dotdot entry references the same
800 	 * inode as the parent pointers.
801 	 *
802 	 * If we're scanning a /consistent/ directory, there should only be
803 	 * one parent pointer, and it should point to the same directory as
804 	 * the dotdot entry.
805 	 *
806 	 * However, a corrupt directory tree might feature a subdirectory with
807 	 * multiple parents.  The directory loop scanner is responsible for
808 	 * correcting that kind of problem, so for now we only validate that
809 	 * the dotdot entry matches /one/ of the parents.
810 	 */
811 	if (S_ISDIR(VFS_I(sc->ip)->i_mode)) {
812 		error = xchk_parent_pptr_and_dotdot(pp);
813 		if (error)
814 			goto out_names;
815 	}
816 
817 	if (pp->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
818 		goto out_names;
819 
820 	/*
821 	 * Complain if the number of parent pointers doesn't match the link
822 	 * count.  This could be a sign of missing parent pointers (or an
823 	 * incorrect link count).
824 	 */
825 	error = xchk_parent_count_pptrs(pp);
826 	if (error)
827 		goto out_names;
828 
829 out_names:
830 	xfblob_destroy(pp->pptr_names);
831 out_entries:
832 	xfarray_destroy(pp->pptr_entries);
833 out_pp:
834 	kvfree(pp);
835 	return error;
836 }
837 
838 /* Scrub a parent pointer. */
839 int
840 xchk_parent(
841 	struct xfs_scrub	*sc)
842 {
843 	struct xfs_mount	*mp = sc->mp;
844 	xfs_ino_t		parent_ino;
845 	int			error = 0;
846 
847 	if (xfs_has_parent(mp))
848 		return xchk_parent_pptr(sc);
849 
850 	/*
851 	 * If we're a directory, check that the '..' link points up to
852 	 * a directory that has one entry pointing to us.
853 	 */
854 	if (!S_ISDIR(VFS_I(sc->ip)->i_mode))
855 		return -ENOENT;
856 
857 	/* We're not a special inode, are we? */
858 	if (!xfs_verify_dir_ino(mp, I_INO(sc->ip))) {
859 		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
860 		return 0;
861 	}
862 
863 	do {
864 		if (xchk_should_terminate(sc, &error))
865 			break;
866 
867 		/* Look up '..' */
868 		error = xchk_dir_lookup(sc, sc->ip, &xfs_name_dotdot,
869 				&parent_ino);
870 		if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error))
871 			return error;
872 		if (!xfs_verify_dir_ino(mp, parent_ino)) {
873 			xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
874 			return 0;
875 		}
876 
877 		/*
878 		 * Check that the dotdot entry points to a parent directory
879 		 * containing a dirent pointing to this subdirectory.
880 		 */
881 		error = xchk_parent_validate(sc, parent_ino);
882 	} while (error == -EAGAIN);
883 	if (error == -EBUSY) {
884 		/*
885 		 * We could not scan a directory, so we marked the check
886 		 * incomplete.  No further error return is necessary.
887 		 */
888 		return 0;
889 	}
890 
891 	return error;
892 }
893 
894 /*
895  * Decide if this file's extended attributes (and therefore its parent
896  * pointers) have been zapped to satisfy the inode and ifork verifiers.
897  * Checking and repairing should be postponed until the extended attribute
898  * structure is fixed.
899  */
900 bool
901 xchk_pptr_looks_zapped(
902 	struct xfs_inode	*ip)
903 {
904 	struct inode		*inode = VFS_I(ip);
905 
906 	ASSERT(xfs_has_parent(ip->i_mount));
907 
908 	/*
909 	 * Temporary files that cannot be linked into the directory tree do not
910 	 * have attr forks because they cannot ever have parents.
911 	 */
912 	if (inode->i_nlink == 0 && !(inode_state_read_once(inode) & I_LINKABLE))
913 		return false;
914 
915 	/*
916 	 * Directory tree roots do not have parents, so the expected outcome
917 	 * of a parent pointer scan is always the empty set.  It's safe to scan
918 	 * them even if the attr fork was zapped.
919 	 */
920 	if (xchk_inode_is_dirtree_root(ip))
921 		return false;
922 
923 	/*
924 	 * Metadata inodes that are rooted in the superblock do not have any
925 	 * parents.  Hence the attr fork will not be initialized, but there are
926 	 * no parent pointers that might have been zapped.
927 	 */
928 	if (xchk_inode_is_sb_rooted(ip))
929 		return false;
930 
931 	/*
932 	 * Linked and linkable non-rootdir files should always have an
933 	 * attribute fork because that is where parent pointers are
934 	 * stored.  If the fork is absent, something is amiss.
935 	 */
936 	if (!xfs_inode_has_attr_fork(ip))
937 		return true;
938 
939 	/* Repair zapped this file's attr fork a short time ago */
940 	if (xfs_ifork_zapped(ip, XFS_ATTR_FORK))
941 		return true;
942 
943 	/*
944 	 * If the dinode repair found a bad attr fork, it will reset the fork
945 	 * to extents format with zero records and wait for the bmapbta
946 	 * scrubber to reconstruct the block mappings.  The extended attribute
947 	 * structure always contain some content when parent pointers are
948 	 * enabled, so this is a clear sign of a zapped attr fork.
949 	 */
950 	return ip->i_af.if_format == XFS_DINODE_FMT_EXTENTS &&
951 	       ip->i_af.if_nextents == 0;
952 }
953