@@ -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;
@@ -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__ */
@@ -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