summaryrefslogtreecommitdiffstats
path: root/fs/xfs/scrub/refcount.c
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2023-04-11 19:00:12 -0700
committerDarrick J. Wong <djwong@kernel.org>2023-04-11 19:00:12 -0700
commit7ac14fa2bd22e99a06ae16382b394f697cfe2b8a (patch)
tree3e6c512aed6eee6657110fb2943600036cffb4b1 /fs/xfs/scrub/refcount.c
parent7ad9ea6398feae3ae4ce79fe08457f93b79a9a43 (diff)
downloadlinux-stable-7ac14fa2bd22e99a06ae16382b394f697cfe2b8a.tar.gz
linux-stable-7ac14fa2bd22e99a06ae16382b394f697cfe2b8a.tar.bz2
linux-stable-7ac14fa2bd22e99a06ae16382b394f697cfe2b8a.zip
xfs: ensure that all metadata and data blocks are not cow staging extents
Make sure that all filesystem metadata blocks and file data blocks are not also marked as CoW staging extents. The extra checking added here was inspired by an actual VM host filesystem corruption incident due to bugs in the CoW handling of 4.x kernels. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Dave Chinner <dchinner@redhat.com>
Diffstat (limited to 'fs/xfs/scrub/refcount.c')
-rw-r--r--fs/xfs/scrub/refcount.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/fs/xfs/scrub/refcount.c b/fs/xfs/scrub/refcount.c
index 771a591a4aeb..db9e46a4f8d4 100644
--- a/fs/xfs/scrub/refcount.c
+++ b/fs/xfs/scrub/refcount.c
@@ -555,3 +555,24 @@ xchk_xref_is_not_shared(
if (outcome != XBTREE_RECPACKING_EMPTY)
xchk_btree_xref_set_corrupt(sc, sc->sa.refc_cur, 0);
}
+
+/* xref check that the extent is not being used for CoW staging. */
+void
+xchk_xref_is_not_cow_staging(
+ struct xfs_scrub *sc,
+ xfs_agblock_t agbno,
+ xfs_extlen_t len)
+{
+ enum xbtree_recpacking outcome;
+ int error;
+
+ if (!sc->sa.refc_cur || xchk_skip_xref(sc->sm))
+ return;
+
+ error = xfs_refcount_has_records(sc->sa.refc_cur, XFS_REFC_DOMAIN_COW,
+ agbno, len, &outcome);
+ if (!xchk_should_check_xref(sc, &error, &sc->sa.refc_cur))
+ return;
+ if (outcome != XBTREE_RECPACKING_EMPTY)
+ xchk_btree_xref_set_corrupt(sc, sc->sa.refc_cur, 0);
+}