Lines Matching +full:scrubber +full:- +full:done
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) 2020-2024 Oracle. All Rights Reserved.
84 if (!XFS_IS_QUOTA_ON(sc->mp)) in xchk_setup_quotacheck()
85 return -ENOENT; in xchk_setup_quotacheck()
89 sc->buf = kzalloc(sizeof(struct xqcheck), XCHK_GFP_FLAGS); in xchk_setup_quotacheck()
90 if (!sc->buf) in xchk_setup_quotacheck()
91 return -ENOMEM; in xchk_setup_quotacheck()
113 * per-transaction dqtrx structure to log quota counter updates; and (2) when
119 * failures in the hook code must abort the iscan and the scrubber must notice
149 if (error == -EFBIG) { in xqcheck_update_incore_counts()
155 error = -ECANCELED; in xqcheck_update_incore_counts()
166 const uintptr_t *tx_idp = arg->key; in xqcheck_dqacct_obj_cmpfn()
169 if (dqa->tx_id != *tx_idp) in xqcheck_dqacct_obj_cmpfn()
193 if (dqa->dqtrx[i].q_type == 0 || in xqcheck_get_dqtrx()
194 (dqa->dqtrx[i].q_type == q_type && in xqcheck_get_dqtrx()
195 dqa->dqtrx[i].q_id == q_id)) in xqcheck_get_dqtrx()
196 return &dqa->dqtrx[i]; in xqcheck_get_dqtrx()
233 switch (p->q_type) { in xqcheck_mod_live_ino_dqtrx()
235 if (!xqc->ucounts) in xqcheck_mod_live_ino_dqtrx()
239 if (!xqc->gcounts) in xqcheck_mod_live_ino_dqtrx()
243 if (!xqc->pcounts) in xqcheck_mod_live_ino_dqtrx()
251 if (!xchk_iscan_want_live_update(&xqc->iscan, p->ino)) in xqcheck_mod_live_ino_dqtrx()
255 mutex_lock(&xqc->lock); in xqcheck_mod_live_ino_dqtrx()
256 dqa = rhashtable_lookup_fast(&xqc->shadow_dquot_acct, &p->tx_id, in xqcheck_mod_live_ino_dqtrx()
263 dqa->tx_id = p->tx_id; in xqcheck_mod_live_ino_dqtrx()
264 error = rhashtable_insert_fast(&xqc->shadow_dquot_acct, in xqcheck_mod_live_ino_dqtrx()
265 &dqa->hash, xqcheck_dqacct_hash_params); in xqcheck_mod_live_ino_dqtrx()
271 dqtrx = xqcheck_get_dqtrx(dqa, p->q_type, p->q_id); in xqcheck_mod_live_ino_dqtrx()
274 if (dqtrx->q_type == 0) { in xqcheck_mod_live_ino_dqtrx()
275 dqtrx->q_type = p->q_type; in xqcheck_mod_live_ino_dqtrx()
276 dqtrx->q_id = p->q_id; in xqcheck_mod_live_ino_dqtrx()
277 dqa->refcount++; in xqcheck_mod_live_ino_dqtrx()
283 dqtrx->bcount_delta += p->delta; in xqcheck_mod_live_ino_dqtrx()
286 dqtrx->delbcnt_delta += p->delta; in xqcheck_mod_live_ino_dqtrx()
289 dqtrx->icount_delta += p->delta; in xqcheck_mod_live_ino_dqtrx()
292 dqtrx->rtbcount_delta += p->delta; in xqcheck_mod_live_ino_dqtrx()
295 dqtrx->delrtb_delta += p->delta; in xqcheck_mod_live_ino_dqtrx()
299 mutex_unlock(&xqc->lock); in xqcheck_mod_live_ino_dqtrx()
303 xchk_iscan_abort(&xqc->iscan); in xqcheck_mod_live_ino_dqtrx()
304 mutex_unlock(&xqc->lock); in xqcheck_mod_live_ino_dqtrx()
328 switch (p->q_type) { in xqcheck_apply_live_dqtrx()
330 counts = xqc->ucounts; in xqcheck_apply_live_dqtrx()
333 counts = xqc->gcounts; in xqcheck_apply_live_dqtrx()
336 counts = xqc->pcounts; in xqcheck_apply_live_dqtrx()
342 if (xchk_iscan_aborted(&xqc->iscan) || counts == NULL) in xqcheck_apply_live_dqtrx()
349 mutex_lock(&xqc->lock); in xqcheck_apply_live_dqtrx()
350 dqa = rhashtable_lookup_fast(&xqc->shadow_dquot_acct, &p->tx_id, in xqcheck_apply_live_dqtrx()
354 dqtrx = xqcheck_get_dqtrx(dqa, p->q_type, p->q_id); in xqcheck_apply_live_dqtrx()
355 if (!dqtrx || dqtrx->q_type == 0) in xqcheck_apply_live_dqtrx()
360 error = xqcheck_update_incore_counts(xqc, counts, p->q_id, in xqcheck_apply_live_dqtrx()
361 dqtrx->icount_delta, in xqcheck_apply_live_dqtrx()
362 dqtrx->bcount_delta + dqtrx->delbcnt_delta, in xqcheck_apply_live_dqtrx()
363 dqtrx->rtbcount_delta + dqtrx->delrtb_delta); in xqcheck_apply_live_dqtrx()
369 dqa->refcount--; in xqcheck_apply_live_dqtrx()
370 if (dqa->refcount == 0) { in xqcheck_apply_live_dqtrx()
371 error = rhashtable_remove_fast(&xqc->shadow_dquot_acct, in xqcheck_apply_live_dqtrx()
372 &dqa->hash, xqcheck_dqacct_hash_params); in xqcheck_apply_live_dqtrx()
378 mutex_unlock(&xqc->lock); in xqcheck_apply_live_dqtrx()
382 xchk_iscan_abort(&xqc->iscan); in xqcheck_apply_live_dqtrx()
384 mutex_unlock(&xqc->lock); in xqcheck_apply_live_dqtrx()
394 struct xfs_trans *tp = xqc->sc->tp; in xqcheck_collect_inode()
398 bool isreg = S_ISREG(VFS_I(ip)->i_mode); in xqcheck_collect_inode()
402 xfs_is_quota_inode(&tp->t_mountp->m_sb, ip->i_ino)) { in xqcheck_collect_inode()
409 xchk_iscan_mark_visited(&xqc->iscan, ip); in xqcheck_collect_inode()
433 if (xchk_iscan_aborted(&xqc->iscan)) { in xqcheck_collect_inode()
434 error = -ECANCELED; in xqcheck_collect_inode()
439 mutex_lock(&xqc->lock); in xqcheck_collect_inode()
440 if (xqc->ucounts) { in xqcheck_collect_inode()
442 error = xqcheck_update_incore_counts(xqc, xqc->ucounts, id, 1, in xqcheck_collect_inode()
448 if (xqc->gcounts) { in xqcheck_collect_inode()
450 error = xqcheck_update_incore_counts(xqc, xqc->gcounts, id, 1, in xqcheck_collect_inode()
456 if (xqc->pcounts) { in xqcheck_collect_inode()
458 error = xqcheck_update_incore_counts(xqc, xqc->pcounts, id, 1, in xqcheck_collect_inode()
463 mutex_unlock(&xqc->lock); in xqcheck_collect_inode()
465 xchk_iscan_mark_visited(&xqc->iscan, ip); in xqcheck_collect_inode()
469 mutex_unlock(&xqc->lock); in xqcheck_collect_inode()
471 xchk_iscan_abort(&xqc->iscan); in xqcheck_collect_inode()
473 xchk_set_incomplete(xqc->sc); in xqcheck_collect_inode()
487 struct xfs_scrub *sc = xqc->sc; in xqcheck_collect_counts()
502 * repeatedly cycling empty transactions. This can be done without in xqcheck_collect_counts()
512 while ((error = xchk_iscan_iter(&xqc->iscan, &ip)) == 1) { in xqcheck_collect_counts()
521 xchk_iscan_iter_finish(&xqc->iscan); in xqcheck_collect_counts()
529 if (error == -EBUSY) in xqcheck_collect_counts()
530 return -ECANCELED; in xqcheck_collect_counts()
563 if (xchk_iscan_aborted(&xqc->iscan)) { in xqcheck_compare_dquot()
564 xchk_set_incomplete(xqc->sc); in xqcheck_compare_dquot()
565 return -ECANCELED; in xqcheck_compare_dquot()
568 mutex_lock(&xqc->lock); in xqcheck_compare_dquot()
569 error = xfarray_load_sparse(counts, dq->q_id, &xcdq); in xqcheck_compare_dquot()
573 if (xcdq.icount != dq->q_ino.count) in xqcheck_compare_dquot()
574 xchk_qcheck_set_corrupt(xqc->sc, dqtype, dq->q_id); in xqcheck_compare_dquot()
576 if (xcdq.bcount != dq->q_blk.count) in xqcheck_compare_dquot()
577 xchk_qcheck_set_corrupt(xqc->sc, dqtype, dq->q_id); in xqcheck_compare_dquot()
579 if (xcdq.rtbcount != dq->q_rtb.count) in xqcheck_compare_dquot()
580 xchk_qcheck_set_corrupt(xqc->sc, dqtype, dq->q_id); in xqcheck_compare_dquot()
583 error = xfarray_store(counts, dq->q_id, &xcdq); in xqcheck_compare_dquot()
584 if (error == -EFBIG) { in xqcheck_compare_dquot()
591 xchk_set_incomplete(xqc->sc); in xqcheck_compare_dquot()
592 error = -ECANCELED; in xqcheck_compare_dquot()
594 mutex_unlock(&xqc->lock); in xqcheck_compare_dquot()
598 if (xqc->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) in xqcheck_compare_dquot()
599 return -ECANCELED; in xqcheck_compare_dquot()
604 mutex_unlock(&xqc->lock); in xqcheck_compare_dquot()
623 mutex_lock(&xqc->lock); in xqcheck_walk_observations()
625 xfs_dqid_t id = cur - 1; in xqcheck_walk_observations()
630 mutex_unlock(&xqc->lock); in xqcheck_walk_observations()
632 error = xfs_qm_dqget(xqc->sc->mp, id, dqtype, false, &dq); in xqcheck_walk_observations()
633 if (error == -ENOENT) { in xqcheck_walk_observations()
634 xchk_qcheck_set_corrupt(xqc->sc, dqtype, id); in xqcheck_walk_observations()
645 if (xchk_should_terminate(xqc->sc, &error)) in xqcheck_walk_observations()
648 mutex_lock(&xqc->lock); in xqcheck_walk_observations()
650 mutex_unlock(&xqc->lock); in xqcheck_walk_observations()
662 struct xfs_scrub *sc = xqc->sc; in xqcheck_compare_dqtype()
666 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) in xqcheck_compare_dqtype()
670 if (!(xfs_quota_chkd_flag(dqtype) & sc->mp->m_qflags)) { in xqcheck_compare_dqtype()
671 xchk_qcheck_set_corrupt(xqc->sc, dqtype, 0); in xqcheck_compare_dqtype()
696 struct xfs_quotainfo *qi = xqc->sc->mp->m_quotainfo; in xqcheck_teardown_scan()
699 xchk_iscan_abort(&xqc->iscan); in xqcheck_teardown_scan()
709 xfs_dqtrx_hook_del(qi, &xqc->qhook); in xqcheck_teardown_scan()
711 if (xqc->shadow_dquot_acct.key_len) { in xqcheck_teardown_scan()
712 rhashtable_free_and_destroy(&xqc->shadow_dquot_acct, in xqcheck_teardown_scan()
714 xqc->shadow_dquot_acct.key_len = 0; in xqcheck_teardown_scan()
717 if (xqc->pcounts) { in xqcheck_teardown_scan()
718 xfarray_destroy(xqc->pcounts); in xqcheck_teardown_scan()
719 xqc->pcounts = NULL; in xqcheck_teardown_scan()
722 if (xqc->gcounts) { in xqcheck_teardown_scan()
723 xfarray_destroy(xqc->gcounts); in xqcheck_teardown_scan()
724 xqc->gcounts = NULL; in xqcheck_teardown_scan()
727 if (xqc->ucounts) { in xqcheck_teardown_scan()
728 xfarray_destroy(xqc->ucounts); in xqcheck_teardown_scan()
729 xqc->ucounts = NULL; in xqcheck_teardown_scan()
732 xchk_iscan_teardown(&xqc->iscan); in xqcheck_teardown_scan()
733 mutex_destroy(&xqc->lock); in xqcheck_teardown_scan()
734 xqc->sc = NULL; in xqcheck_teardown_scan()
748 struct xfs_quotainfo *qi = sc->mp->m_quotainfo; in xqcheck_setup_scan()
752 ASSERT(xqc->sc == NULL); in xqcheck_setup_scan()
753 xqc->sc = sc; in xqcheck_setup_scan()
755 mutex_init(&xqc->lock); in xqcheck_setup_scan()
758 xchk_iscan_start(sc, 30000, 100, &xqc->iscan); in xqcheck_setup_scan()
760 error = -ENOMEM; in xqcheck_setup_scan()
761 if (xfs_this_quota_on(sc->mp, XFS_DQTYPE_USER)) { in xqcheck_setup_scan()
764 sizeof(struct xqcheck_dquot), &xqc->ucounts); in xqcheck_setup_scan()
770 if (xfs_this_quota_on(sc->mp, XFS_DQTYPE_GROUP)) { in xqcheck_setup_scan()
773 sizeof(struct xqcheck_dquot), &xqc->gcounts); in xqcheck_setup_scan()
779 if (xfs_this_quota_on(sc->mp, XFS_DQTYPE_PROJ)) { in xqcheck_setup_scan()
782 sizeof(struct xqcheck_dquot), &xqc->pcounts); in xqcheck_setup_scan()
792 error = rhashtable_init(&xqc->shadow_dquot_acct, in xqcheck_setup_scan()
800 * ILOCK, which means that any in-progress inode updates will finish in xqcheck_setup_scan()
807 ASSERT(sc->flags & XCHK_FSGATES_QUOTA); in xqcheck_setup_scan()
808 xfs_dqtrx_hook_setup(&xqc->qhook, xqcheck_mod_live_ino_dqtrx, in xqcheck_setup_scan()
811 error = xfs_dqtrx_hook_add(qi, &xqc->qhook); in xqcheck_setup_scan()
816 sc->buf_cleanup = xqcheck_teardown_scan; in xqcheck_setup_scan()
829 struct xqcheck *xqc = sc->buf; in xchk_quotacheck()
843 if (xchk_iscan_aborted(&xqc->iscan)) in xchk_quotacheck()
845 if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_INCOMPLETE) in xchk_quotacheck()
849 if (xqc->ucounts) { in xchk_quotacheck()
854 if (xqc->gcounts) { in xchk_quotacheck()
859 if (xqc->pcounts) { in xchk_quotacheck()
866 if (xchk_iscan_aborted(&xqc->iscan)) in xchk_quotacheck()