From: Darrick J. Wong Date: Fri, 19 Aug 2016 00:52:26 +0000 (+1000) Subject: xfs_repair: look for mergeable rmaps X-Git-Tag: v4.8.0-rc1~22 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6584173423c7a12f018b564887049c550f801885;p=thirdparty%2Fxfsprogs-dev.git xfs_repair: look for mergeable rmaps Check for adjacent mergeable rmaps; this is a sign that we've screwed up somehow. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- diff --git a/repair/scan.c b/repair/scan.c index 1f2062223..807a23694 100644 --- a/repair/scan.c +++ b/repair/scan.c @@ -873,6 +873,7 @@ _("unknown block (%d,%d-%d) mismatch on %s tree, state - %d,%" PRIx64 "\n"), struct rmap_priv { struct aghdr_cnts *agcnts; struct xfs_rmap_irec high_key; + struct xfs_rmap_irec last_rec; xfs_agblock_t nr_blocks; }; @@ -1026,6 +1027,16 @@ advance: goto advance; } + /* Is this mergeable with the previous record? */ + if (mergeable_rmaps(&rmap_priv->last_rec, &key)) { + do_warn( + _("record %d in block (%u/%u) of %s tree should be merged with previous record\n"), + i, agno, bno, name); + rmap_priv->last_rec.rm_blockcount += + key.rm_blockcount; + } else + rmap_priv->last_rec = key; + /* Check that we don't go past the high key. */ key.rm_startblock += key.rm_blockcount - 1; if (!XFS_RMAP_NON_INODE_OWNER(key.rm_owner) && @@ -1909,6 +1920,7 @@ validate_agf( memset(&priv.high_key, 0xFF, sizeof(priv.high_key)); priv.high_key.rm_blockcount = 0; priv.agcnts = agcnts; + priv.last_rec.rm_owner = XFS_RMAP_OWN_UNKNOWN; priv.nr_blocks = 0; bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_RMAP]); if (bno != 0 && verify_agbno(mp, agno, bno)) {