[PATCH 09/10] xfs: validate feature support when recovering rmap/refcount/bmap intents

Darrick J. Wong
2020-12-04T01:15:19Z

From: Darrick J. Wong <darrick.wong@oracle.com>

The bmap, rmap, and refcount log intent items were added to support the
rmap and reflink features. Because these features come with changes to
the ondisk format, the log items aren't tied to a log incompat flag.

However, the log recovery routines don't actually check for those
feature flags. The kernel has no business replayng an intent item for a
feature that isn't enabled, so check that as part of recovered log item
validation. (Note that kernels pre-dating rmap and reflink will fail
the mount on the unknown log item type code.)

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
fs/xfs/xfs_bmap_item.c | 4 ++++
fs/xfs/xfs_refcount_item.c | 3 +++
fs/xfs/xfs_rmap_item.c | 3 +++
3 files changed, 10 insertions(+)

diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c
index 78346d47564b..4ea9132716c6 100644
--- a/fs/xfs/xfs_bmap_item.c
+++ b/fs/xfs/xfs_bmap_item.c
@@ -425,6 +425,10 @@ xfs_bui_validate(
{
struct xfs_map_extent *bmap;

+ if (!xfs_sb_version_hasrmapbt(&mp->m_sb) &&
+ !xfs_sb_version_hasreflink(&mp->m_sb))
+ return false;
+
/* Only one mapping operation per BUI... */
if (buip->bui_format.bui_nextents != XFS_BUI_MAX_FAST_EXTENTS)
return false;
diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c
index 8ad6c81f6d8f..2b28f5643c0b 100644
--- a/fs/xfs/xfs_refcount_item.c
+++ b/fs/xfs/xfs_refcount_item.c
@@ -423,6 +423,9 @@ xfs_cui_validate_phys(
struct xfs_mount *mp,
struct xfs_phys_extent *refc)
{
+ if (!xfs_sb_version_hasreflink(&mp->m_sb))
+ return false;
+
if (refc->pe_flags & ~XFS_REFCOUNT_EXTENT_FLAGS)
return false;

diff --git a/fs/xfs/xfs_rmap_item.c b/fs/xfs/xfs_rmap_item.c
index f296ec349936..2628bc0080fe 100644
--- a/fs/xfs/xfs_rmap_item.c
+++ b/fs/xfs/xfs_rmap_item.c
@@ -466,6 +466,9 @@ xfs_rui_validate_map(
struct xfs_mount *mp,
struct xfs_map_extent *rmap)
{
+ if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
+ return false;
+
if (rmap->me_flags & ~XFS_RMAP_EXTENT_FLAGS)
return false;