aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllison Henderson <allison.henderson@oracle.com>2022-06-22 14:28:52 -0500
committerEric Sandeen <sandeen@sandeen.net>2022-06-22 14:28:52 -0500
commitc6ad4bc15019235a6cbe1a51d6d6e454dd4a8d89 (patch)
tree10e0ee64475523b02dd89ad629d5f29eac0f7c6b
parent6bcbc2443f477e36240b06caf96db98d4091e6aa (diff)
downloadxfsprogs-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.c95
-rw-r--r--libxfs/xfs_defer.c1
-rw-r--r--libxfs/xfs_defer.h1
-rw-r--r--libxfs/xfs_format.h9
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)