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_const(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 kstrdup_const("rtgroups", GFP_KERNEL), 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_const("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()
328 error = xchk_dir_lookup(sc, mpath->dp, &mpath->xname, &ino); in xchk_metapath()
329 trace_xchk_metapath_lookup(sc, mpath->path, mpath->dp, ino); in xchk_metapath()
330 if (error == -ENOENT) { in xchk_metapath()
332 xchk_ino_set_corrupt(sc, sc->ip->i_ino); in xchk_metapath()
338 if (ino != sc->ip->i_ino) { in xchk_metapath()
340 xchk_ino_set_corrupt(sc, sc->ip->i_ino); in xchk_metapath()
356 struct xfs_scrub *sc = mpath->sc; in xrep_metapath_link()
358 mpath->du.dp = mpath->dp; in xrep_metapath_link()
359 mpath->du.name = &mpath->xname; in xrep_metapath_link()
360 mpath->du.ip = sc->ip; in xrep_metapath_link()
362 if (xfs_has_parent(sc->mp)) in xrep_metapath_link()
363 mpath->du.ppargs = &mpath->link_ppargs; in xrep_metapath_link()
365 mpath->du.ppargs = NULL; in xrep_metapath_link()
367 trace_xrep_metapath_link(sc, mpath->path, mpath->dp, sc->ip->i_ino); in xrep_metapath_link()
369 return xfs_dir_add_child(sc->tp, mpath->link_resblks, &mpath->du); in xrep_metapath_link()
380 struct xfs_scrub *sc = mpath->sc; in xrep_metapath_unlink()
381 struct xfs_mount *mp = sc->mp; in xrep_metapath_unlink()
384 trace_xrep_metapath_unlink(sc, mpath->path, mpath->dp, ino); in xrep_metapath_unlink()
388 xfs_trans_log_inode(sc->tp, mpath->dp, XFS_ILOG_CORE); in xrep_metapath_unlink()
389 return xfs_dir_removename(sc->tp, mpath->dp, &mpath->xname, in xrep_metapath_unlink()
390 ino, mpath->unlink_resblks); in xrep_metapath_unlink()
393 mpath->du.dp = mpath->dp; in xrep_metapath_unlink()
394 mpath->du.name = &mpath->xname; in xrep_metapath_unlink()
395 mpath->du.ip = ip; in xrep_metapath_unlink()
396 mpath->du.ppargs = NULL; in xrep_metapath_unlink()
401 error = xfs_parent_lookup(sc->tp, ip, &mpath->xname, &rec, in xrep_metapath_unlink()
402 &mpath->pptr_args); in xrep_metapath_unlink()
404 case -ENOATTR: in xrep_metapath_unlink()
407 mpath->du.ppargs = &mpath->unlink_ppargs; in xrep_metapath_unlink()
414 return xfs_dir_remove_child(sc->tp, mpath->unlink_resblks, &mpath->du); in xrep_metapath_unlink()
418 * Try to create a dirent in @mpath->dp with the name @mpath->xname that points
419 * to @sc->ip. Returns:
421 * -EEXIST and an @alleged_child if the dirent that points to the wrong inode;
422 * 0 if there is now a dirent pointing to @sc->ip; or
430 struct xfs_scrub *sc = mpath->sc; in xrep_metapath_try_link()
435 error = xchk_trans_alloc(sc, mpath->link_resblks); in xrep_metapath_try_link()
444 xfs_trans_ijoin(sc->tp, mpath->dp, 0); in xrep_metapath_try_link()
445 xfs_trans_ijoin(sc->tp, sc->ip, 0); in xrep_metapath_try_link()
447 error = xchk_dir_lookup(sc, mpath->dp, &mpath->xname, &ino); in xrep_metapath_try_link()
448 trace_xrep_metapath_lookup(sc, mpath->path, mpath->dp, ino); in xrep_metapath_try_link()
449 if (error == -ENOENT) { in xrep_metapath_try_link()
452 * pointing to @sc->ip. in xrep_metapath_try_link()
465 if (ino == sc->ip->i_ino) { in xrep_metapath_try_link()
466 /* The dirent already points to @sc->ip; we're done. */ in xrep_metapath_try_link()
476 error = -EEXIST; in xrep_metapath_try_link()
488 * -EINTR to abort the repair. The lock state of @dp is not recorded in @mpath.
495 struct xfs_scrub *sc = mpath->sc; in xchk_metapath_ilock_parent_and_child()
499 xfs_ilock(mpath->dp, XFS_ILOCK_EXCL); in xchk_metapath_ilock_parent_and_child()
502 xfs_iunlock(mpath->dp, XFS_ILOCK_EXCL); in xchk_metapath_ilock_parent_and_child()
511 return -EINTR; in xchk_metapath_ilock_parent_and_child()
515 * Try to remove a dirent in @mpath->dp with the name @mpath->xname that points
519 * -EEXIST if the dirent points to @sc->ip;
520 * -EAGAIN and an updated @alleged_child if the dirent points elsewhere; or
528 struct xfs_scrub *sc = mpath->sc; in xrep_metapath_try_unlink()
533 ASSERT(*alleged_child != sc->ip->i_ino); in xrep_metapath_try_unlink()
535 trace_xrep_metapath_try_unlink(sc, mpath->path, mpath->dp, in xrep_metapath_try_unlink()
542 error = xchk_trans_alloc(sc, mpath->unlink_resblks); in xrep_metapath_try_unlink()
547 if (error == -EINVAL || error == -ENOENT) { in xrep_metapath_try_unlink()
561 xfs_trans_ijoin(sc->tp, mpath->dp, 0); in xrep_metapath_try_unlink()
563 xfs_trans_ijoin(sc->tp, ip, 0); in xrep_metapath_try_unlink()
565 error = xchk_dir_lookup(sc, mpath->dp, &mpath->xname, &ino); in xrep_metapath_try_unlink()
566 trace_xrep_metapath_lookup(sc, mpath->path, mpath->dp, ino); in xrep_metapath_try_unlink()
567 if (error == -ENOENT) { in xrep_metapath_try_unlink()
578 if (ino == sc->ip->i_ino) { in xrep_metapath_try_unlink()
579 /* The dirent already points to @sc->ip; we're done. */ in xrep_metapath_try_unlink()
580 error = -EEXIST; in xrep_metapath_try_unlink()
590 error = -EAGAIN; in xrep_metapath_try_unlink()
605 xfs_iunlock(mpath->dp, XFS_ILOCK_EXCL); in xrep_metapath_try_unlink()
624 struct xchk_metapath *mpath = sc->buf; in xrep_metapath()
625 struct xfs_mount *mp = sc->mp; in xrep_metapath()
629 if (sc->sm->sm_ino == XFS_SCRUB_METAPATH_PROBE) in xrep_metapath()
633 if (mpath->dp == NULL) in xrep_metapath()
634 return -EFSCORRUPTED; in xrep_metapath()
641 error = xfs_attr_add_fork(sc->ip, in xrep_metapath()
648 mpath->unlink_resblks = xfs_remove_space_res(mp, MAXNAMELEN); in xrep_metapath()
649 mpath->link_resblks = xfs_link_space_res(mp, MAXNAMELEN); in xrep_metapath()
654 /* Re-establish the link, or tell us which inode to remove. */ in xrep_metapath()
658 if (error != -EEXIST) in xrep_metapath()
667 } while (error == -EAGAIN); in xrep_metapath()
668 if (error == -EEXIST) { in xrep_metapath()
669 /* Link established; we're done. */ in xrep_metapath()