xref: /linux/fs/xfs/scrub/dirtree_repair.c (revision 546b928da0427b0d6c663cbb992bd7bfa9ac7971)
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_platform.h"
7 #include "xfs_fs.h"
8 #include "xfs_shared.h"
9 #include "xfs_format.h"
10 #include "xfs_trans_resv.h"
11 #include "xfs_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
xrep_setup_dirtree(struct xfs_scrub * sc)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
xrep_dirpath_set_outcome(struct xchk_dirtree * dl,struct xchk_dirpath * path,enum xchk_dirpath_outcome outcome)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
xrep_dirtree_delete_all_paths(struct xchk_dirtree * dl,struct xchk_dirtree_outcomes * oc)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
xrep_dirpath_retain_parent(struct xchk_dirtree * dl,struct xchk_dirpath * path)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
xrep_dirtree_find_surviving_path(struct xchk_dirtree * dl,struct xchk_dirtree_outcomes * oc)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
xrep_dirtree_keep_one_good_path(struct xchk_dirtree * dl,struct xchk_dirtree_outcomes * oc)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
xrep_dirtree_keep_one_suspect_path(struct xchk_dirtree * dl,struct xchk_dirtree_outcomes * oc)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
xrep_dirtree_decide_fate(struct xchk_dirtree * dl,struct xchk_dirtree_outcomes * oc)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
xrep_dirtree_prep_path(struct xchk_dirtree * dl,struct xchk_dirpath * path,struct xchk_dirpath_step * step)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
xrep_dirtree_purge_dentry(struct xchk_dirtree * dl,struct xfs_inode * dp,const struct xfs_name * name)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
xrep_dirtree_unlink_iolock(struct xfs_scrub * sc,struct xfs_inode * dp)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 (sc->ip == dp)
353 		return 0;
354 	if (xfs_ilock_nowait(dp, XFS_IOLOCK_EXCL))
355 		return 0;
356 
357 	xchk_iunlock(sc, XFS_IOLOCK_EXCL);
358 	do {
359 		xfs_ilock(dp, XFS_IOLOCK_EXCL);
360 		if (xchk_ilock_nowait(sc, XFS_IOLOCK_EXCL))
361 			break;
362 		xfs_iunlock(dp, XFS_IOLOCK_EXCL);
363 
364 		if (xchk_should_terminate(sc, &error)) {
365 			xchk_ilock(sc, XFS_IOLOCK_EXCL);
366 			return error;
367 		}
368 
369 		delay(1);
370 	} while (1);
371 
372 	return 0;
373 }
374 
375 /*
376  * Remove a link from the directory tree and update the dcache.  Returns
377  * -ESTALE if the scan data are now out of date.
378  */
379 STATIC int
xrep_dirtree_unlink(struct xchk_dirtree * dl,struct xfs_inode * dp,struct xchk_dirpath * path,struct xchk_dirpath_step * step)380 xrep_dirtree_unlink(
381 	struct xchk_dirtree		*dl,
382 	struct xfs_inode		*dp,
383 	struct xchk_dirpath		*path,
384 	struct xchk_dirpath_step	*step)
385 {
386 	struct xfs_scrub		*sc = dl->sc;
387 	struct xfs_mount		*mp = sc->mp;
388 	xfs_ino_t			dotdot_ino;
389 	xfs_ino_t			parent_ino = dl->parent_ino;
390 	unsigned int			resblks;
391 	int				dontcare;
392 	int				error;
393 
394 	/* Take IOLOCK_EXCL of the parent and child. */
395 	error = xrep_dirtree_unlink_iolock(sc, dp);
396 	if (error)
397 		return error;
398 
399 	/*
400 	 * Create the transaction that we need to sever the path.  Ignore
401 	 * EDQUOT and ENOSPC being returned via nospace_error because the
402 	 * directory code can handle a reservationless update.
403 	 */
404 	resblks = xfs_remove_space_res(mp, step->name_len);
405 	if (sc->ip == dp) {
406 again:
407 		error = xfs_trans_alloc_inode(dp, &M_RES(mp)->tr_remove,
408 				resblks, 0, false, &sc->tp);
409 		if ((error == -ENOSPC || error == -EDQUOT) && resblks > 0) {
410 			resblks = 0;
411 			goto again;
412 		}
413 	} else {
414 		error = xfs_trans_alloc_dir(dp, &M_RES(mp)->tr_remove, sc->ip,
415 				&resblks, &sc->tp, &dontcare);
416 	}
417 	if (error)
418 		goto out_iolock;
419 
420 	/*
421 	 * Cancel if someone invalidate the paths while we were trying to get
422 	 * the ILOCK.
423 	 */
424 	mutex_lock(&dl->lock);
425 	if (dl->stale) {
426 		mutex_unlock(&dl->lock);
427 		error = -ESTALE;
428 		goto out_trans_cancel;
429 	}
430 	xrep_dirpath_set_outcome(dl, path, XREP_DIRPATH_DELETING);
431 	mutex_unlock(&dl->lock);
432 
433 	trace_xrep_dirtree_delete_path(dl->sc, sc->ip, path->path_nr,
434 			&dl->xname, &dl->pptr_rec);
435 
436 	/*
437 	 * Decide if we need to reset the dotdot entry.  Rules:
438 	 *
439 	 * - If there's a surviving parent, we want dotdot to point there.
440 	 * - If we don't have any surviving parents, then point dotdot at the
441 	 *   root dir.
442 	 * - If dotdot is already set to the value we want, pass in NULLFSINO
443 	 *   for no change necessary.
444 	 *
445 	 * Do this /before/ we dirty anything, in case the dotdot lookup
446 	 * fails.
447 	 */
448 	error = xchk_dir_lookup(sc, sc->ip, &xfs_name_dotdot, &dotdot_ino);
449 	if (error)
450 		goto out_trans_cancel;
451 	if (parent_ino == NULLFSINO)
452 		parent_ino = dl->root_ino;
453 	if (dotdot_ino == parent_ino)
454 		parent_ino = NULLFSINO;
455 
456 	/* Drop the link from sc->ip's dotdot entry.  */
457 	error = xfs_droplink(sc->tp, dp);
458 	if (error)
459 		goto out_trans_cancel;
460 
461 	/* Reset the dotdot entry to a surviving parent. */
462 	if (parent_ino != NULLFSINO) {
463 		error = xfs_dir_replace(sc->tp, sc->ip, &xfs_name_dotdot,
464 				parent_ino, 0);
465 		if (error)
466 			goto out_trans_cancel;
467 	}
468 
469 	/* Drop the link from dp to sc->ip. */
470 	error = xfs_droplink(sc->tp, sc->ip);
471 	if (error)
472 		goto out_trans_cancel;
473 
474 	error = xfs_dir_removename(sc->tp, dp, &dl->xname, I_INO(sc->ip),
475 			resblks);
476 	if (error) {
477 		ASSERT(error != -ENOENT);
478 		goto out_trans_cancel;
479 	}
480 
481 	if (xfs_has_parent(sc->mp)) {
482 		memset(&dl->ppargs, 0, sizeof(dl->ppargs));
483 		error = xfs_parent_removename(sc->tp, &dl->ppargs, dp,
484 				&dl->xname, sc->ip);
485 		if (error)
486 			goto out_trans_cancel;
487 	}
488 
489 	/*
490 	 * Notify dirent hooks that we removed the bad link, invalidate the
491 	 * dcache, and commit the repair.
492 	 */
493 	xfs_dir_update_hook(dp, sc->ip, -1, &dl->xname);
494 	error = xrep_dirtree_purge_dentry(dl, dp, &dl->xname);
495 	if (error)
496 		goto out_trans_cancel;
497 
498 	error = xrep_trans_commit(sc);
499 	goto out_ilock;
500 
501 out_trans_cancel:
502 	xchk_trans_cancel(sc);
503 out_ilock:
504 	xfs_iunlock(sc->ip, XFS_ILOCK_EXCL);
505 	if (dp != sc->ip)
506 		xfs_iunlock(dp, XFS_ILOCK_EXCL);
507 out_iolock:
508 	if (dp != sc->ip)
509 		xfs_iunlock(dp, XFS_IOLOCK_EXCL);
510 	return error;
511 }
512 
513 /*
514  * Delete a directory entry that points to this directory.  Returns -ESTALE
515  * if the scan data are now out of date.
516  */
517 STATIC int
xrep_dirtree_delete_path(struct xchk_dirtree * dl,struct xchk_dirpath * path)518 xrep_dirtree_delete_path(
519 	struct xchk_dirtree		*dl,
520 	struct xchk_dirpath		*path)
521 {
522 	struct xchk_dirpath_step	step;
523 	struct xfs_scrub		*sc = dl->sc;
524 	struct xfs_inode		*dp;
525 	int				error;
526 
527 	/*
528 	 * Load the parent pointer and directory inode for this path, then
529 	 * drop the scan lock, the ILOCK, and the transaction so that
530 	 * _delete_path can reserve the proper transaction.  This sets up
531 	 * @dl->xname for the deletion.
532 	 */
533 	error = xrep_dirtree_prep_path(dl, path, &step);
534 	if (error)
535 		return error;
536 
537 	error = xchk_iget(sc, be64_to_cpu(step.pptr_rec.p_ino), &dp);
538 	if (error)
539 		return error;
540 
541 	mutex_unlock(&dl->lock);
542 	xchk_trans_cancel(sc);
543 	xchk_iunlock(sc, XFS_ILOCK_EXCL);
544 
545 	/* Delete the directory link and release the parent. */
546 	error = xrep_dirtree_unlink(dl, dp, path, &step);
547 	xchk_irele(sc, dp);
548 
549 	/*
550 	 * Retake all the resources we had at the beginning even if the repair
551 	 * failed or the scan data are now stale.  This keeps things simple for
552 	 * the caller.
553 	 */
554 	xchk_trans_alloc_empty(sc);
555 	xchk_ilock(sc, XFS_ILOCK_EXCL);
556 	mutex_lock(&dl->lock);
557 
558 	if (!error && dl->stale)
559 		error = -ESTALE;
560 	return error;
561 }
562 
563 /* Add a new path to represent our in-progress adoption. */
564 STATIC int
xrep_dirtree_create_adoption_path(struct xchk_dirtree * dl)565 xrep_dirtree_create_adoption_path(
566 	struct xchk_dirtree		*dl)
567 {
568 	struct xfs_scrub		*sc = dl->sc;
569 	struct xchk_dirpath		*path;
570 	int				error;
571 
572 	/*
573 	 * We should have capped the number of paths at XFS_MAXLINK-1 in the
574 	 * scanner.
575 	 */
576 	if (dl->nr_paths > XFS_MAXLINK) {
577 		ASSERT(dl->nr_paths <= XFS_MAXLINK);
578 		return -EFSCORRUPTED;
579 	}
580 
581 	/*
582 	 * Create a new xchk_path structure to remember this parent pointer
583 	 * and record the first name step.
584 	 */
585 	path = kmalloc_obj(struct xchk_dirpath, XCHK_GFP_FLAGS);
586 	if (!path)
587 		return -ENOMEM;
588 
589 	INIT_LIST_HEAD(&path->list);
590 	xino_bitmap_init(&path->seen_inodes);
591 	path->nr_steps = 0;
592 	path->outcome = XREP_DIRPATH_ADOPTING;
593 
594 	/*
595 	 * Record the new link that we just created in the orphanage.  Because
596 	 * adoption is the last repair that we perform, we don't bother filling
597 	 * in the path all the way back to the root.
598 	 */
599 	xfs_inode_to_parent_rec(&dl->pptr_rec, sc->orphanage);
600 
601 	error = xino_bitmap_set(&path->seen_inodes, I_INO(sc->orphanage));
602 	if (error)
603 		goto out_path;
604 
605 	trace_xrep_dirtree_create_adoption(sc, sc->ip, dl->nr_paths,
606 			&dl->xname, &dl->pptr_rec);
607 
608 	error = xchk_dirpath_append(dl, sc->ip, path, &dl->xname,
609 			&dl->pptr_rec);
610 	if (error)
611 		goto out_path;
612 
613 	path->first_step = xfarray_length(dl->path_steps) - 1;
614 	path->second_step = XFARRAY_NULLIDX;
615 	path->path_nr = dl->nr_paths;
616 
617 	list_add_tail(&path->list, &dl->path_list);
618 	dl->nr_paths++;
619 	return 0;
620 
621 out_path:
622 	xino_bitmap_destroy(&path->seen_inodes);
623 	kfree(path);
624 	return error;
625 }
626 
627 /*
628  * Prepare to move a file to the orphanage by taking the IOLOCK of the
629  * orphanage and the child (scrub target).  Caller must hold IOLOCK_EXCL on
630  * @sc->ip.  Returns 0 if we took both locks, or a negative errno if we
631  * couldn't lock the orphanage in time.
632  */
633 static inline int
xrep_dirtree_adopt_iolock(struct xfs_scrub * sc)634 xrep_dirtree_adopt_iolock(
635 	struct xfs_scrub	*sc)
636 {
637 	int			error;
638 
639 	ASSERT(sc->ilock_flags & XFS_IOLOCK_EXCL);
640 
641 	if (xrep_orphanage_ilock_nowait(sc, XFS_IOLOCK_EXCL))
642 		return 0;
643 
644 	xchk_iunlock(sc, XFS_IOLOCK_EXCL);
645 	do {
646 		xrep_orphanage_ilock(sc, XFS_IOLOCK_EXCL);
647 		if (xchk_ilock_nowait(sc, XFS_IOLOCK_EXCL))
648 			break;
649 		xrep_orphanage_iunlock(sc, XFS_IOLOCK_EXCL);
650 
651 		if (xchk_should_terminate(sc, &error)) {
652 			xchk_ilock(sc, XFS_IOLOCK_EXCL);
653 			return error;
654 		}
655 
656 		delay(1);
657 	} while (1);
658 
659 	return 0;
660 }
661 
662 /*
663  * Reattach this orphaned directory to the orphanage.  Do not call this with
664  * any resources held.  Returns -ESTALE if the scan data have become out of
665  * date.
666  */
667 STATIC int
xrep_dirtree_adopt(struct xchk_dirtree * dl)668 xrep_dirtree_adopt(
669 	struct xchk_dirtree		*dl)
670 {
671 	struct xfs_scrub		*sc = dl->sc;
672 	int				error;
673 
674 	/* Take the IOLOCK of the orphanage and the scrub target. */
675 	error = xrep_dirtree_adopt_iolock(sc);
676 	if (error)
677 		return error;
678 
679 	/*
680 	 * Set up for an adoption.  The directory tree fixer runs after the
681 	 * link counts have been corrected.  Therefore, we must bump the
682 	 * child's link count since there will be no further opportunity to fix
683 	 * errors.
684 	 */
685 	error = xrep_adoption_trans_alloc(sc, &dl->adoption);
686 	if (error)
687 		goto out_iolock;
688 	dl->adoption.bump_child_nlink = true;
689 
690 	/* Figure out what name we're going to use here. */
691 	error = xrep_adoption_compute_name(&dl->adoption, &dl->xname);
692 	if (error)
693 		goto out_trans;
694 
695 	/*
696 	 * Now that we have a proposed name for the orphanage entry, create
697 	 * a faux path so that the live update hook will see it.
698 	 */
699 	mutex_lock(&dl->lock);
700 	if (dl->stale) {
701 		mutex_unlock(&dl->lock);
702 		error = -ESTALE;
703 		goto out_trans;
704 	}
705 	error = xrep_dirtree_create_adoption_path(dl);
706 	mutex_unlock(&dl->lock);
707 	if (error)
708 		goto out_trans;
709 
710 	/* Reparent the directory. */
711 	error = xrep_adoption_move(&dl->adoption);
712 	if (error)
713 		goto out_trans;
714 
715 	/*
716 	 * Commit the name and release all inode locks except for the scrub
717 	 * target's IOLOCK.
718 	 */
719 	error = xrep_trans_commit(sc);
720 	goto out_ilock;
721 
722 out_trans:
723 	xchk_trans_cancel(sc);
724 out_ilock:
725 	xchk_iunlock(sc, XFS_ILOCK_EXCL);
726 	xrep_orphanage_iunlock(sc, XFS_ILOCK_EXCL);
727 out_iolock:
728 	xrep_orphanage_iunlock(sc, XFS_IOLOCK_EXCL);
729 	return error;
730 }
731 
732 /*
733  * This newly orphaned directory needs to be adopted by the orphanage.
734  * Make this happen.
735  */
736 STATIC int
xrep_dirtree_move_to_orphanage(struct xchk_dirtree * dl)737 xrep_dirtree_move_to_orphanage(
738 	struct xchk_dirtree		*dl)
739 {
740 	struct xfs_scrub		*sc = dl->sc;
741 	int				error;
742 
743 	/*
744 	 * Start by dropping all the resources that we hold so that we can grab
745 	 * all the resources that we need for the adoption.
746 	 */
747 	mutex_unlock(&dl->lock);
748 	xchk_trans_cancel(sc);
749 	xchk_iunlock(sc, XFS_ILOCK_EXCL);
750 
751 	/* Perform the adoption. */
752 	error = xrep_dirtree_adopt(dl);
753 
754 	/*
755 	 * Retake all the resources we had at the beginning even if the repair
756 	 * failed or the scan data are now stale.  This keeps things simple for
757 	 * the caller.
758 	 */
759 	xchk_trans_alloc_empty(sc);
760 	xchk_ilock(sc, XFS_ILOCK_EXCL);
761 	mutex_lock(&dl->lock);
762 
763 	if (!error && dl->stale)
764 		error = -ESTALE;
765 	return error;
766 }
767 
768 /*
769  * Try to fix all the problems.  Returns -ESTALE if the scan data have become
770  * out of date.
771  */
772 STATIC int
xrep_dirtree_fix_problems(struct xchk_dirtree * dl,struct xchk_dirtree_outcomes * oc)773 xrep_dirtree_fix_problems(
774 	struct xchk_dirtree		*dl,
775 	struct xchk_dirtree_outcomes	*oc)
776 {
777 	struct xchk_dirpath		*path;
778 	int				error;
779 
780 	/* Delete all the paths we don't want. */
781 	xchk_dirtree_for_each_path(dl, path) {
782 		if (path->outcome != XCHK_DIRPATH_DELETE)
783 			continue;
784 
785 		error = xrep_dirtree_delete_path(dl, path);
786 		if (error)
787 			return error;
788 	}
789 
790 	/* Reparent this directory to the orphanage. */
791 	if (oc->needs_adoption) {
792 		if (xrep_orphanage_can_adopt(dl->sc))
793 			return xrep_dirtree_move_to_orphanage(dl);
794 		return -EFSCORRUPTED;
795 	}
796 
797 	return 0;
798 }
799 
800 /* Fix directory loops involving this directory. */
801 int
xrep_dirtree(struct xfs_scrub * sc)802 xrep_dirtree(
803 	struct xfs_scrub		*sc)
804 {
805 	struct xchk_dirtree		*dl = sc->buf;
806 	struct xchk_dirtree_outcomes	oc;
807 	int				error;
808 
809 	/*
810 	 * Prepare to fix the directory tree by retaking the scan lock.  The
811 	 * order of resource acquisition is still IOLOCK -> transaction ->
812 	 * ILOCK -> scan lock.
813 	 */
814 	mutex_lock(&dl->lock);
815 	do {
816 		/*
817 		 * Decide what we're going to do, then do it.  An -ESTALE
818 		 * return here means the scan results are invalid and we have
819 		 * to walk again.
820 		 */
821 		if (!dl->stale) {
822 			xrep_dirtree_decide_fate(dl, &oc);
823 
824 			trace_xrep_dirtree_decided_fate(dl, &oc);
825 
826 			error = xrep_dirtree_fix_problems(dl, &oc);
827 			if (!error || error != -ESTALE)
828 				break;
829 		}
830 		error = xchk_dirtree_find_paths_to_root(dl);
831 		if (error == -ELNRNG || error == -ENOSR)
832 			error = -EFSCORRUPTED;
833 	} while (!error);
834 	mutex_unlock(&dl->lock);
835 
836 	return error;
837 }
838