aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2018-12-12 11:46:26 -0500
committerDarrick J. Wong <darrick.wong@oracle.com>2018-12-12 11:47:17 -0500
commit2c2d9d3a205afa93bf6105e4ab6f1ff536291dc6 (patch)
tree16bc390a260310b768bd664be1c296c3ff434a8d
parentc1b4a321ede083521b91c314e1c4fa233ac33740 (diff)
xfs: count inode blocks correctly in inobt scrub
A big block filesystem might require more than one inobt record to cover all the inodes in the block. In these cases it is not correct to round the irec count up to the nearest block because this causes us to overestimate the number of inode blocks we expect to find. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Dave Chinner <dchinner@redhat.com>
-rw-r--r--fs/xfs/scrub/ialloc.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/fs/xfs/scrub/ialloc.c b/fs/xfs/scrub/ialloc.c
index 9b5287a0e8ba..882dc56c5c21 100644
--- a/fs/xfs/scrub/ialloc.c
+++ b/fs/xfs/scrub/ialloc.c
@@ -44,6 +44,11 @@ xchk_setup_ag_iallocbt(
44 44
45/* Inode btree scrubber. */ 45/* Inode btree scrubber. */
46 46
47struct xchk_iallocbt {
48 /* Number of inodes we see while scanning inobt. */
49 unsigned long long inodes;
50};
51
47/* 52/*
48 * If we're checking the finobt, cross-reference with the inobt. 53 * If we're checking the finobt, cross-reference with the inobt.
49 * Otherwise we're checking the inobt; if there is an finobt, make sure 54 * Otherwise we're checking the inobt; if there is an finobt, make sure
@@ -266,7 +271,7 @@ xchk_iallocbt_rec(
266 union xfs_btree_rec *rec) 271 union xfs_btree_rec *rec)
267{ 272{
268 struct xfs_mount *mp = bs->cur->bc_mp; 273 struct xfs_mount *mp = bs->cur->bc_mp;
269 xfs_filblks_t *inode_blocks = bs->private; 274 struct xchk_iallocbt *iabt = bs->private;
270 struct xfs_inobt_rec_incore irec; 275 struct xfs_inobt_rec_incore irec;
271 uint64_t holes; 276 uint64_t holes;
272 xfs_agnumber_t agno = bs->cur->bc_private.a.agno; 277 xfs_agnumber_t agno = bs->cur->bc_private.a.agno;
@@ -304,8 +309,7 @@ xchk_iallocbt_rec(
304 (agbno & (mp->m_blocks_per_cluster - 1))) 309 (agbno & (mp->m_blocks_per_cluster - 1)))
305 xchk_btree_set_corrupt(bs->sc, bs->cur, 0); 310 xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
306 311
307 *inode_blocks += XFS_B_TO_FSB(mp, 312 iabt->inodes += irec.ir_count;
308 irec.ir_count * mp->m_sb.sb_inodesize);
309 313
310 /* Handle non-sparse inodes */ 314 /* Handle non-sparse inodes */
311 if (!xfs_inobt_issparse(irec.ir_holemask)) { 315 if (!xfs_inobt_issparse(irec.ir_holemask)) {
@@ -397,9 +401,10 @@ STATIC void
397xchk_iallocbt_xref_rmap_inodes( 401xchk_iallocbt_xref_rmap_inodes(
398 struct xfs_scrub *sc, 402 struct xfs_scrub *sc,
399 int which, 403 int which,
400 xfs_filblks_t inode_blocks) 404 unsigned long long inodes)
401{ 405{
402 xfs_filblks_t blocks; 406 xfs_filblks_t blocks;
407 xfs_filblks_t inode_blocks;
403 int error; 408 int error;
404 409
405 if (!sc->sa.rmap_cur || xchk_skip_xref(sc->sm)) 410 if (!sc->sa.rmap_cur || xchk_skip_xref(sc->sm))
@@ -410,6 +415,7 @@ xchk_iallocbt_xref_rmap_inodes(
410 &XFS_RMAP_OINFO_INODES, &blocks); 415 &XFS_RMAP_OINFO_INODES, &blocks);
411 if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur)) 416 if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur))
412 return; 417 return;
418 inode_blocks = XFS_B_TO_FSB(sc->mp, inodes * sc->mp->m_sb.sb_inodesize);
413 if (blocks != inode_blocks) 419 if (blocks != inode_blocks)
414 xchk_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0); 420 xchk_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0);
415} 421}
@@ -421,12 +427,14 @@ xchk_iallocbt(
421 xfs_btnum_t which) 427 xfs_btnum_t which)
422{ 428{
423 struct xfs_btree_cur *cur; 429 struct xfs_btree_cur *cur;
424 xfs_filblks_t inode_blocks = 0; 430 struct xchk_iallocbt iabt = {
431 .inodes = 0,
432 };
425 int error; 433 int error;
426 434
427 cur = which == XFS_BTNUM_INO ? sc->sa.ino_cur : sc->sa.fino_cur; 435 cur = which == XFS_BTNUM_INO ? sc->sa.ino_cur : sc->sa.fino_cur;
428 error = xchk_btree(sc, cur, xchk_iallocbt_rec, &XFS_RMAP_OINFO_INOBT, 436 error = xchk_btree(sc, cur, xchk_iallocbt_rec, &XFS_RMAP_OINFO_INOBT,
429 &inode_blocks); 437 &iabt);
430 if (error) 438 if (error)
431 return error; 439 return error;
432 440
@@ -440,7 +448,7 @@ xchk_iallocbt(
440 * to inode chunks with free inodes. 448 * to inode chunks with free inodes.
441 */ 449 */
442 if (which == XFS_BTNUM_INO) 450 if (which == XFS_BTNUM_INO)
443 xchk_iallocbt_xref_rmap_inodes(sc, which, inode_blocks); 451 xchk_iallocbt_xref_rmap_inodes(sc, which, iabt.inodes);
444 452
445 return error; 453 return error;
446} 454}