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