Lines Matching +full:scrubber +full:- +full:done

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) 2023-2024 Oracle. All Rights Reserved.
39 * metadata, this scrubber ensures that the ondisk metadir path points to the
80 if (mpath->dp_ilock_flags) in xchk_metapath_cleanup()
81 xfs_iunlock(mpath->dp, mpath->dp_ilock_flags); in xchk_metapath_cleanup()
82 kfree(mpath->path); in xchk_metapath_cleanup()
97 return -ENOMEM; in xchk_setup_metapath_scan()
108 return -ENOMEM; in xchk_setup_metapath_scan()
111 mpath->sc = sc; in xchk_setup_metapath_scan()
112 sc->buf = mpath; in xchk_setup_metapath_scan()
113 sc->buf_cleanup = xchk_metapath_cleanup; in xchk_setup_metapath_scan()
115 mpath->dp = dp; in xchk_setup_metapath_scan()
116 mpath->path = path; /* path is now owned by mpath */ in xchk_setup_metapath_scan()
118 mpath->xname.name = mpath->path; in xchk_setup_metapath_scan()
119 mpath->xname.len = strlen(mpath->path); in xchk_setup_metapath_scan()
120 mpath->xname.type = xfs_mode_to_ftype(VFS_I(ip)->i_mode); in xchk_setup_metapath_scan()
131 if (!sc->mp->m_rtdirip) in xchk_setup_metapath_rtdir()
132 return -ENOENT; in xchk_setup_metapath_rtdir()
134 return xchk_setup_metapath_scan(sc, sc->mp->m_metadirip, in xchk_setup_metapath_rtdir()
135 kasprintf(GFP_KERNEL, "rtgroups"), sc->mp->m_rtdirip); in xchk_setup_metapath_rtdir()
148 rtg = xfs_rtgroup_get(sc->mp, sc->sm->sm_agno); in xchk_setup_metapath_rtginode()
150 return -ENOENT; in xchk_setup_metapath_rtginode()
152 ip = rtg->rtg_inodes[type]; in xchk_setup_metapath_rtginode()
154 error = -ENOENT; in xchk_setup_metapath_rtginode()
158 error = xchk_setup_metapath_scan(sc, sc->mp->m_rtdirip, in xchk_setup_metapath_rtginode()
166 # define xchk_setup_metapath_rtdir(...) (-ENOENT)
167 # define xchk_setup_metapath_rtginode(...) (-ENOENT)
176 struct xfs_quotainfo *qi = sc->mp->m_quotainfo; in xchk_setup_metapath_quotadir()
178 if (!qi || !qi->qi_dirip) in xchk_setup_metapath_quotadir()
179 return -ENOENT; in xchk_setup_metapath_quotadir()
181 return xchk_setup_metapath_scan(sc, sc->mp->m_metadirip, in xchk_setup_metapath_quotadir()
182 kstrdup("quota", GFP_KERNEL), qi->qi_dirip); in xchk_setup_metapath_quotadir()
191 struct xfs_quotainfo *qi = sc->mp->m_quotainfo; in xchk_setup_metapath_dqinode()
195 return -ENOENT; in xchk_setup_metapath_dqinode()
199 ip = qi->qi_uquotaip; in xchk_setup_metapath_dqinode()
202 ip = qi->qi_gquotaip; in xchk_setup_metapath_dqinode()
205 ip = qi->qi_pquotaip; in xchk_setup_metapath_dqinode()
209 return -EINVAL; in xchk_setup_metapath_dqinode()
212 return -ENOENT; in xchk_setup_metapath_dqinode()
214 return xchk_setup_metapath_scan(sc, qi->qi_dirip, in xchk_setup_metapath_dqinode()
218 # define xchk_setup_metapath_quotadir(...) (-ENOENT)
219 # define xchk_setup_metapath_dqinode(...) (-ENOENT)
226 if (!xfs_has_metadir(sc->mp)) in xchk_setup_metapath()
227 return -ENOENT; in xchk_setup_metapath()
228 if (sc->sm->sm_gen) in xchk_setup_metapath()
229 return -EINVAL; in xchk_setup_metapath()
231 switch (sc->sm->sm_ino) { in xchk_setup_metapath()
234 if (sc->sm->sm_agno) in xchk_setup_metapath()
235 return -EINVAL; in xchk_setup_metapath()
256 return -ENOENT; in xchk_setup_metapath()
263 * to lock the child. Returns 0 if successful, or -EINTR to abort the scrub.
269 struct xfs_scrub *sc = mpath->sc; in xchk_metapath_ilock_both()
273 xfs_ilock(mpath->dp, XFS_ILOCK_EXCL); in xchk_metapath_ilock_both()
275 mpath->dp_ilock_flags |= XFS_ILOCK_EXCL; in xchk_metapath_ilock_both()
278 xfs_iunlock(mpath->dp, XFS_ILOCK_EXCL); in xchk_metapath_ilock_both()
287 return -EINTR; in xchk_metapath_ilock_both()
295 struct xfs_scrub *sc = mpath->sc; in xchk_metapath_iunlock()
299 mpath->dp_ilock_flags &= ~XFS_ILOCK_EXCL; in xchk_metapath_iunlock()
300 xfs_iunlock(mpath->dp, XFS_ILOCK_EXCL); in xchk_metapath_iunlock()
307 struct xchk_metapath *mpath = sc->buf; in xchk_metapath()
312 if (sc->sm->sm_ino == XFS_SCRUB_METAPATH_PROBE) in xchk_metapath()
316 if (mpath->dp == NULL) { in xchk_metapath()
317 xchk_ino_set_corrupt(sc, sc->ip->i_ino); in xchk_metapath()
330 error = xchk_dir_lookup(sc, mpath->dp, &mpath->xname, &ino); in xchk_metapath()
331 trace_xchk_metapath_lookup(sc, mpath->path, mpath->dp, ino); in xchk_metapath()
332 if (error == -ENOENT) { in xchk_metapath()
334 xchk_ino_set_corrupt(sc, sc->ip->i_ino); in xchk_metapath()
340 if (ino != sc->ip->i_ino) { in xchk_metapath()
342 xchk_ino_set_corrupt(sc, sc->ip->i_ino); in xchk_metapath()
358 struct xfs_scrub *sc = mpath->sc; in xrep_metapath_link()
360 mpath->du.dp = mpath->dp; in xrep_metapath_link()
361 mpath->du.name = &mpath->xname; in xrep_metapath_link()
362 mpath->du.ip = sc->ip; in xrep_metapath_link()
364 if (xfs_has_parent(sc->mp)) in xrep_metapath_link()
365 mpath->du.ppargs = &mpath->link_ppargs; in xrep_metapath_link()
367 mpath->du.ppargs = NULL; in xrep_metapath_link()
369 trace_xrep_metapath_link(sc, mpath->path, mpath->dp, sc->ip->i_ino); in xrep_metapath_link()
371 return xfs_dir_add_child(sc->tp, mpath->link_resblks, &mpath->du); in xrep_metapath_link()
382 struct xfs_scrub *sc = mpath->sc; in xrep_metapath_unlink()
383 struct xfs_mount *mp = sc->mp; in xrep_metapath_unlink()
386 trace_xrep_metapath_unlink(sc, mpath->path, mpath->dp, ino); in xrep_metapath_unlink()
390 xfs_trans_log_inode(sc->tp, mpath->dp, XFS_ILOG_CORE); in xrep_metapath_unlink()
391 return xfs_dir_removename(sc->tp, mpath->dp, &mpath->xname, in xrep_metapath_unlink()
392 ino, mpath->unlink_resblks); in xrep_metapath_unlink()
395 mpath->du.dp = mpath->dp; in xrep_metapath_unlink()
396 mpath->du.name = &mpath->xname; in xrep_metapath_unlink()
397 mpath->du.ip = ip; in xrep_metapath_unlink()
398 mpath->du.ppargs = NULL; in xrep_metapath_unlink()
403 error = xfs_parent_lookup(sc->tp, ip, &mpath->xname, &rec, in xrep_metapath_unlink()
404 &mpath->pptr_args); in xrep_metapath_unlink()
406 case -ENOATTR: in xrep_metapath_unlink()
409 mpath->du.ppargs = &mpath->unlink_ppargs; in xrep_metapath_unlink()
416 return xfs_dir_remove_child(sc->tp, mpath->unlink_resblks, &mpath->du); in xrep_metapath_unlink()
420 * Try to create a dirent in @mpath->dp with the name @mpath->xname that points
421 * to @sc->ip. Returns:
423 * -EEXIST and an @alleged_child if the dirent that points to the wrong inode;
424 * 0 if there is now a dirent pointing to @sc->ip; or
432 struct xfs_scrub *sc = mpath->sc; in xrep_metapath_try_link()
437 error = xchk_trans_alloc(sc, mpath->link_resblks); in xrep_metapath_try_link()
446 xfs_trans_ijoin(sc->tp, mpath->dp, 0); in xrep_metapath_try_link()
447 xfs_trans_ijoin(sc->tp, sc->ip, 0); in xrep_metapath_try_link()
449 error = xchk_dir_lookup(sc, mpath->dp, &mpath->xname, &ino); in xrep_metapath_try_link()
450 trace_xrep_metapath_lookup(sc, mpath->path, mpath->dp, ino); in xrep_metapath_try_link()
451 if (error == -ENOENT) { in xrep_metapath_try_link()
454 * pointing to @sc->ip. in xrep_metapath_try_link()
467 if (ino == sc->ip->i_ino) { in xrep_metapath_try_link()
468 /* The dirent already points to @sc->ip; we're done. */ in xrep_metapath_try_link()
478 error = -EEXIST; in xrep_metapath_try_link()
490 * -EINTR to abort the repair. The lock state of @dp is not recorded in @mpath.
497 struct xfs_scrub *sc = mpath->sc; in xchk_metapath_ilock_parent_and_child()
501 xfs_ilock(mpath->dp, XFS_ILOCK_EXCL); in xchk_metapath_ilock_parent_and_child()
504 xfs_iunlock(mpath->dp, XFS_ILOCK_EXCL); in xchk_metapath_ilock_parent_and_child()
513 return -EINTR; in xchk_metapath_ilock_parent_and_child()
517 * Try to remove a dirent in @mpath->dp with the name @mpath->xname that points
521 * -EEXIST if the dirent points to @sc->ip;
522 * -EAGAIN and an updated @alleged_child if the dirent points elsewhere; or
530 struct xfs_scrub *sc = mpath->sc; in xrep_metapath_try_unlink()
535 ASSERT(*alleged_child != sc->ip->i_ino); in xrep_metapath_try_unlink()
537 trace_xrep_metapath_try_unlink(sc, mpath->path, mpath->dp, in xrep_metapath_try_unlink()
544 error = xchk_trans_alloc(sc, mpath->unlink_resblks); in xrep_metapath_try_unlink()
549 if (error == -EINVAL || error == -ENOENT) { in xrep_metapath_try_unlink()
563 xfs_trans_ijoin(sc->tp, mpath->dp, 0); in xrep_metapath_try_unlink()
565 xfs_trans_ijoin(sc->tp, ip, 0); in xrep_metapath_try_unlink()
567 error = xchk_dir_lookup(sc, mpath->dp, &mpath->xname, &ino); in xrep_metapath_try_unlink()
568 trace_xrep_metapath_lookup(sc, mpath->path, mpath->dp, ino); in xrep_metapath_try_unlink()
569 if (error == -ENOENT) { in xrep_metapath_try_unlink()
580 if (ino == sc->ip->i_ino) { in xrep_metapath_try_unlink()
581 /* The dirent already points to @sc->ip; we're done. */ in xrep_metapath_try_unlink()
582 error = -EEXIST; in xrep_metapath_try_unlink()
592 error = -EAGAIN; in xrep_metapath_try_unlink()
607 xfs_iunlock(mpath->dp, XFS_ILOCK_EXCL); in xrep_metapath_try_unlink()
626 struct xchk_metapath *mpath = sc->buf; in xrep_metapath()
627 struct xfs_mount *mp = sc->mp; in xrep_metapath()
631 if (sc->sm->sm_ino == XFS_SCRUB_METAPATH_PROBE) in xrep_metapath()
635 if (mpath->dp == NULL) in xrep_metapath()
636 return -EFSCORRUPTED; in xrep_metapath()
643 error = xfs_attr_add_fork(sc->ip, in xrep_metapath()
650 mpath->unlink_resblks = xfs_remove_space_res(mp, MAXNAMELEN); in xrep_metapath()
651 mpath->link_resblks = xfs_link_space_res(mp, MAXNAMELEN); in xrep_metapath()
656 /* Re-establish the link, or tell us which inode to remove. */ in xrep_metapath()
660 if (error != -EEXIST) in xrep_metapath()
669 } while (error == -EAGAIN); in xrep_metapath()
670 if (error == -EEXIST) { in xrep_metapath()
671 /* Link established; we're done. */ in xrep_metapath()