diff mbox series

[01/11] xfs: allow newer INCOMPAT/RO_COMPAT feature bits to protect ATTRI log items

Message ID 170405005610.1804370.15326025974579452778.stgit@frogsfrogsfrogs (mailing list archive)
State New
Headers show
Series [01/11] xfs: allow newer INCOMPAT/RO_COMPAT feature bits to protect ATTRI log items | expand

Commit Message

Darrick J. Wong Dec. 31, 2023, 11:02 p.m. UTC
From: Darrick J. Wong <djwong@kernel.org>

Log recovery (which can include replaying ATTRI intent items) occurs on
rw and ro mounts.  Dirty logs containing these log items must be
protected from being replayed by older kernels.  The log incompat
feature XFS_SB_FEAT_INCOMPAT_LOG_XATTRS provides this protection.

However, adding this flag to the filesystem introduces performance
problems of its own -- each time we do, we must force the log and write
the primary superblock before writing any ATTRI log items.  This was ok
when the only users were developers using the debug knob, but this sucks
for regular users.  We'd like to avoid that.

If a filesystem has ro-compat or incompat feature bits set that weren't
defined at the time that ATTRI log items were defined, then any kernel
that doesn't know about ATTRI items will reject that filesystem.  This
provides the same protection as the log-incompat feature, but at a much
lower cost because most ro-compat and incompat features are set on a
permanent basis.

Avoid the performance hit by detecting these feature bits and skipping
the xfs_add_incompat_log_feature calls.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 libxfs/xfs_attr.c   |    6 +++++-
 libxfs/xfs_attr.h   |   23 +++++++++++++++++++++++
 libxfs/xfs_format.h |    6 +++++-
 3 files changed, 33 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/libxfs/xfs_attr.c b/libxfs/xfs_attr.c
index 8f527ac9292..8958434247f 100644
--- a/libxfs/xfs_attr.c
+++ b/libxfs/xfs_attr.c
@@ -883,9 +883,13 @@  xfs_attr_defer_add(
 	struct xfs_da_args	*args,
 	unsigned int		op_flags)
 {
-
 	struct xfs_attr_intent	*new;
 
+	/* ATTRI log items must be protected from older kernels */
+	if (args->op_flags & XFS_DA_OP_LOGGED)
+		ASSERT(xfs_attri_can_use_without_log_assistance(args->dp->i_mount) ||
+		       xfs_sb_version_haslogxattrs(&args->dp->i_mount->m_sb));
+
 	new = kmem_cache_zalloc(xfs_attr_intent_cache, GFP_NOFS | __GFP_NOFAIL);
 	new->xattri_op_flags = op_flags;
 	new->xattri_da_args = args;
diff --git a/libxfs/xfs_attr.h b/libxfs/xfs_attr.h
index e4f55008552..273e8dff76c 100644
--- a/libxfs/xfs_attr.h
+++ b/libxfs/xfs_attr.h
@@ -620,4 +620,27 @@  void xfs_attr_intent_destroy_cache(void);
 
 int xfs_attr_sf_totsize(struct xfs_inode *dp);
 
+/*
+ * Decide if this filesystem has a new enough permanent feature set to protect
+ * attri log items from being replayed on a kernel that does not have
+ * XFS_SB_FEAT_INCOMPAT_LOG_XATTRS set.
+ */
+static inline bool
+xfs_attri_can_use_without_log_assistance(
+	struct xfs_mount	*mp)
+{
+	if (!xfs_sb_is_v5(&mp->m_sb))
+		return false;
+
+	if (xfs_sb_has_incompat_feature(&mp->m_sb,
+				~(XFS_SB_FEAT_INCOMPAT_FTYPE |
+				  XFS_SB_FEAT_INCOMPAT_SPINODES |
+				  XFS_SB_FEAT_INCOMPAT_META_UUID |
+				  XFS_SB_FEAT_INCOMPAT_BIGTIME |
+				  XFS_SB_FEAT_INCOMPAT_NREXT64)))
+		return true;
+
+	return false;
+}
+
 #endif	/* __XFS_ATTR_H__ */
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index ec25010b577..8b952909ce1 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -390,7 +390,11 @@  xfs_sb_has_incompat_feature(
 	return (sbp->sb_features_incompat & feature) != 0;
 }
 
-#define XFS_SB_FEAT_INCOMPAT_LOG_XATTRS   (1 << 0)	/* Delayed Attributes */
+/*
+ * Log contains ATTRI log intent items which are not otherwise protected by
+ * an INCOMPAT/RO_COMPAT feature flag.
+ */
+#define XFS_SB_FEAT_INCOMPAT_LOG_XATTRS   (1 << 0)
 
 /*
  * Log contains SXI log intent items which are not otherwise protected by