From c6ad4bc15019235a6cbe1a51d6d6e454dd4a8d89 Mon Sep 17 00:00:00 2001 From: Allison Henderson Date: Wed, 22 Jun 2022 14:28:52 -0500 Subject: [PATCH] xfs: Implement attr logging and replay Source kernel commit: 1d08e11d04d293cb7006d1c8641be1fdd8a8e397 This patch adds the needed routines to create, log and recover logged extended attribute intents. Signed-off-by: Allison Henderson Reviewed-by: Chandan Babu R Reviewed-by: Darrick J. Wong Signed-off-by: Dave Chinner Signed-off-by: Eric Sandeen --- libxfs/defer_item.c | 95 +++++++++++++++++++++++++++++++++++++++++++++ libxfs/xfs_defer.c | 1 + libxfs/xfs_defer.h | 1 + libxfs/xfs_format.h | 9 ++++- 4 files changed, 105 insertions(+), 1 deletion(-) diff --git a/libxfs/defer_item.c b/libxfs/defer_item.c index bd6ace1c4..fc56d3bf6 100644 --- a/libxfs/defer_item.c +++ b/libxfs/defer_item.c @@ -8,6 +8,7 @@ #include "xfs_shared.h" #include "xfs_format.h" #include "xfs_log_format.h" +#include "xfs_da_format.h" #include "xfs_trans_resv.h" #include "xfs_bit.h" #include "xfs_sb.h" @@ -20,6 +21,8 @@ #include "xfs_refcount.h" #include "xfs_bmap.h" #include "xfs_inode.h" +#include "xfs_da_btree.h" +#include "xfs_attr.h" /* Dummy defer item ops, since we don't do logging. */ @@ -453,3 +456,95 @@ const struct xfs_defer_op_type xfs_bmap_update_defer_type = { .finish_item = xfs_bmap_update_finish_item, .cancel_item = xfs_bmap_update_cancel_item, }; + +/* Get an ATTRI. */ +static struct xfs_log_item * +xfs_attr_create_intent( + struct xfs_trans *tp, + struct list_head *items, + unsigned int count, + bool sort) +{ + return NULL; +} + +/* Abort all pending ATTRs. */ +static void +xfs_attr_abort_intent( + struct xfs_log_item *intent) +{ +} + +/* Get an ATTRD so we can process all the attrs. */ +static struct xfs_log_item * +xfs_attr_create_done( + struct xfs_trans *tp, + struct xfs_log_item *intent, + unsigned int count) +{ + return NULL; +} + +/* Process an attr. */ +static int +xfs_attr_finish_item( + struct xfs_trans *tp, + struct xfs_log_item *done, + struct list_head *item, + struct xfs_btree_cur **state) +{ + struct xfs_attr_item *attr; + int error; + struct xfs_delattr_context *dac; + struct xfs_da_args *args; + unsigned int op; + + attr = container_of(item, struct xfs_attr_item, xattri_list); + dac = &attr->xattri_dac; + args = dac->da_args; + op = attr->xattri_op_flags & XFS_ATTR_OP_FLAGS_TYPE_MASK; + + /* + * Always reset trans after EAGAIN cycle + * since the transaction is new + */ + args->trans = tp; + + switch (op) { + case XFS_ATTR_OP_FLAGS_SET: + error = xfs_attr_set_iter(dac, &dac->leaf_bp); + break; + case XFS_ATTR_OP_FLAGS_REMOVE: + ASSERT(XFS_IFORK_Q(args->dp)); + error = xfs_attr_remove_iter(dac); + break; + default: + error = -EFSCORRUPTED; + break; + } + + if (error != -EAGAIN) + kmem_free(attr); + + return error; +} + +/* Cancel an attr */ +static void +xfs_attr_cancel_item( + struct list_head *item) +{ + struct xfs_attr_item *attr; + + attr = container_of(item, struct xfs_attr_item, xattri_list); + kmem_free(attr); +} + +const struct xfs_defer_op_type xfs_attr_defer_type = { + .max_items = 1, + .create_intent = xfs_attr_create_intent, + .abort_intent = xfs_attr_abort_intent, + .create_done = xfs_attr_create_done, + .finish_item = xfs_attr_finish_item, + .cancel_item = xfs_attr_cancel_item, +}; diff --git a/libxfs/xfs_defer.c b/libxfs/xfs_defer.c index 4923b4225..f25de52be 100644 --- a/libxfs/xfs_defer.c +++ b/libxfs/xfs_defer.c @@ -181,6 +181,7 @@ static const struct xfs_defer_op_type *defer_op_types[] = { [XFS_DEFER_OPS_TYPE_RMAP] = &xfs_rmap_update_defer_type, [XFS_DEFER_OPS_TYPE_FREE] = &xfs_extent_free_defer_type, [XFS_DEFER_OPS_TYPE_AGFL_FREE] = &xfs_agfl_free_defer_type, + [XFS_DEFER_OPS_TYPE_ATTR] = &xfs_attr_defer_type, }; static bool diff --git a/libxfs/xfs_defer.h b/libxfs/xfs_defer.h index fcd23e5cf..114a3a493 100644 --- a/libxfs/xfs_defer.h +++ b/libxfs/xfs_defer.h @@ -19,6 +19,7 @@ enum xfs_defer_ops_type { XFS_DEFER_OPS_TYPE_RMAP, XFS_DEFER_OPS_TYPE_FREE, XFS_DEFER_OPS_TYPE_AGFL_FREE, + XFS_DEFER_OPS_TYPE_ATTR, XFS_DEFER_OPS_TYPE_MAX, }; diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h index 96fd49fbc..afdfc8108 100644 --- a/libxfs/xfs_format.h +++ b/libxfs/xfs_format.h @@ -390,7 +390,9 @@ xfs_sb_has_incompat_feature( return (sbp->sb_features_incompat & feature) != 0; } -#define XFS_SB_FEAT_INCOMPAT_LOG_ALL 0 +#define XFS_SB_FEAT_INCOMPAT_LOG_XATTRS (1 << 0) /* Delayed Attributes */ +#define XFS_SB_FEAT_INCOMPAT_LOG_ALL \ + (XFS_SB_FEAT_INCOMPAT_LOG_XATTRS) #define XFS_SB_FEAT_INCOMPAT_LOG_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_LOG_ALL static inline bool xfs_sb_has_incompat_log_feature( @@ -415,6 +417,11 @@ xfs_sb_add_incompat_log_features( sbp->sb_features_log_incompat |= features; } +static inline bool xfs_sb_version_haslogxattrs(struct xfs_sb *sbp) +{ + return xfs_sb_is_v5(sbp) && (sbp->sb_features_log_incompat & + XFS_SB_FEAT_INCOMPAT_LOG_XATTRS); +} static inline bool xfs_is_quota_inode(struct xfs_sb *sbp, xfs_ino_t ino) -- 2.47.2