@@ -885,9 +885,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
@@ -469,7 +469,8 @@ xfs_attri_validate(
unsigned int op = attrp->alfi_op_flags &
XFS_ATTRI_OP_FLAGS_TYPE_MASK;
- if (!xfs_sb_version_haslogxattrs(&mp->m_sb))
+ if (!xfs_sb_version_haslogxattrs(&mp->m_sb) &&
+ !xfs_attri_can_use_without_log_assistance(mp))
return false;
if (attrp->__pad != 0)
@@ -33,6 +33,13 @@ xfs_attr_grab_log_assist(
{
int error = 0;
+ /*
+ * As a performance optimization, skip the log force and super write
+ * if the filesystem featureset already protects the attri log items.
+ */
+ if (xfs_attri_can_use_without_log_assistance(mp))
+ return 0;
+
/*
* Protect ourselves from an idle log clearing the logged xattrs log
* incompat feature bit.
@@ -76,7 +83,8 @@ static inline void
xfs_attr_rele_log_assist(
struct xfs_mount *mp)
{
- xlog_drop_incompat_feat(mp->m_log, XLOG_INCOMPAT_FEAT_XATTRS);
+ if (!xfs_attri_can_use_without_log_assistance(mp))
+ xlog_drop_incompat_feat(mp->m_log, XLOG_INCOMPAT_FEAT_XATTRS);
}
static inline bool