Source kernel commit: 1d08e11d04d293cb7006d1c8641be1fdd8a8e397 This patch adds the needed routines to create, log and recover logged extended attribute intents. Signed-off-by: Allison Henderson <allison.henderson@xxxxxxxxxx> Reviewed-by: Chandan Babu R <chandanrlinux@xxxxxxxxx> Reviewed-by: Darrick J. Wong <djwong@xxxxxxxxxx> Signed-off-by: Dave Chinner <david@xxxxxxxxxxxxx> Signed-off-by: Allison Henderson <allison.henderson@xxxxxxxxxx> --- libxfs/defer_item.c | 92 +++++++++++++++++++++++++++++++++++++++++++++ libxfs/xfs_defer.c | 1 + libxfs/xfs_defer.h | 1 + libxfs/xfs_format.h | 9 ++++- 4 files changed, 102 insertions(+), 1 deletion(-) diff --git a/libxfs/defer_item.c b/libxfs/defer_item.c index 1337fa5fa457..be2a9903701f 100644 --- a/libxfs/defer_item.c +++ b/libxfs/defer_item.c @@ -120,6 +120,98 @@ const struct xfs_defer_op_type xfs_extent_free_defer_type = { .cancel_item = xfs_extent_free_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, +}; + /* * AGFL blocks are accounted differently in the reserve pools and are not * inserted into the busy extent list. diff --git a/libxfs/xfs_defer.c b/libxfs/xfs_defer.c index 3a2576c14ee9..259ae39f90b5 100644 --- a/libxfs/xfs_defer.c +++ b/libxfs/xfs_defer.c @@ -180,6 +180,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 c3a540345fae..f18494c0d791 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 d665c04e69dd..302b50bc5830 100644 --- a/libxfs/xfs_format.h +++ b/libxfs/xfs_format.h @@ -388,7 +388,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( @@ -413,6 +415,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.25.1