aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2023-03-24 13:34:29 -0700
committerDarrick J. Wong <djwong@kernel.org>2023-04-06 12:20:11 -0700
commitfee9424c142b24fc3bc25e7ba5023aad692b9e2c (patch)
treee09e9b472b75749e31ed4e03bf5f7578115240f0
parent38c1ed8b8ebc7da7ce65683723fc380fe3e6581d (diff)
downloadxfs-linux-pptrs-online-parent-repair.tar.gz
xfs: compare generated and existing parent pointerspptrs-online-parent-repair_2023-04-06pptrs-online-parent-repair
Check our work to make sure we found all the parent pointers that the original file had. Signed-off-by: Darrick J. Wong <djwong@kernel.org>
-rw-r--r--fs/xfs/scrub/parent_repair.c29
-rw-r--r--fs/xfs/scrub/trace.h1
2 files changed, 28 insertions, 2 deletions
diff --git a/fs/xfs/scrub/parent_repair.c b/fs/xfs/scrub/parent_repair.c
index 293d9e9310183c..1f83e0f85dc099 100644
--- a/fs/xfs/scrub/parent_repair.c
+++ b/fs/xfs/scrub/parent_repair.c
@@ -486,7 +486,10 @@ xrep_pptr_scan_dirtree(
return 0;
}
-/* Dump a parent pointer from the temporary file. */
+/*
+ * Dump a parent pointer from the temporary file and check it against the file
+ * we're rebuilding. We are not committing any of this.
+ */
STATIC int
xrep_pptr_dump_tempptr(
struct xfs_scrub *sc,
@@ -500,6 +503,8 @@ xrep_pptr_dump_tempptr(
{
struct xrep_pptrs *rp = priv;
const struct xfs_parent_name_rec *rec = (const void *)name;
+ struct xfs_inode *other_ip;
+ int error;
if (!(attr_flags & XFS_ATTR_PARENT))
return 0;
@@ -508,10 +513,26 @@ xrep_pptr_dump_tempptr(
!xfs_parent_valuecheck(sc->mp, value, valuelen))
return -EFSCORRUPTED;
+ if (ip == sc->ip)
+ other_ip = sc->tempip;
+ else if (ip == sc->tempip)
+ other_ip = sc->ip;
+ else
+ return -EFSCORRUPTED;
+
xfs_parent_irec_from_disk(&rp->pptr, rec, value, valuelen);
trace_xrep_pptr_dumpname(sc->tempip, &rp->pptr);
- return 0;
+
+ error = xfs_parent_lookup(sc->tp, other_ip, &rp->pptr,
+ &rp->pptr_scratch);
+ if (error == -ENOATTR) {
+ trace_xrep_pptr_checkname(other_ip, &rp->pptr);
+ ASSERT(error != -ENOATTR);
+ return -EFSCORRUPTED;
+ }
+
+ return error;
}
/*
@@ -590,6 +611,10 @@ xrep_pptr_rebuild_tree(
if (error)
return error;
+ error = xchk_xattr_walk(sc, sc->ip, xrep_pptr_dump_tempptr, rp);
+ if (error)
+ return error;
+
return xchk_xattr_walk(sc, sc->tempip, xrep_pptr_dump_tempptr, rp);
}
diff --git a/fs/xfs/scrub/trace.h b/fs/xfs/scrub/trace.h
index 5b070c177d484e..87e400096245eb 100644
--- a/fs/xfs/scrub/trace.h
+++ b/fs/xfs/scrub/trace.h
@@ -1374,6 +1374,7 @@ DEFINE_EVENT(xrep_pptr_class, name, \
DEFINE_XREP_PPTR_CLASS(xrep_pptr_createname);
DEFINE_XREP_PPTR_CLASS(xrep_pptr_removename);
DEFINE_XREP_PPTR_CLASS(xrep_pptr_dumpname);
+DEFINE_XREP_PPTR_CLASS(xrep_pptr_checkname);
DECLARE_EVENT_CLASS(xrep_pptr_scan_class,
TP_PROTO(struct xfs_inode *ip, const struct xfs_inode *dp,