/* * Live Quotacheck Repair * ====================== * * Use the live quota counter information that we collected to replace the * counter values in the incore dquots. A scrub->repair cycle should have left * the live data and hooks active, so this is safe so long as we make sure the * dquot is locked.
*/
/* Commit new counters to a dquot. */ staticint
xqcheck_commit_dquot( struct xqcheck *xqc,
xfs_dqtype_t dqtype, struct xfs_dquot *dq)
{ struct xqcheck_dquot xcdq; struct xfarray *counts = xqcheck_counters_for(xqc, dqtype);
int64_t delta; bool dirty = false; int error = 0;
/* Unlock the dquot just long enough to allocate a transaction. */
xfs_dqunlock(dq);
error = xchk_trans_alloc(xqc->sc, 0);
xfs_dqlock(dq); if (error) return error;
xfs_trans_dqjoin(xqc->sc->tp, dq);
if (xchk_iscan_aborted(&xqc->iscan)) {
error = -ECANCELED; goto out_cancel;
}
mutex_lock(&xqc->lock);
error = xfarray_load_sparse(counts, dq->q_id, &xcdq); if (error) goto out_unlock;
xcdq.flags |= (XQCHECK_DQUOT_REPAIR_SCANNED | XQCHECK_DQUOT_WRITTEN);
error = xfarray_store(counts, dq->q_id, &xcdq); if (error == -EFBIG) { /* * EFBIG means we tried to store data at too high a byte offset * in the sparse array. IOWs, we cannot complete the repair * and must cancel the whole operation. This should never * happen, but we need to catch it anyway.
*/
error = -ECANCELED;
}
mutex_unlock(&xqc->lock); if (error || !dirty) goto out_cancel;
/* Commit the dirty dquot to disk. */
dq->q_flags |= XFS_DQFLAG_DIRTY; if (dq->q_id)
xfs_qm_adjust_dqtimers(dq);
xfs_trans_log_dquot(xqc->sc->tp, dq);
/* * Transaction commit unlocks the dquot, so we must re-lock it so that * the caller can put the reference (which apparently requires a locked * dquot).
*/
error = xrep_trans_commit(xqc->sc);
xfs_dqlock(dq); return error;
/* * Update the counters of every dquot that the quota file knows about.
*/
xchk_dqiter_init(&cursor, sc, dqtype); while ((error = xchk_dquot_iter(&cursor, &dq)) == 1) {
error = xqcheck_commit_dquot(xqc, dqtype, dq);
xfs_qm_dqput(dq); if (error) break;
} if (error) return error;
/* * Make a second pass to deal with the dquots that we know about but * the quota file previously did not know about.
*/
mutex_lock(&xqc->lock); while ((error = xfarray_iter(counts, &cur, &xcdq)) == 1) {
xfs_dqid_t id = cur - 1;
if (xcdq.flags & XQCHECK_DQUOT_REPAIR_SCANNED) continue;
mutex_unlock(&xqc->lock);
/* * Grab the dquot, allowing for dquot block allocation in a * separate transaction. We committed the scrub transaction * in a previous step, so we will not be creating nested * transactions here.
*/
error = xfs_qm_dqget(mp, id, dqtype, true, &dq); if (error) return error;
error = xqcheck_commit_dquot(xqc, dqtype, dq);
xfs_qm_dqput(dq); if (error) return error;
/* Figure out quota CHKD flags for the running quota types. */ staticinlineunsignedint
xqcheck_chkd_flags( struct xfs_mount *mp)
{ unsignedint ret = 0;
if (XFS_IS_UQUOTA_ON(mp))
ret |= XFS_UQUOTA_CHKD; if (XFS_IS_GQUOTA_ON(mp))
ret |= XFS_GQUOTA_CHKD; if (XFS_IS_PQUOTA_ON(mp))
ret |= XFS_PQUOTA_CHKD; return ret;
}
/* Commit the new dquot counters. */ int
xrep_quotacheck( struct xfs_scrub *sc)
{ struct xqcheck *xqc = sc->buf; unsignedint qflags = xqcheck_chkd_flags(sc->mp); int error;
/* * Clear the CHKD flag for the running quota types and commit the scrub * transaction so that we can allocate new quota block mappings if we * have to. If we crash after this point, the sb still has the CHKD * flags cleared, so mount quotacheck will fix all of this up.
*/
xrep_update_qflags(sc, qflags, 0);
error = xrep_trans_commit(sc); if (error) return error;
/* Commit the new counters to the dquots. */ if (xqc->ucounts) {
error = xqcheck_commit_dqtype(xqc, XFS_DQTYPE_USER); if (error) return error;
} if (xqc->gcounts) {
error = xqcheck_commit_dqtype(xqc, XFS_DQTYPE_GROUP); if (error) return error;
} if (xqc->pcounts) {
error = xqcheck_commit_dqtype(xqc, XFS_DQTYPE_PROJ); if (error) return error;
}
/* Set the CHKD flags now that we've fixed quota counts. */
error = xchk_trans_alloc(sc, 0); if (error) return error;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.