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
xchk_setup_parent(struct xfs_scrub * sc)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
xchk_parent_actor(struct xfs_scrub * sc,struct xfs_inode * dp,xfs_dir2_dataptr_t dapos,const struct xfs_name * name,xfs_ino_t ino,void * priv)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
xchk_parent_ilock_dir(struct xfs_inode * dp)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
xchk_parent_validate(struct xfs_scrub * sc,xfs_ino_t parent_ino)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
xchk_parent_scan_dotdot(struct xfs_scrub * sc,struct xfs_inode * ip,unsigned int attr_flags,const unsigned char * name,unsigned int namelen,const void * value,unsigned int valuelen,void * priv)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
xchk_parent_pptr_and_dotdot(struct xchk_pptrs * pp)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
xchk_parent_lock_dir(struct xfs_scrub * sc,struct xfs_inode * dp)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
xchk_parent_dirent(struct xchk_pptrs * pp,const struct xfs_name * xname,struct xfs_inode * dp)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
xchk_parent_iget(struct xchk_pptrs * pp,const struct xfs_parent_rec * pptr,struct xfs_inode ** dpp)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
xchk_parent_scan_attr(struct xfs_scrub * sc,struct xfs_inode * ip,unsigned int attr_flags,const unsigned char * name,unsigned int namelen,const void * value,unsigned int valuelen,void * priv)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 -ECANCELED;
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
xchk_parent_revalidate_pptr(struct xchk_pptrs * pp,const struct xfs_name * xname,struct xfs_parent_rec * pptr)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
xchk_parent_slow_pptr(struct xchk_pptrs * pp,const struct xfs_name * xname,struct xfs_parent_rec * pptr)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
xchk_parent_finish_slow_pptrs(struct xchk_pptrs * pp)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
xchk_parent_count_pptr(struct xfs_scrub * sc,struct xfs_inode * ip,unsigned int attr_flags,const unsigned char * name,unsigned int namelen,const void * value,unsigned int valuelen,void * priv)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
xchk_parent_count_pptrs(struct xchk_pptrs * pp)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
xchk_parent_pptr(struct xfs_scrub * sc)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
xchk_parent(struct xfs_scrub * sc)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
xchk_pptr_looks_zapped(struct xfs_inode * ip)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