1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2023-2024 Oracle. All Rights Reserved.
4 * Author: Darrick J. Wong <[email protected]>
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/bitmap.h"
23 #include "scrub/ino_bitmap.h"
24 #include "scrub/xfile.h"
25 #include "scrub/xfarray.h"
26 #include "scrub/xfblob.h"
27 #include "scrub/listxattr.h"
28 #include "scrub/trace.h"
29 #include "scrub/repair.h"
30 #include "scrub/orphanage.h"
31 #include "scrub/dirtree.h"
32
33 /*
34 * Directory Tree Structure Validation
35 * ===================================
36 *
37 * Validating the tree qualities of the directory tree structure can be
38 * difficult. If the tree is frozen, running a depth (or breadth) first search
39 * and marking a bitmap suffices to determine if there is a cycle. XORing the
40 * mark bitmap with the inode bitmap afterwards tells us if there are
41 * disconnected cycles. If the tree is not frozen, directory updates can move
42 * subtrees across the scanner wavefront, which complicates the design greatly.
43 *
44 * Directory parent pointers change that by enabling an incremental approach to
45 * validation of the tree structure. Instead of using one thread to scan the
46 * entire filesystem, we instead can have multiple threads walking individual
47 * subdirectories upwards to the root. In a perfect world, the IOLOCK would
48 * suffice to stabilize two directories in a parent -> child relationship.
49 * Unfortunately, the VFS does not take the IOLOCK when moving a child
50 * subdirectory, so we instead synchronize on ILOCK and use dirent update hooks
51 * to detect a race. If a race occurs in a path, we restart the scan.
52 *
53 * If the walk terminates without reaching the root, we know the path is
54 * disconnected and ought to be attached to the lost and found. If on the walk
55 * we find the same subdir that we're scanning, we know this is a cycle and
56 * should delete an incoming edge. If we find multiple paths to the root, we
57 * know to delete an incoming edge.
58 *
59 * There are two big hitches with this approach: first, all file link counts
60 * must be correct to prevent other writers from doing the wrong thing with the
61 * directory tree structure. Second, because we're walking upwards in a tree
62 * of arbitrary depth, we cannot hold all the ILOCKs. Instead, we will use a
63 * directory update hook to invalidate the scan results if one of the paths
64 * we've scanned has changed.
65 */
66
67 /* Clean up the dirtree checking resources. */
68 STATIC void
xchk_dirtree_buf_cleanup(void * buf)69 xchk_dirtree_buf_cleanup(
70 void *buf)
71 {
72 struct xchk_dirtree *dl = buf;
73 struct xchk_dirpath *path, *n;
74
75 if (dl->scan_ino != NULLFSINO)
76 xfs_dir_hook_del(dl->sc->mp, &dl->dhook);
77
78 xchk_dirtree_for_each_path_safe(dl, path, n) {
79 list_del_init(&path->list);
80 xino_bitmap_destroy(&path->seen_inodes);
81 kfree(path);
82 }
83
84 xfblob_destroy(dl->path_names);
85 xfarray_destroy(dl->path_steps);
86 mutex_destroy(&dl->lock);
87 }
88
89 /* Set us up to look for directory loops. */
90 int
xchk_setup_dirtree(struct xfs_scrub * sc)91 xchk_setup_dirtree(
92 struct xfs_scrub *sc)
93 {
94 struct xchk_dirtree *dl;
95 char *descr;
96 int error;
97
98 xchk_fsgates_enable(sc, XCHK_FSGATES_DIRENTS);
99
100 if (xchk_could_repair(sc)) {
101 error = xrep_setup_dirtree(sc);
102 if (error)
103 return error;
104 }
105
106 dl = kvzalloc(sizeof(struct xchk_dirtree), XCHK_GFP_FLAGS);
107 if (!dl)
108 return -ENOMEM;
109 dl->sc = sc;
110 dl->xname.name = dl->namebuf;
111 dl->hook_xname.name = dl->hook_namebuf;
112 INIT_LIST_HEAD(&dl->path_list);
113 dl->root_ino = NULLFSINO;
114 dl->scan_ino = NULLFSINO;
115 dl->parent_ino = NULLFSINO;
116
117 mutex_init(&dl->lock);
118
119 descr = xchk_xfile_ino_descr(sc, "dirtree path steps");
120 error = xfarray_create(descr, 0, sizeof(struct xchk_dirpath_step),
121 &dl->path_steps);
122 kfree(descr);
123 if (error)
124 goto out_dl;
125
126 descr = xchk_xfile_ino_descr(sc, "dirtree path names");
127 error = xfblob_create(descr, &dl->path_names);
128 kfree(descr);
129 if (error)
130 goto out_steps;
131
132 error = xchk_setup_inode_contents(sc, 0);
133 if (error)
134 goto out_names;
135
136 sc->buf = dl;
137 sc->buf_cleanup = xchk_dirtree_buf_cleanup;
138 return 0;
139
140 out_names:
141 xfblob_destroy(dl->path_names);
142 out_steps:
143 xfarray_destroy(dl->path_steps);
144 out_dl:
145 mutex_destroy(&dl->lock);
146 kvfree(dl);
147 return error;
148 }
149
150 /*
151 * Add the parent pointer described by @dl->pptr to the given path as a new
152 * step. Returns -ELNRNG if the path is too deep.
153 */
154 int
xchk_dirpath_append(struct xchk_dirtree * dl,struct xfs_inode * ip,struct xchk_dirpath * path,const struct xfs_name * name,const struct xfs_parent_rec * pptr)155 xchk_dirpath_append(
156 struct xchk_dirtree *dl,
157 struct xfs_inode *ip,
158 struct xchk_dirpath *path,
159 const struct xfs_name *name,
160 const struct xfs_parent_rec *pptr)
161 {
162 struct xchk_dirpath_step step = {
163 .pptr_rec = *pptr, /* struct copy */
164 .name_len = name->len,
165 };
166 int error;
167
168 /*
169 * If this path is more than 2 billion steps long, this directory tree
170 * is too far gone to fix.
171 */
172 if (path->nr_steps >= XFS_MAXLINK)
173 return -ELNRNG;
174
175 error = xfblob_storename(dl->path_names, &step.name_cookie, name);
176 if (error)
177 return error;
178
179 error = xino_bitmap_set(&path->seen_inodes, ip->i_ino);
180 if (error)
181 return error;
182
183 error = xfarray_append(dl->path_steps, &step);
184 if (error)
185 return error;
186
187 path->nr_steps++;
188 return 0;
189 }
190
191 /*
192 * Create an xchk_path for each parent pointer of the directory that we're
193 * scanning. For each path created, we will eventually try to walk towards the
194 * root with the goal of deleting all parents except for one that leads to the
195 * root.
196 *
197 * Returns -EFSCORRUPTED to signal that the inode being scanned has a corrupt
198 * parent pointer and hence there's no point in continuing; or -ENOSR if there
199 * are too many parent pointers for this directory.
200 */
201 STATIC int
xchk_dirtree_create_path(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)202 xchk_dirtree_create_path(
203 struct xfs_scrub *sc,
204 struct xfs_inode *ip,
205 unsigned int attr_flags,
206 const unsigned char *name,
207 unsigned int namelen,
208 const void *value,
209 unsigned int valuelen,
210 void *priv)
211 {
212 struct xfs_name xname = {
213 .name = name,
214 .len = namelen,
215 };
216 struct xchk_dirtree *dl = priv;
217 struct xchk_dirpath *path;
218 const struct xfs_parent_rec *rec = value;
219 int error;
220
221 if (!(attr_flags & XFS_ATTR_PARENT))
222 return 0;
223
224 error = xfs_parent_from_attr(sc->mp, attr_flags, name, namelen, value,
225 valuelen, NULL, NULL);
226 if (error)
227 return error;
228
229 /*
230 * If there are more than 2 billion actual parent pointers for this
231 * subdirectory, this fs is too far gone to fix.
232 */
233 if (dl->nr_paths >= XFS_MAXLINK)
234 return -ENOSR;
235
236 trace_xchk_dirtree_create_path(sc, ip, dl->nr_paths, &xname, rec);
237
238 /*
239 * Create a new xchk_path structure to remember this parent pointer
240 * and record the first name step.
241 */
242 path = kmalloc(sizeof(struct xchk_dirpath), XCHK_GFP_FLAGS);
243 if (!path)
244 return -ENOMEM;
245
246 INIT_LIST_HEAD(&path->list);
247 xino_bitmap_init(&path->seen_inodes);
248 path->nr_steps = 0;
249 path->outcome = XCHK_DIRPATH_SCANNING;
250
251 error = xchk_dirpath_append(dl, sc->ip, path, &xname, rec);
252 if (error)
253 goto out_path;
254
255 path->first_step = xfarray_length(dl->path_steps) - 1;
256 path->second_step = XFARRAY_NULLIDX;
257 path->path_nr = dl->nr_paths;
258
259 list_add_tail(&path->list, &dl->path_list);
260 dl->nr_paths++;
261 return 0;
262 out_path:
263 kfree(path);
264 return error;
265 }
266
267 /*
268 * Validate that the first step of this path still has a corresponding
269 * parent pointer in @sc->ip. We probably dropped @sc->ip's ILOCK while
270 * walking towards the roots, which is why this is necessary.
271 *
272 * This function has a side effect of loading the first parent pointer of this
273 * path into the parent pointer scratch pad. This prepares us to walk up the
274 * directory tree towards the root. Returns -ESTALE if the scan data is now
275 * out of date.
276 */
277 STATIC int
xchk_dirpath_revalidate(struct xchk_dirtree * dl,struct xchk_dirpath * path)278 xchk_dirpath_revalidate(
279 struct xchk_dirtree *dl,
280 struct xchk_dirpath *path)
281 {
282 struct xfs_scrub *sc = dl->sc;
283 int error;
284
285 /*
286 * Look up the parent pointer that corresponds to the start of this
287 * path. If the parent pointer has disappeared on us, dump all the
288 * scan results and try again.
289 */
290 error = xfs_parent_lookup(sc->tp, sc->ip, &dl->xname, &dl->pptr_rec,
291 &dl->pptr_args);
292 if (error == -ENOATTR) {
293 trace_xchk_dirpath_disappeared(dl->sc, sc->ip, path->path_nr,
294 path->first_step, &dl->xname, &dl->pptr_rec);
295 dl->stale = true;
296 return -ESTALE;
297 }
298
299 return error;
300 }
301
302 /*
303 * Walk the parent pointers of a directory at the end of a path and record
304 * the parent that we find in @dl->xname/pptr_rec.
305 */
306 STATIC int
xchk_dirpath_find_next_step(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)307 xchk_dirpath_find_next_step(
308 struct xfs_scrub *sc,
309 struct xfs_inode *ip,
310 unsigned int attr_flags,
311 const unsigned char *name,
312 unsigned int namelen,
313 const void *value,
314 unsigned int valuelen,
315 void *priv)
316 {
317 struct xchk_dirtree *dl = priv;
318 const struct xfs_parent_rec *rec = value;
319 int error;
320
321 if (!(attr_flags & XFS_ATTR_PARENT))
322 return 0;
323
324 error = xfs_parent_from_attr(sc->mp, attr_flags, name, namelen, value,
325 valuelen, NULL, NULL);
326 if (error)
327 return error;
328
329 /*
330 * If we've already set @dl->pptr_rec, then this directory has multiple
331 * parents. Signal this back to the caller via -EMLINK.
332 */
333 if (dl->parents_found > 0)
334 return -EMLINK;
335
336 dl->parents_found++;
337 memcpy(dl->namebuf, name, namelen);
338 dl->xname.len = namelen;
339 dl->pptr_rec = *rec; /* struct copy */
340 return 0;
341 }
342
343 /* Set and log the outcome of a path walk. */
344 static inline void
xchk_dirpath_set_outcome(struct xchk_dirtree * dl,struct xchk_dirpath * path,enum xchk_dirpath_outcome outcome)345 xchk_dirpath_set_outcome(
346 struct xchk_dirtree *dl,
347 struct xchk_dirpath *path,
348 enum xchk_dirpath_outcome outcome)
349 {
350 trace_xchk_dirpath_set_outcome(dl->sc, path->path_nr, path->nr_steps,
351 outcome);
352
353 path->outcome = outcome;
354 }
355
356 /*
357 * Scan the directory at the end of this path for its parent directory link.
358 * If we find one, extend the path. Returns -ESTALE if the scan data out of
359 * date. Returns -EFSCORRUPTED if the parent pointer is bad; or -ELNRNG if
360 * the path got too deep.
361 */
362 STATIC int
xchk_dirpath_step_up(struct xchk_dirtree * dl,struct xchk_dirpath * path,bool is_metadir)363 xchk_dirpath_step_up(
364 struct xchk_dirtree *dl,
365 struct xchk_dirpath *path,
366 bool is_metadir)
367 {
368 struct xfs_scrub *sc = dl->sc;
369 struct xfs_inode *dp;
370 xfs_ino_t parent_ino = be64_to_cpu(dl->pptr_rec.p_ino);
371 unsigned int lock_mode;
372 int error;
373
374 /* Grab and lock the parent directory. */
375 error = xchk_iget(sc, parent_ino, &dp);
376 if (error)
377 return error;
378
379 lock_mode = xfs_ilock_attr_map_shared(dp);
380 mutex_lock(&dl->lock);
381
382 if (dl->stale) {
383 error = -ESTALE;
384 goto out_scanlock;
385 }
386
387 /* We've reached the root directory; the path is ok. */
388 if (parent_ino == dl->root_ino) {
389 xchk_dirpath_set_outcome(dl, path, XCHK_DIRPATH_OK);
390 error = 0;
391 goto out_scanlock;
392 }
393
394 /*
395 * The inode being scanned is its own distant ancestor! Get rid of
396 * this path.
397 */
398 if (parent_ino == sc->ip->i_ino) {
399 xchk_dirpath_set_outcome(dl, path, XCHK_DIRPATH_DELETE);
400 error = 0;
401 goto out_scanlock;
402 }
403
404 /*
405 * We've seen this inode before during the path walk. There's a loop
406 * above us in the directory tree. This probably means that we cannot
407 * continue, but let's keep walking paths to get a full picture.
408 */
409 if (xino_bitmap_test(&path->seen_inodes, parent_ino)) {
410 xchk_dirpath_set_outcome(dl, path, XCHK_DIRPATH_LOOP);
411 error = 0;
412 goto out_scanlock;
413 }
414
415 /* The handle encoded in the parent pointer must match. */
416 if (VFS_I(dp)->i_generation != be32_to_cpu(dl->pptr_rec.p_gen)) {
417 trace_xchk_dirpath_badgen(dl->sc, dp, path->path_nr,
418 path->nr_steps, &dl->xname, &dl->pptr_rec);
419 error = -EFSCORRUPTED;
420 goto out_scanlock;
421 }
422
423 /* Parent pointer must point up to a directory. */
424 if (!S_ISDIR(VFS_I(dp)->i_mode)) {
425 trace_xchk_dirpath_nondir_parent(dl->sc, dp, path->path_nr,
426 path->nr_steps, &dl->xname, &dl->pptr_rec);
427 error = -EFSCORRUPTED;
428 goto out_scanlock;
429 }
430
431 /* Parent cannot be an unlinked directory. */
432 if (VFS_I(dp)->i_nlink == 0) {
433 trace_xchk_dirpath_unlinked_parent(dl->sc, dp, path->path_nr,
434 path->nr_steps, &dl->xname, &dl->pptr_rec);
435 error = -EFSCORRUPTED;
436 goto out_scanlock;
437 }
438
439 /* Parent must be in the same directory tree. */
440 if (is_metadir != xfs_is_metadir_inode(dp)) {
441 trace_xchk_dirpath_crosses_tree(dl->sc, dp, path->path_nr,
442 path->nr_steps, &dl->xname, &dl->pptr_rec);
443 error = -EFSCORRUPTED;
444 goto out_scanlock;
445 }
446
447 /*
448 * If the extended attributes look as though they has been zapped by
449 * the inode record repair code, we cannot scan for parent pointers.
450 */
451 if (xchk_pptr_looks_zapped(dp)) {
452 error = -EBUSY;
453 xchk_set_incomplete(sc);
454 goto out_scanlock;
455 }
456
457 /*
458 * Walk the parent pointers of @dp to find the parent of this directory
459 * to find the next step in our walk. If we find that @dp has exactly
460 * one parent, the parent pointer information will be stored in
461 * @dl->pptr_rec. This prepares us for the next step of the walk.
462 */
463 mutex_unlock(&dl->lock);
464 dl->parents_found = 0;
465 error = xchk_xattr_walk(sc, dp, xchk_dirpath_find_next_step, NULL, dl);
466 mutex_lock(&dl->lock);
467 if (error == -EFSCORRUPTED || error == -EMLINK ||
468 (!error && dl->parents_found == 0)) {
469 /*
470 * Further up the directory tree from @sc->ip, we found a
471 * corrupt parent pointer, multiple parent pointers while
472 * finding this directory's parent, or zero parents despite
473 * having a nonzero link count. Keep looking for other paths.
474 */
475 xchk_dirpath_set_outcome(dl, path, XCHK_DIRPATH_CORRUPT);
476 error = 0;
477 goto out_scanlock;
478 }
479 if (error)
480 goto out_scanlock;
481
482 if (dl->stale) {
483 error = -ESTALE;
484 goto out_scanlock;
485 }
486
487 trace_xchk_dirpath_found_next_step(sc, dp, path->path_nr,
488 path->nr_steps, &dl->xname, &dl->pptr_rec);
489
490 /* Append to the path steps */
491 error = xchk_dirpath_append(dl, dp, path, &dl->xname, &dl->pptr_rec);
492 if (error)
493 goto out_scanlock;
494
495 if (path->second_step == XFARRAY_NULLIDX)
496 path->second_step = xfarray_length(dl->path_steps) - 1;
497
498 out_scanlock:
499 mutex_unlock(&dl->lock);
500 xfs_iunlock(dp, lock_mode);
501 xchk_irele(sc, dp);
502 return error;
503 }
504
505 /*
506 * Walk the directory tree upwards towards what is hopefully the root
507 * directory, recording path steps as we go. The current path components are
508 * stored in dl->pptr_rec and dl->xname.
509 *
510 * Returns -ESTALE if the scan data are out of date. Returns -EFSCORRUPTED
511 * only if the direct parent pointer of @sc->ip associated with this path is
512 * corrupt.
513 */
514 STATIC int
xchk_dirpath_walk_upwards(struct xchk_dirtree * dl,struct xchk_dirpath * path)515 xchk_dirpath_walk_upwards(
516 struct xchk_dirtree *dl,
517 struct xchk_dirpath *path)
518 {
519 struct xfs_scrub *sc = dl->sc;
520 bool is_metadir;
521 int error;
522
523 ASSERT(sc->ilock_flags & XFS_ILOCK_EXCL);
524
525 /* Reload the start of this path and make sure it's still there. */
526 error = xchk_dirpath_revalidate(dl, path);
527 if (error)
528 return error;
529
530 trace_xchk_dirpath_walk_upwards(sc, sc->ip, path->path_nr, &dl->xname,
531 &dl->pptr_rec);
532
533 /*
534 * The inode being scanned is its own direct ancestor!
535 * Get rid of this path.
536 */
537 if (be64_to_cpu(dl->pptr_rec.p_ino) == sc->ip->i_ino) {
538 xchk_dirpath_set_outcome(dl, path, XCHK_DIRPATH_DELETE);
539 return 0;
540 }
541
542 /*
543 * Drop ILOCK_EXCL on the inode being scanned. We still hold
544 * IOLOCK_EXCL on it, so it cannot move around or be renamed.
545 *
546 * Beyond this point we're walking up the directory tree, which means
547 * that we can acquire and drop the ILOCK on an alias of sc->ip. The
548 * ILOCK state is no longer tracked in the scrub context. Hence we
549 * must drop @sc->ip's ILOCK during the walk.
550 */
551 is_metadir = xfs_is_metadir_inode(sc->ip);
552 mutex_unlock(&dl->lock);
553 xchk_iunlock(sc, XFS_ILOCK_EXCL);
554
555 /*
556 * Take the first step in the walk towards the root by checking the
557 * start of this path, which is a direct parent pointer of @sc->ip.
558 * If we see any kind of error here (including corruptions), the parent
559 * pointer of @sc->ip is corrupt. Stop the whole scan.
560 */
561 error = xchk_dirpath_step_up(dl, path, is_metadir);
562 if (error) {
563 xchk_ilock(sc, XFS_ILOCK_EXCL);
564 mutex_lock(&dl->lock);
565 return error;
566 }
567
568 /*
569 * Take steps upward from the second step in this path towards the
570 * root. If we hit corruption errors here, there's a problem
571 * *somewhere* in the path, but we don't need to stop scanning.
572 */
573 while (!error && path->outcome == XCHK_DIRPATH_SCANNING)
574 error = xchk_dirpath_step_up(dl, path, is_metadir);
575
576 /* Retake the locks we had, mark paths, etc. */
577 xchk_ilock(sc, XFS_ILOCK_EXCL);
578 mutex_lock(&dl->lock);
579 if (error == -EFSCORRUPTED) {
580 xchk_dirpath_set_outcome(dl, path, XCHK_DIRPATH_CORRUPT);
581 error = 0;
582 }
583 if (!error && dl->stale)
584 return -ESTALE;
585 return error;
586 }
587
588 /*
589 * Decide if this path step has been touched by this live update. Returns
590 * 1 for yes, 0 for no, or a negative errno.
591 */
592 STATIC int
xchk_dirpath_step_is_stale(struct xchk_dirtree * dl,struct xchk_dirpath * path,unsigned int step_nr,xfarray_idx_t step_idx,struct xfs_dir_update_params * p,xfs_ino_t * cursor)593 xchk_dirpath_step_is_stale(
594 struct xchk_dirtree *dl,
595 struct xchk_dirpath *path,
596 unsigned int step_nr,
597 xfarray_idx_t step_idx,
598 struct xfs_dir_update_params *p,
599 xfs_ino_t *cursor)
600 {
601 struct xchk_dirpath_step step;
602 xfs_ino_t child_ino = *cursor;
603 int error;
604
605 error = xfarray_load(dl->path_steps, step_idx, &step);
606 if (error)
607 return error;
608 *cursor = be64_to_cpu(step.pptr_rec.p_ino);
609
610 /*
611 * If the parent and child being updated are not the ones mentioned in
612 * this path step, the scan data is still ok.
613 */
614 if (p->ip->i_ino != child_ino || p->dp->i_ino != *cursor)
615 return 0;
616
617 /*
618 * If the dirent name lengths or byte sequences are different, the scan
619 * data is still ok.
620 */
621 if (p->name->len != step.name_len)
622 return 0;
623
624 error = xfblob_loadname(dl->path_names, step.name_cookie,
625 &dl->hook_xname, step.name_len);
626 if (error)
627 return error;
628
629 if (memcmp(dl->hook_xname.name, p->name->name, p->name->len) != 0)
630 return 0;
631
632 /*
633 * If the update comes from the repair code itself, walk the state
634 * machine forward.
635 */
636 if (p->ip->i_ino == dl->scan_ino &&
637 path->outcome == XREP_DIRPATH_ADOPTING) {
638 xchk_dirpath_set_outcome(dl, path, XREP_DIRPATH_ADOPTED);
639 return 0;
640 }
641
642 if (p->ip->i_ino == dl->scan_ino &&
643 path->outcome == XREP_DIRPATH_DELETING) {
644 xchk_dirpath_set_outcome(dl, path, XREP_DIRPATH_DELETED);
645 return 0;
646 }
647
648 /* Exact match, scan data is out of date. */
649 trace_xchk_dirpath_changed(dl->sc, path->path_nr, step_nr, p->dp,
650 p->ip, p->name);
651 return 1;
652 }
653
654 /*
655 * Decide if this path has been touched by this live update. Returns 1 for
656 * yes, 0 for no, or a negative errno.
657 */
658 STATIC int
xchk_dirpath_is_stale(struct xchk_dirtree * dl,struct xchk_dirpath * path,struct xfs_dir_update_params * p)659 xchk_dirpath_is_stale(
660 struct xchk_dirtree *dl,
661 struct xchk_dirpath *path,
662 struct xfs_dir_update_params *p)
663 {
664 xfs_ino_t cursor = dl->scan_ino;
665 xfarray_idx_t idx = path->first_step;
666 unsigned int i;
667 int ret;
668
669 /*
670 * The child being updated has not been seen by this path at all; this
671 * path cannot be stale.
672 */
673 if (!xino_bitmap_test(&path->seen_inodes, p->ip->i_ino))
674 return 0;
675
676 ret = xchk_dirpath_step_is_stale(dl, path, 0, idx, p, &cursor);
677 if (ret != 0)
678 return ret;
679
680 for (i = 1, idx = path->second_step; i < path->nr_steps; i++, idx++) {
681 ret = xchk_dirpath_step_is_stale(dl, path, i, idx, p, &cursor);
682 if (ret != 0)
683 return ret;
684 }
685
686 return 0;
687 }
688
689 /*
690 * Decide if a directory update from the regular filesystem touches any of the
691 * paths we've scanned, and invalidate the scan data if true.
692 */
693 STATIC int
xchk_dirtree_live_update(struct notifier_block * nb,unsigned long action,void * data)694 xchk_dirtree_live_update(
695 struct notifier_block *nb,
696 unsigned long action,
697 void *data)
698 {
699 struct xfs_dir_update_params *p = data;
700 struct xchk_dirtree *dl;
701 struct xchk_dirpath *path;
702 int ret;
703
704 dl = container_of(nb, struct xchk_dirtree, dhook.dirent_hook.nb);
705
706 trace_xchk_dirtree_live_update(dl->sc, p->dp, action, p->ip, p->delta,
707 p->name);
708
709 mutex_lock(&dl->lock);
710
711 if (dl->stale || dl->aborted)
712 goto out_unlock;
713
714 xchk_dirtree_for_each_path(dl, path) {
715 ret = xchk_dirpath_is_stale(dl, path, p);
716 if (ret < 0) {
717 dl->aborted = true;
718 break;
719 }
720 if (ret == 1) {
721 dl->stale = true;
722 break;
723 }
724 }
725
726 out_unlock:
727 mutex_unlock(&dl->lock);
728 return NOTIFY_DONE;
729 }
730
731 /* Delete all the collected path information. */
732 STATIC void
xchk_dirtree_reset(void * buf)733 xchk_dirtree_reset(
734 void *buf)
735 {
736 struct xchk_dirtree *dl = buf;
737 struct xchk_dirpath *path, *n;
738
739 ASSERT(dl->sc->ilock_flags & XFS_ILOCK_EXCL);
740
741 xchk_dirtree_for_each_path_safe(dl, path, n) {
742 list_del_init(&path->list);
743 xino_bitmap_destroy(&path->seen_inodes);
744 kfree(path);
745 }
746 dl->nr_paths = 0;
747
748 xfarray_truncate(dl->path_steps);
749 xfblob_truncate(dl->path_names);
750
751 dl->stale = false;
752 }
753
754 /*
755 * Load the name/pptr from the first step in this path into @dl->pptr_rec and
756 * @dl->xname.
757 */
758 STATIC int
xchk_dirtree_load_path(struct xchk_dirtree * dl,struct xchk_dirpath * path)759 xchk_dirtree_load_path(
760 struct xchk_dirtree *dl,
761 struct xchk_dirpath *path)
762 {
763 struct xchk_dirpath_step step;
764 int error;
765
766 error = xfarray_load(dl->path_steps, path->first_step, &step);
767 if (error)
768 return error;
769
770 error = xfblob_loadname(dl->path_names, step.name_cookie, &dl->xname,
771 step.name_len);
772 if (error)
773 return error;
774
775 dl->pptr_rec = step.pptr_rec; /* struct copy */
776 return 0;
777 }
778
779 /*
780 * For each parent pointer of this subdir, trace a path upwards towards the
781 * root directory and record what we find. Returns 0 for success;
782 * -EFSCORRUPTED if walking the parent pointers of @sc->ip failed, -ELNRNG if a
783 * path was too deep; -ENOSR if there were too many parent pointers; or
784 * a negative errno.
785 */
786 int
xchk_dirtree_find_paths_to_root(struct xchk_dirtree * dl)787 xchk_dirtree_find_paths_to_root(
788 struct xchk_dirtree *dl)
789 {
790 struct xfs_scrub *sc = dl->sc;
791 struct xchk_dirpath *path;
792 int error = 0;
793
794 do {
795 if (xchk_should_terminate(sc, &error))
796 return error;
797
798 xchk_dirtree_reset(dl);
799
800 /*
801 * If the extended attributes look as though they has been
802 * zapped by the inode record repair code, we cannot scan for
803 * parent pointers.
804 */
805 if (xchk_pptr_looks_zapped(sc->ip)) {
806 xchk_set_incomplete(sc);
807 return -EBUSY;
808 }
809
810 /*
811 * Create path walk contexts for each parent of the directory
812 * that is being scanned. Directories are supposed to have
813 * only one parent, but this is how we detect multiple parents.
814 */
815 error = xchk_xattr_walk(sc, sc->ip, xchk_dirtree_create_path,
816 NULL, dl);
817 if (error)
818 return error;
819
820 xchk_dirtree_for_each_path(dl, path) {
821 /* Load path components into dl->pptr/xname */
822 error = xchk_dirtree_load_path(dl, path);
823 if (error)
824 return error;
825
826 /*
827 * Try to walk up each path to the root. This enables
828 * us to find directory loops in ancestors, and the
829 * like.
830 */
831 error = xchk_dirpath_walk_upwards(dl, path);
832 if (error == -EFSCORRUPTED) {
833 /*
834 * A parent pointer of @sc->ip is bad, don't
835 * bother continuing.
836 */
837 break;
838 }
839 if (error == -ESTALE) {
840 /* This had better be an invalidation. */
841 ASSERT(dl->stale);
842 break;
843 }
844 if (error)
845 return error;
846 if (dl->aborted)
847 return 0;
848 }
849 } while (dl->stale);
850
851 return error;
852 }
853
854 /*
855 * Figure out what to do with the paths we tried to find. Do not call this
856 * if the scan results are stale.
857 */
858 void
xchk_dirtree_evaluate(struct xchk_dirtree * dl,struct xchk_dirtree_outcomes * oc)859 xchk_dirtree_evaluate(
860 struct xchk_dirtree *dl,
861 struct xchk_dirtree_outcomes *oc)
862 {
863 struct xchk_dirpath *path;
864
865 ASSERT(!dl->stale);
866
867 /* Scan the paths we have to decide what to do. */
868 memset(oc, 0, sizeof(struct xchk_dirtree_outcomes));
869 xchk_dirtree_for_each_path(dl, path) {
870 trace_xchk_dirpath_evaluate_path(dl->sc, path->path_nr,
871 path->nr_steps, path->outcome);
872
873 switch (path->outcome) {
874 case XCHK_DIRPATH_SCANNING:
875 /* shouldn't get here */
876 ASSERT(0);
877 break;
878 case XCHK_DIRPATH_DELETE:
879 /* This one is already going away. */
880 oc->bad++;
881 break;
882 case XCHK_DIRPATH_CORRUPT:
883 case XCHK_DIRPATH_LOOP:
884 /* Couldn't find the end of this path. */
885 oc->suspect++;
886 break;
887 case XCHK_DIRPATH_STALE:
888 /* shouldn't get here either */
889 ASSERT(0);
890 break;
891 case XCHK_DIRPATH_OK:
892 /* This path got all the way to the root. */
893 oc->good++;
894 break;
895 case XREP_DIRPATH_DELETING:
896 case XREP_DIRPATH_DELETED:
897 case XREP_DIRPATH_ADOPTING:
898 case XREP_DIRPATH_ADOPTED:
899 /* These should not be in progress! */
900 ASSERT(0);
901 break;
902 }
903 }
904
905 trace_xchk_dirtree_evaluate(dl, oc);
906 }
907
908 /* Look for directory loops. */
909 int
xchk_dirtree(struct xfs_scrub * sc)910 xchk_dirtree(
911 struct xfs_scrub *sc)
912 {
913 struct xchk_dirtree_outcomes oc;
914 struct xchk_dirtree *dl = sc->buf;
915 int error;
916
917 /*
918 * Nondirectories do not point downwards to other files, so they cannot
919 * cause a cycle in the directory tree.
920 */
921 if (!S_ISDIR(VFS_I(sc->ip)->i_mode))
922 return -ENOENT;
923
924 ASSERT(xfs_has_parent(sc->mp));
925
926 /*
927 * Find the root of the directory tree. Remember which directory to
928 * scan, because the hook doesn't detach until after sc->ip gets
929 * released during teardown.
930 */
931 dl->root_ino = xchk_inode_rootdir_inum(sc->ip);
932 dl->scan_ino = sc->ip->i_ino;
933
934 trace_xchk_dirtree_start(sc->ip, sc->sm, 0);
935
936 /*
937 * Hook into the directory entry code so that we can capture updates to
938 * paths that we have already scanned. The scanner thread takes each
939 * directory's ILOCK, which means that any in-progress directory update
940 * will finish before we can scan the directory.
941 */
942 ASSERT(sc->flags & XCHK_FSGATES_DIRENTS);
943 xfs_dir_hook_setup(&dl->dhook, xchk_dirtree_live_update);
944 error = xfs_dir_hook_add(sc->mp, &dl->dhook);
945 if (error)
946 goto out;
947
948 mutex_lock(&dl->lock);
949
950 /* Trace each parent pointer's path to the root. */
951 error = xchk_dirtree_find_paths_to_root(dl);
952 if (error == -EFSCORRUPTED || error == -ELNRNG || error == -ENOSR) {
953 /*
954 * Don't bother walking the paths if the xattr structure or the
955 * parent pointers are corrupt; this scan cannot be completed
956 * without full information.
957 */
958 xchk_ino_xref_set_corrupt(sc, sc->ip->i_ino);
959 error = 0;
960 goto out_scanlock;
961 }
962 if (error == -EBUSY) {
963 /*
964 * We couldn't scan some directory's parent pointers because
965 * the attr fork looked like it had been zapped. The
966 * scan was marked incomplete, so no further error code
967 * is necessary.
968 */
969 error = 0;
970 goto out_scanlock;
971 }
972 if (error)
973 goto out_scanlock;
974 if (dl->aborted) {
975 xchk_set_incomplete(sc);
976 goto out_scanlock;
977 }
978
979 /* Assess what we found in our path evaluation. */
980 xchk_dirtree_evaluate(dl, &oc);
981 if (xchk_dirtree_parentless(dl)) {
982 if (oc.good || oc.bad || oc.suspect)
983 xchk_ino_set_corrupt(sc, sc->ip->i_ino);
984 } else {
985 if (oc.bad || oc.good + oc.suspect != 1)
986 xchk_ino_set_corrupt(sc, sc->ip->i_ino);
987 if (oc.suspect)
988 xchk_ino_xref_set_corrupt(sc, sc->ip->i_ino);
989 }
990
991 out_scanlock:
992 mutex_unlock(&dl->lock);
993 out:
994 trace_xchk_dirtree_done(sc->ip, sc->sm, error);
995 return error;
996 }
997
998 /* Does the directory targetted by this scrub have no parents? */
999 bool
xchk_dirtree_parentless(const struct xchk_dirtree * dl)1000 xchk_dirtree_parentless(const struct xchk_dirtree *dl)
1001 {
1002 struct xfs_scrub *sc = dl->sc;
1003
1004 if (xchk_inode_is_dirtree_root(sc->ip))
1005 return true;
1006 if (VFS_I(sc->ip)->i_nlink == 0)
1007 return true;
1008 return false;
1009 }
1010