diff options
author | Allison Henderson <allison.henderson@oracle.com> | 2022-06-22 14:28:52 -0500 |
---|---|---|
committer | Eric Sandeen <sandeen@sandeen.net> | 2022-06-22 14:28:52 -0500 |
commit | c6ad4bc15019235a6cbe1a51d6d6e454dd4a8d89 (patch) | |
tree | 10e0ee64475523b02dd89ad629d5f29eac0f7c6b | |
parent | 6bcbc2443f477e36240b06caf96db98d4091e6aa (diff) | |
download | xfsprogs-dev-c6ad4bc15019235a6cbe1a51d6d6e454dd4a8d89.tar.gz |
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 <allison.henderson@oracle.com>
Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
-rw-r--r-- | libxfs/defer_item.c | 95 | ||||
-rw-r--r-- | libxfs/xfs_defer.c | 1 | ||||
-rw-r--r-- | libxfs/xfs_defer.h | 1 | ||||
-rw-r--r-- | libxfs/xfs_format.h | 9 |
4 files changed, 105 insertions, 1 deletions
diff --git a/libxfs/defer_item.c b/libxfs/defer_item.c index bd6ace1c4e..fc56d3bf62 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 4923b4225f..f25de52be8 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 fcd23e5cf1..114a3a4930 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 96fd49fbc9..afdfc8108c 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) |