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
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 (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
xrep_dirtree_unlink(struct xchk_dirtree * dl,struct xfs_inode * dp,struct xchk_dirpath * path,struct xchk_dirpath_step * step)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
xrep_dirtree_delete_path(struct xchk_dirtree * dl,struct xchk_dirpath * path)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
xrep_dirtree_create_adoption_path(struct xchk_dirtree * dl)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
xrep_dirtree_adopt_iolock(struct xfs_scrub * sc)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
xrep_dirtree_adopt(struct xchk_dirtree * dl)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
xrep_dirtree_move_to_orphanage(struct xchk_dirtree * dl)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
xrep_dirtree_fix_problems(struct xchk_dirtree * dl,struct xchk_dirtree_outcomes * oc)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
xrep_dirtree(struct xfs_scrub * sc)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