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