]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_repair: use range query when while checking rmaps
authorDarrick J. Wong <darrick.wong@oracle.com>
Tue, 25 Oct 2016 22:14:35 +0000 (15:14 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Wed, 26 Oct 2016 23:41:08 +0000 (16:41 -0700)
For shared extents, we ought to use a range query on the rmapbt to
find the corresponding rmap.  However, most of the time the observed
rmap will be an exact match for the rmapbt rmap, in which case we
could have used the (much faster) regular lookup.  Therefore, try the
regular lookup first and resort to the range lookup if that doesn't
get us what we want.  This can cut the run time of the rmap check of
xfs_repair in half.

Theoretically, the only reason why an observed rmap wouldn't be an
exact match for an rmapbt rmap is because we modified some file on
account of a metadata error.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
libxfs/libxfs_api_defs.h
repair/rmap.c

index 8c15b750860291c8d919d909e3c7e231822c94b7..e95763d56648cb89cda76d872e5c0b6191c44066 100644 (file)
 #define xfs_refcountbt_init_cursor     libxfs_refcountbt_init_cursor
 #define xfs_refcount_lookup_le         libxfs_refcount_lookup_le
 #define xfs_refcount_get_rec           libxfs_refcount_get_rec
+#define xfs_rmap_lookup_le_range       libxfs_rmap_lookup_le_range
 
 #endif /* __LIBXFS_API_DEFS_H__ */
index dd0be53c3651d04dbc636b839d90db2d5fefa680..45e183ac4864c7296f9435c2870079eae98316a4 100644 (file)
@@ -917,6 +917,20 @@ rmap_lookup(
        return -libxfs_rmap_get_rec(bt_cur, tmp, have);
 }
 
+/* Look for an rmap in the rmapbt that matches a given rmap. */
+static int
+rmap_lookup_overlapped(
+       struct xfs_btree_cur    *bt_cur,
+       struct xfs_rmap_irec    *rm_rec,
+       struct xfs_rmap_irec    *tmp,
+       int                     *have)
+{
+       /* Have to use our fancy version for overlapped */
+       return -libxfs_rmap_lookup_le_range(bt_cur, rm_rec->rm_startblock,
+                               rm_rec->rm_owner, rm_rec->rm_offset,
+                               rm_rec->rm_flags, tmp, have);
+}
+
 /* Does the btree rmap cover the observed rmap? */
 #define NEXTP(x)       ((x)->rm_startblock + (x)->rm_blockcount)
 #define NEXTL(x)       ((x)->rm_offset + (x)->rm_blockcount)
@@ -1005,6 +1019,18 @@ rmaps_verify_btree(
                error = rmap_lookup(bt_cur, rm_rec, &tmp, &have);
                if (error)
                        goto err;
+               /*
+                * Using the range query is expensive, so only do it if
+                * the regular lookup doesn't find anything or if it doesn't
+                * match the observed rmap.
+                */
+               if (xfs_sb_version_hasreflink(&bt_cur->bc_mp->m_sb) &&
+                               (!have || !rmap_is_good(rm_rec, &tmp))) {
+                       error = rmap_lookup_overlapped(bt_cur, rm_rec,
+                                       &tmp, &have);
+                       if (error)
+                               goto err;
+               }
                if (!have) {
                        do_warn(
 _("Missing reverse-mapping record for (%u/%u) %slen %u owner %"PRId64" \