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