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