/* Set us up to repair the rtsummary file. */ int
xrep_setup_rtsummary( struct xfs_scrub *sc, struct xchk_rtsummary *rts)
{ struct xfs_mount *mp = sc->mp; unsignedlonglong blocks; int error;
error = xrep_tempfile_create(sc, S_IFREG); if (error) return error;
/* * If we're doing a repair, we reserve enough blocks to write out a * completely new summary file, plus twice as many blocks as we would * need if we can only allocate one block per data fork mapping. This * should cover the preallocation of the temporary file and exchanging * the extent mappings. * * We cannot use xfs_exchmaps_estimate because we have not yet * constructed the replacement rtsummary and therefore do not know how * many extents it will use. By the time we do, we will have a dirty * transaction (which we cannot drop because we cannot drop the * rtsummary ILOCK) and cannot ask for more reservation.
*/
blocks = mp->m_rsumblocks;
blocks += xfs_bmbt_calc_size(mp, blocks) * 2; if (blocks > UINT_MAX) return -EOPNOTSUPP;
/* Repair the realtime summary. */ int
xrep_rtsummary( struct xfs_scrub *sc)
{ struct xchk_rtsummary *rts = sc->buf; struct xfs_mount *mp = sc->mp; int error;
/* We require the rmapbt to rebuild anything. */ if (!xfs_has_rmapbt(mp)) return -EOPNOTSUPP; /* We require atomic file exchange range to rebuild anything. */ if (!xfs_has_exchange_range(mp)) return -EOPNOTSUPP;
/* Walk away if we disagree on the size of the rt bitmap. */ if (rts->rbmblocks != mp->m_sb.sb_rbmblocks) return 0;
/* Make sure any problems with the fork are fixed. */
error = xrep_metadata_inode_forks(sc); if (error) return error;
/* * Try to take ILOCK_EXCL of the temporary file. We had better be the * only ones holding onto this inode, but we can't block while holding * the rtsummary file's ILOCK_EXCL.
*/ while (!xrep_tempfile_ilock_nowait(sc)) { if (xchk_should_terminate(sc, &error)) return error;
delay(1);
}
/* Make sure we have space allocated for the entire summary file. */
xfs_trans_ijoin(sc->tp, sc->ip, 0);
xfs_trans_ijoin(sc->tp, sc->tempip, 0);
error = xrep_tempfile_prealloc(sc, 0, rts->rsumblocks); if (error) return error;
/* Last chance to abort before we start committing fixes. */ if (xchk_should_terminate(sc, &error)) return error;
/* Copy the rtsummary file that we generated. */
error = xrep_tempfile_copyin(sc, 0, rts->rsumblocks,
xrep_rtsummary_prep_buf, rts); if (error) return error;
error = xrep_tempfile_set_isize(sc, XFS_FSB_TO_B(mp, rts->rsumblocks)); if (error) return error;
/* * Now exchange the contents. Nothing in repair uses the temporary * buffer, so we can reuse it for the tempfile exchrange information.
*/
error = xrep_tempexch_trans_reserve(sc, XFS_DATA_FORK, 0,
rts->rsumblocks, &rts->tempexch); if (error) return error;
error = xrep_tempexch_contents(sc, &rts->tempexch); if (error) return error;
/* Reset incore state and blow out the summary cache. */ if (sc->sr.rtg->rtg_rsum_cache)
memset(sc->sr.rtg->rtg_rsum_cache, 0xFF, mp->m_sb.sb_rbmblocks);
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.