xref: /linux/fs/xfs/scrub/dirtree_repair.c (revision c532de5a67a70f8533d495f8f2aaa9a0491c3ad0)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2023-2024 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_trans_space.h"
12 #include "xfs_mount.h"
13 #include "xfs_log_format.h"
14 #include "xfs_trans.h"
15 #include "xfs_inode.h"
16 #include "xfs_icache.h"
17 #include "xfs_dir2.h"
18 #include "xfs_dir2_priv.h"
19 #include "xfs_attr.h"
20 #include "xfs_parent.h"
21 #include "scrub/scrub.h"
22 #include "scrub/common.h"
23 #include "scrub/bitmap.h"
24 #include "scrub/ino_bitmap.h"
25 #include "scrub/xfile.h"
26 #include "scrub/xfarray.h"
27 #include "scrub/xfblob.h"
28 #include "scrub/listxattr.h"
29 #include "scrub/trace.h"
30 #include "scrub/repair.h"
31 #include "scrub/orphanage.h"
32 #include "scrub/dirtree.h"
33 #include "scrub/readdir.h"
34 
35 /*
36  * Directory Tree Structure Repairs
37  * ================================
38  *
39  * If we decide that the directory being scanned is participating in a
40  * directory loop, the only change we can make is to remove directory entries
41  * pointing down to @sc->ip.  If that leaves it with no parents, the directory
42  * should be adopted by the orphanage.
43  */
44 
45 /* Set up to repair directory loops. */
46 int
47 xrep_setup_dirtree(
48 	struct xfs_scrub	*sc)
49 {
50 	return xrep_orphanage_try_create(sc);
51 }
52 
53 /* Change the outcome of this path. */
54 static inline void
55 xrep_dirpath_set_outcome(
56 	struct xchk_dirtree		*dl,
57 	struct xchk_dirpath		*path,
58 	enum xchk_dirpath_outcome	outcome)
59 {
60 	trace_xrep_dirpath_set_outcome(dl->sc, path->path_nr, path->nr_steps,
61 			outcome);
62 
63 	path->outcome = outcome;
64 }
65 
66 /* Delete all paths. */
67 STATIC void
68 xrep_dirtree_delete_all_paths(
69 	struct xchk_dirtree		*dl,
70 	struct xchk_dirtree_outcomes	*oc)
71 {
72 	struct xchk_dirpath		*path;
73 
74 	xchk_dirtree_for_each_path(dl, path) {
75 		switch (path->outcome) {
76 		case XCHK_DIRPATH_CORRUPT:
77 		case XCHK_DIRPATH_LOOP:
78 			oc->suspect--;
79 			oc->bad++;
80 			xrep_dirpath_set_outcome(dl, path, XCHK_DIRPATH_DELETE);
81 			break;
82 		case XCHK_DIRPATH_OK:
83 			oc->good--;
84 			oc->bad++;
85 			xrep_dirpath_set_outcome(dl, path, XCHK_DIRPATH_DELETE);
86 			break;
87 		default:
88 			break;
89 		}
90 	}
91 
92 	ASSERT(oc->suspect == 0);
93 	ASSERT(oc->good == 0);
94 }
95 
96 /* Since this is the surviving path, set the dotdot entry to this value. */
97 STATIC void
98 xrep_dirpath_retain_parent(
99 	struct xchk_dirtree		*dl,
100 	struct xchk_dirpath		*path)
101 {
102 	struct xchk_dirpath_step	step;
103 	int				error;
104 
105 	error = xfarray_load(dl->path_steps, path->first_step, &step);
106 	if (error)
107 		return;
108 
109 	dl->parent_ino = be64_to_cpu(step.pptr_rec.p_ino);
110 }
111 
112 /* Find the one surviving path so we know how to set dotdot. */
113 STATIC void
114 xrep_dirtree_find_surviving_path(
115 	struct xchk_dirtree		*dl,
116 	struct xchk_dirtree_outcomes	*oc)
117 {
118 	struct xchk_dirpath		*path;
119 	bool				foundit = false;
120 
121 	xchk_dirtree_for_each_path(dl, path) {
122 		switch (path->outcome) {
123 		case XCHK_DIRPATH_CORRUPT:
124 		case XCHK_DIRPATH_LOOP:
125 		case XCHK_DIRPATH_OK:
126 			if (!foundit) {
127 				xrep_dirpath_retain_parent(dl, path);
128 				foundit = true;
129 				continue;
130 			}
131 			ASSERT(foundit == false);
132 			break;
133 		default:
134 			break;
135 		}
136 	}
137 
138 	ASSERT(oc->suspect + oc->good == 1);
139 }
140 
141 /* Delete all paths except for the one good one. */
142 STATIC void
143 xrep_dirtree_keep_one_good_path(
144 	struct xchk_dirtree		*dl,
145 	struct xchk_dirtree_outcomes	*oc)
146 {
147 	struct xchk_dirpath		*path;
148 	bool				foundit = false;
149 
150 	xchk_dirtree_for_each_path(dl, path) {
151 		switch (path->outcome) {
152 		case XCHK_DIRPATH_CORRUPT:
153 		case XCHK_DIRPATH_LOOP:
154 			oc->suspect--;
155 			oc->bad++;
156 			xrep_dirpath_set_outcome(dl, path, XCHK_DIRPATH_DELETE);
157 			break;
158 		case XCHK_DIRPATH_OK:
159 			if (!foundit) {
160 				xrep_dirpath_retain_parent(dl, path);
161 				foundit = true;
162 				continue;
163 			}
164 			oc->good--;
165 			oc->bad++;
166 			xrep_dirpath_set_outcome(dl, path, XCHK_DIRPATH_DELETE);
167 			break;
168 		default:
169 			break;
170 		}
171 	}
172 
173 	ASSERT(oc->suspect == 0);
174 	ASSERT(oc->good < 2);
175 }
176 
177 /* Delete all paths except for one suspect one. */
178 STATIC void
179 xrep_dirtree_keep_one_suspect_path(
180 	struct xchk_dirtree		*dl,
181 	struct xchk_dirtree_outcomes	*oc)
182 {
183 	struct xchk_dirpath		*path;
184 	bool				foundit = false;
185 
186 	xchk_dirtree_for_each_path(dl, path) {
187 		switch (path->outcome) {
188 		case XCHK_DIRPATH_CORRUPT:
189 		case XCHK_DIRPATH_LOOP:
190 			if (!foundit) {
191 				xrep_dirpath_retain_parent(dl, path);
192 				foundit = true;
193 				continue;
194 			}
195 			oc->suspect--;
196 			oc->bad++;
197 			xrep_dirpath_set_outcome(dl, path, XCHK_DIRPATH_DELETE);
198 			break;
199 		case XCHK_DIRPATH_OK:
200 			ASSERT(0);
201 			break;
202 		default:
203 			break;
204 		}
205 	}
206 
207 	ASSERT(oc->suspect == 1);
208 	ASSERT(oc->good == 0);
209 }
210 
211 /*
212  * Figure out what to do with the paths we tried to find.  Returns -EDEADLOCK
213  * if the scan results have become stale.
214  */
215 STATIC void
216 xrep_dirtree_decide_fate(
217 	struct xchk_dirtree		*dl,
218 	struct xchk_dirtree_outcomes	*oc)
219 {
220 	xchk_dirtree_evaluate(dl, oc);
221 
222 	/* Parentless directories should not have any paths at all. */
223 	if (xchk_dirtree_parentless(dl)) {
224 		xrep_dirtree_delete_all_paths(dl, oc);
225 		return;
226 	}
227 
228 	/* One path is exactly the number of paths we want. */
229 	if (oc->good + oc->suspect == 1) {
230 		xrep_dirtree_find_surviving_path(dl, oc);
231 		return;
232 	}
233 
234 	/* Zero paths means we should reattach the subdir to the orphanage. */
235 	if (oc->good + oc->suspect == 0) {
236 		if (dl->sc->orphanage)
237 			oc->needs_adoption = true;
238 		return;
239 	}
240 
241 	/*
242 	 * Otherwise, this subdirectory has too many parents.  If there's at
243 	 * least one good path, keep it and delete the others.
244 	 */
245 	if (oc->good > 0) {
246 		xrep_dirtree_keep_one_good_path(dl, oc);
247 		return;
248 	}
249 
250 	/*
251 	 * There are no good paths and there are too many suspect paths.
252 	 * Keep the first suspect path and delete the rest.
253 	 */
254 	xrep_dirtree_keep_one_suspect_path(dl, oc);
255 }
256 
257 /*
258  * Load the first step of this path into @step and @dl->xname/pptr
259  * for later repair work.
260  */
261 STATIC int
262 xrep_dirtree_prep_path(
263 	struct xchk_dirtree		*dl,
264 	struct xchk_dirpath		*path,
265 	struct xchk_dirpath_step	*step)
266 {
267 	int				error;
268 
269 	error = xfarray_load(dl->path_steps, path->first_step, step);
270 	if (error)
271 		return error;
272 
273 	error = xfblob_loadname(dl->path_names, step->name_cookie, &dl->xname,
274 			step->name_len);
275 	if (error)
276 		return error;
277 
278 	dl->pptr_rec = step->pptr_rec; /* struct copy */
279 	return 0;
280 }
281 
282 /* Delete the VFS dentry for a removed child. */
283 STATIC int
284 xrep_dirtree_purge_dentry(
285 	struct xchk_dirtree	*dl,
286 	struct xfs_inode	*dp,
287 	const struct xfs_name	*name)
288 {
289 	struct qstr		qname = QSTR_INIT(name->name, name->len);
290 	struct dentry		*parent_dentry, *child_dentry;
291 	int			error = 0;
292 
293 	/*
294 	 * Find the dentry for the parent directory.  If there isn't one, we're
295 	 * done.  Caller already holds i_rwsem for parent and child.
296 	 */
297 	parent_dentry = d_find_alias(VFS_I(dp));
298 	if (!parent_dentry)
299 		return 0;
300 
301 	/* The VFS thinks the parent is a directory, right? */
302 	if (!d_is_dir(parent_dentry)) {
303 		ASSERT(d_is_dir(parent_dentry));
304 		error = -EFSCORRUPTED;
305 		goto out_dput_parent;
306 	}
307 
308 	/*
309 	 * Try to find the dirent pointing to the child.  If there isn't one,
310 	 * we're done.
311 	 */
312 	qname.hash = full_name_hash(parent_dentry, name->name, name->len);
313 	child_dentry = d_lookup(parent_dentry, &qname);
314 	if (!child_dentry) {
315 		error = 0;
316 		goto out_dput_parent;
317 	}
318 
319 	trace_xrep_dirtree_delete_child(dp->i_mount, child_dentry);
320 
321 	/* Child is not a directory?  We're screwed. */
322 	if (!d_is_dir(child_dentry)) {
323 		ASSERT(d_is_dir(child_dentry));
324 		error = -EFSCORRUPTED;
325 		goto out_dput_child;
326 	}
327 
328 	/* Replace the child dentry with a negative one. */
329 	d_delete(child_dentry);
330 
331 out_dput_child:
332 	dput(child_dentry);
333 out_dput_parent:
334 	dput(parent_dentry);
335 	return error;
336 }
337 
338 /*
339  * Prepare to delete a link by taking the IOLOCK of the parent and the child
340  * (scrub target).  Caller must hold IOLOCK_EXCL on @sc->ip.  Returns 0 if we
341  * took both locks, or a negative errno if we couldn't lock the parent in time.
342  */
343 static inline int
344 xrep_dirtree_unlink_iolock(
345 	struct xfs_scrub	*sc,
346 	struct xfs_inode	*dp)
347 {
348 	int			error;
349 
350 	ASSERT(sc->ilock_flags & XFS_IOLOCK_EXCL);
351 
352 	if (xfs_ilock_nowait(dp, XFS_IOLOCK_EXCL))
353 		return 0;
354 
355 	xchk_iunlock(sc, XFS_IOLOCK_EXCL);
356 	do {
357 		xfs_ilock(dp, XFS_IOLOCK_EXCL);
358 		if (xchk_ilock_nowait(sc, XFS_IOLOCK_EXCL))
359 			break;
360 		xfs_iunlock(dp, XFS_IOLOCK_EXCL);
361 
362 		if (xchk_should_terminate(sc, &error)) {
363 			xchk_ilock(sc, XFS_IOLOCK_EXCL);
364 			return error;
365 		}
366 
367 		delay(1);
368 	} while (1);
369 
370 	return 0;
371 }
372 
373 /*
374  * Remove a link from the directory tree and update the dcache.  Returns
375  * -ESTALE if the scan data are now out of date.
376  */
377 STATIC int
378 xrep_dirtree_unlink(
379 	struct xchk_dirtree		*dl,
380 	struct xfs_inode		*dp,
381 	struct xchk_dirpath		*path,
382 	struct xchk_dirpath_step	*step)
383 {
384 	struct xfs_scrub		*sc = dl->sc;
385 	struct xfs_mount		*mp = sc->mp;
386 	xfs_ino_t			dotdot_ino;
387 	xfs_ino_t			parent_ino = dl->parent_ino;
388 	unsigned int			resblks;
389 	int				dontcare;
390 	int				error;
391 
392 	/* Take IOLOCK_EXCL of the parent and child. */
393 	error = xrep_dirtree_unlink_iolock(sc, dp);
394 	if (error)
395 		return error;
396 
397 	/*
398 	 * Create the transaction that we need to sever the path.  Ignore
399 	 * EDQUOT and ENOSPC being returned via nospace_error because the
400 	 * directory code can handle a reservationless update.
401 	 */
402 	resblks = xfs_remove_space_res(mp, step->name_len);
403 	error = xfs_trans_alloc_dir(dp, &M_RES(mp)->tr_remove, sc->ip,
404 			&resblks, &sc->tp, &dontcare);
405 	if (error)
406 		goto out_iolock;
407 
408 	/*
409 	 * Cancel if someone invalidate the paths while we were trying to get
410 	 * the ILOCK.
411 	 */
412 	mutex_lock(&dl->lock);
413 	if (dl->stale) {
414 		mutex_unlock(&dl->lock);
415 		error = -ESTALE;
416 		goto out_trans_cancel;
417 	}
418 	xrep_dirpath_set_outcome(dl, path, XREP_DIRPATH_DELETING);
419 	mutex_unlock(&dl->lock);
420 
421 	trace_xrep_dirtree_delete_path(dl->sc, sc->ip, path->path_nr,
422 			&dl->xname, &dl->pptr_rec);
423 
424 	/*
425 	 * Decide if we need to reset the dotdot entry.  Rules:
426 	 *
427 	 * - If there's a surviving parent, we want dotdot to point there.
428 	 * - If we don't have any surviving parents, then point dotdot at the
429 	 *   root dir.
430 	 * - If dotdot is already set to the value we want, pass in NULLFSINO
431 	 *   for no change necessary.
432 	 *
433 	 * Do this /before/ we dirty anything, in case the dotdot lookup
434 	 * fails.
435 	 */
436 	error = xchk_dir_lookup(sc, sc->ip, &xfs_name_dotdot, &dotdot_ino);
437 	if (error)
438 		goto out_trans_cancel;
439 	if (parent_ino == NULLFSINO)
440 		parent_ino = dl->root_ino;
441 	if (dotdot_ino == parent_ino)
442 		parent_ino = NULLFSINO;
443 
444 	/* Drop the link from sc->ip's dotdot entry.  */
445 	error = xfs_droplink(sc->tp, dp);
446 	if (error)
447 		goto out_trans_cancel;
448 
449 	/* Reset the dotdot entry to a surviving parent. */
450 	if (parent_ino != NULLFSINO) {
451 		error = xfs_dir_replace(sc->tp, sc->ip, &xfs_name_dotdot,
452 				parent_ino, 0);
453 		if (error)
454 			goto out_trans_cancel;
455 	}
456 
457 	/* Drop the link from dp to sc->ip. */
458 	error = xfs_droplink(sc->tp, sc->ip);
459 	if (error)
460 		goto out_trans_cancel;
461 
462 	error = xfs_dir_removename(sc->tp, dp, &dl->xname, sc->ip->i_ino,
463 			resblks);
464 	if (error) {
465 		ASSERT(error != -ENOENT);
466 		goto out_trans_cancel;
467 	}
468 
469 	if (xfs_has_parent(sc->mp)) {
470 		error = xfs_parent_removename(sc->tp, &dl->ppargs, dp,
471 				&dl->xname, sc->ip);
472 		if (error)
473 			goto out_trans_cancel;
474 	}
475 
476 	/*
477 	 * Notify dirent hooks that we removed the bad link, invalidate the
478 	 * dcache, and commit the repair.
479 	 */
480 	xfs_dir_update_hook(dp, sc->ip, -1, &dl->xname);
481 	error = xrep_dirtree_purge_dentry(dl, dp, &dl->xname);
482 	if (error)
483 		goto out_trans_cancel;
484 
485 	error = xrep_trans_commit(sc);
486 	goto out_ilock;
487 
488 out_trans_cancel:
489 	xchk_trans_cancel(sc);
490 out_ilock:
491 	xfs_iunlock(sc->ip, XFS_ILOCK_EXCL);
492 	xfs_iunlock(dp, XFS_ILOCK_EXCL);
493 out_iolock:
494 	xfs_iunlock(dp, XFS_IOLOCK_EXCL);
495 	return error;
496 }
497 
498 /*
499  * Delete a directory entry that points to this directory.  Returns -ESTALE
500  * if the scan data are now out of date.
501  */
502 STATIC int
503 xrep_dirtree_delete_path(
504 	struct xchk_dirtree		*dl,
505 	struct xchk_dirpath		*path)
506 {
507 	struct xchk_dirpath_step	step;
508 	struct xfs_scrub		*sc = dl->sc;
509 	struct xfs_inode		*dp;
510 	int				error;
511 
512 	/*
513 	 * Load the parent pointer and directory inode for this path, then
514 	 * drop the scan lock, the ILOCK, and the transaction so that
515 	 * _delete_path can reserve the proper transaction.  This sets up
516 	 * @dl->xname for the deletion.
517 	 */
518 	error = xrep_dirtree_prep_path(dl, path, &step);
519 	if (error)
520 		return error;
521 
522 	error = xchk_iget(sc, be64_to_cpu(step.pptr_rec.p_ino), &dp);
523 	if (error)
524 		return error;
525 
526 	mutex_unlock(&dl->lock);
527 	xchk_trans_cancel(sc);
528 	xchk_iunlock(sc, XFS_ILOCK_EXCL);
529 
530 	/* Delete the directory link and release the parent. */
531 	error = xrep_dirtree_unlink(dl, dp, path, &step);
532 	xchk_irele(sc, dp);
533 
534 	/*
535 	 * Retake all the resources we had at the beginning even if the repair
536 	 * failed or the scan data are now stale.  This keeps things simple for
537 	 * the caller.
538 	 */
539 	xchk_trans_alloc_empty(sc);
540 	xchk_ilock(sc, XFS_ILOCK_EXCL);
541 	mutex_lock(&dl->lock);
542 
543 	if (!error && dl->stale)
544 		error = -ESTALE;
545 	return error;
546 }
547 
548 /* Add a new path to represent our in-progress adoption. */
549 STATIC int
550 xrep_dirtree_create_adoption_path(
551 	struct xchk_dirtree		*dl)
552 {
553 	struct xfs_scrub		*sc = dl->sc;
554 	struct xchk_dirpath		*path;
555 	int				error;
556 
557 	/*
558 	 * We should have capped the number of paths at XFS_MAXLINK-1 in the
559 	 * scanner.
560 	 */
561 	if (dl->nr_paths > XFS_MAXLINK) {
562 		ASSERT(dl->nr_paths <= XFS_MAXLINK);
563 		return -EFSCORRUPTED;
564 	}
565 
566 	/*
567 	 * Create a new xchk_path structure to remember this parent pointer
568 	 * and record the first name step.
569 	 */
570 	path = kmalloc(sizeof(struct xchk_dirpath), XCHK_GFP_FLAGS);
571 	if (!path)
572 		return -ENOMEM;
573 
574 	INIT_LIST_HEAD(&path->list);
575 	xino_bitmap_init(&path->seen_inodes);
576 	path->nr_steps = 0;
577 	path->outcome = XREP_DIRPATH_ADOPTING;
578 
579 	/*
580 	 * Record the new link that we just created in the orphanage.  Because
581 	 * adoption is the last repair that we perform, we don't bother filling
582 	 * in the path all the way back to the root.
583 	 */
584 	xfs_inode_to_parent_rec(&dl->pptr_rec, sc->orphanage);
585 
586 	error = xino_bitmap_set(&path->seen_inodes, sc->orphanage->i_ino);
587 	if (error)
588 		goto out_path;
589 
590 	trace_xrep_dirtree_create_adoption(sc, sc->ip, dl->nr_paths,
591 			&dl->xname, &dl->pptr_rec);
592 
593 	error = xchk_dirpath_append(dl, sc->ip, path, &dl->xname,
594 			&dl->pptr_rec);
595 	if (error)
596 		goto out_path;
597 
598 	path->first_step = xfarray_length(dl->path_steps) - 1;
599 	path->second_step = XFARRAY_NULLIDX;
600 	path->path_nr = dl->nr_paths;
601 
602 	list_add_tail(&path->list, &dl->path_list);
603 	dl->nr_paths++;
604 	return 0;
605 
606 out_path:
607 	kfree(path);
608 	return error;
609 }
610 
611 /*
612  * Prepare to move a file to the orphanage by taking the IOLOCK of the
613  * orphanage and the child (scrub target).  Caller must hold IOLOCK_EXCL on
614  * @sc->ip.  Returns 0 if we took both locks, or a negative errno if we
615  * couldn't lock the orphanage in time.
616  */
617 static inline int
618 xrep_dirtree_adopt_iolock(
619 	struct xfs_scrub	*sc)
620 {
621 	int			error;
622 
623 	ASSERT(sc->ilock_flags & XFS_IOLOCK_EXCL);
624 
625 	if (xrep_orphanage_ilock_nowait(sc, XFS_IOLOCK_EXCL))
626 		return 0;
627 
628 	xchk_iunlock(sc, XFS_IOLOCK_EXCL);
629 	do {
630 		xrep_orphanage_ilock(sc, XFS_IOLOCK_EXCL);
631 		if (xchk_ilock_nowait(sc, XFS_IOLOCK_EXCL))
632 			break;
633 		xrep_orphanage_iunlock(sc, XFS_IOLOCK_EXCL);
634 
635 		if (xchk_should_terminate(sc, &error)) {
636 			xchk_ilock(sc, XFS_IOLOCK_EXCL);
637 			return error;
638 		}
639 
640 		delay(1);
641 	} while (1);
642 
643 	return 0;
644 }
645 
646 /*
647  * Reattach this orphaned directory to the orphanage.  Do not call this with
648  * any resources held.  Returns -ESTALE if the scan data have become out of
649  * date.
650  */
651 STATIC int
652 xrep_dirtree_adopt(
653 	struct xchk_dirtree		*dl)
654 {
655 	struct xfs_scrub		*sc = dl->sc;
656 	int				error;
657 
658 	/* Take the IOLOCK of the orphanage and the scrub target. */
659 	error = xrep_dirtree_adopt_iolock(sc);
660 	if (error)
661 		return error;
662 
663 	/*
664 	 * Set up for an adoption.  The directory tree fixer runs after the
665 	 * link counts have been corrected.  Therefore, we must bump the
666 	 * child's link count since there will be no further opportunity to fix
667 	 * errors.
668 	 */
669 	error = xrep_adoption_trans_alloc(sc, &dl->adoption);
670 	if (error)
671 		goto out_iolock;
672 	dl->adoption.bump_child_nlink = true;
673 
674 	/* Figure out what name we're going to use here. */
675 	error = xrep_adoption_compute_name(&dl->adoption, &dl->xname);
676 	if (error)
677 		goto out_trans;
678 
679 	/*
680 	 * Now that we have a proposed name for the orphanage entry, create
681 	 * a faux path so that the live update hook will see it.
682 	 */
683 	mutex_lock(&dl->lock);
684 	if (dl->stale) {
685 		mutex_unlock(&dl->lock);
686 		error = -ESTALE;
687 		goto out_trans;
688 	}
689 	error = xrep_dirtree_create_adoption_path(dl);
690 	mutex_unlock(&dl->lock);
691 	if (error)
692 		goto out_trans;
693 
694 	/* Reparent the directory. */
695 	error = xrep_adoption_move(&dl->adoption);
696 	if (error)
697 		goto out_trans;
698 
699 	/*
700 	 * Commit the name and release all inode locks except for the scrub
701 	 * target's IOLOCK.
702 	 */
703 	error = xrep_trans_commit(sc);
704 	goto out_ilock;
705 
706 out_trans:
707 	xchk_trans_cancel(sc);
708 out_ilock:
709 	xchk_iunlock(sc, XFS_ILOCK_EXCL);
710 	xrep_orphanage_iunlock(sc, XFS_ILOCK_EXCL);
711 out_iolock:
712 	xrep_orphanage_iunlock(sc, XFS_IOLOCK_EXCL);
713 	return error;
714 }
715 
716 /*
717  * This newly orphaned directory needs to be adopted by the orphanage.
718  * Make this happen.
719  */
720 STATIC int
721 xrep_dirtree_move_to_orphanage(
722 	struct xchk_dirtree		*dl)
723 {
724 	struct xfs_scrub		*sc = dl->sc;
725 	int				error;
726 
727 	/*
728 	 * Start by dropping all the resources that we hold so that we can grab
729 	 * all the resources that we need for the adoption.
730 	 */
731 	mutex_unlock(&dl->lock);
732 	xchk_trans_cancel(sc);
733 	xchk_iunlock(sc, XFS_ILOCK_EXCL);
734 
735 	/* Perform the adoption. */
736 	error = xrep_dirtree_adopt(dl);
737 
738 	/*
739 	 * Retake all the resources we had at the beginning even if the repair
740 	 * failed or the scan data are now stale.  This keeps things simple for
741 	 * the caller.
742 	 */
743 	xchk_trans_alloc_empty(sc);
744 	xchk_ilock(sc, XFS_ILOCK_EXCL);
745 	mutex_lock(&dl->lock);
746 
747 	if (!error && dl->stale)
748 		error = -ESTALE;
749 	return error;
750 }
751 
752 /*
753  * Try to fix all the problems.  Returns -ESTALE if the scan data have become
754  * out of date.
755  */
756 STATIC int
757 xrep_dirtree_fix_problems(
758 	struct xchk_dirtree		*dl,
759 	struct xchk_dirtree_outcomes	*oc)
760 {
761 	struct xchk_dirpath		*path;
762 	int				error;
763 
764 	/* Delete all the paths we don't want. */
765 	xchk_dirtree_for_each_path(dl, path) {
766 		if (path->outcome != XCHK_DIRPATH_DELETE)
767 			continue;
768 
769 		error = xrep_dirtree_delete_path(dl, path);
770 		if (error)
771 			return error;
772 	}
773 
774 	/* Reparent this directory to the orphanage. */
775 	if (oc->needs_adoption) {
776 		if (xrep_orphanage_can_adopt(dl->sc))
777 			return xrep_dirtree_move_to_orphanage(dl);
778 		return -EFSCORRUPTED;
779 	}
780 
781 	return 0;
782 }
783 
784 /* Fix directory loops involving this directory. */
785 int
786 xrep_dirtree(
787 	struct xfs_scrub		*sc)
788 {
789 	struct xchk_dirtree		*dl = sc->buf;
790 	struct xchk_dirtree_outcomes	oc;
791 	int				error;
792 
793 	/*
794 	 * Prepare to fix the directory tree by retaking the scan lock.  The
795 	 * order of resource acquisition is still IOLOCK -> transaction ->
796 	 * ILOCK -> scan lock.
797 	 */
798 	mutex_lock(&dl->lock);
799 	do {
800 		/*
801 		 * Decide what we're going to do, then do it.  An -ESTALE
802 		 * return here means the scan results are invalid and we have
803 		 * to walk again.
804 		 */
805 		if (!dl->stale) {
806 			xrep_dirtree_decide_fate(dl, &oc);
807 
808 			trace_xrep_dirtree_decided_fate(dl, &oc);
809 
810 			error = xrep_dirtree_fix_problems(dl, &oc);
811 			if (!error || error != -ESTALE)
812 				break;
813 		}
814 		error = xchk_dirtree_find_paths_to_root(dl);
815 		if (error == -ELNRNG || error == -ENOSR)
816 			error = -EFSCORRUPTED;
817 	} while (!error);
818 	mutex_unlock(&dl->lock);
819 
820 	return error;
821 }
822