]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_repair: look for mergeable rmaps
authorDarrick J. Wong <darrick.wong@oracle.com>
Fri, 19 Aug 2016 00:52:26 +0000 (10:52 +1000)
committerDave Chinner <david@fromorbit.com>
Fri, 19 Aug 2016 00:52:26 +0000 (10:52 +1000)
Check for adjacent mergeable rmaps; this is a sign that we've
screwed up somehow.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
repair/scan.c

index 1f20622230579ebb4d81ec187f15c9bfbea0e2cf..807a236945965ece4a37879832483d47acb939c4 100644 (file)
@@ -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)) {