]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: Implement attr logging and replay
authorAllison Henderson <allison.henderson@oracle.com>
Wed, 22 Jun 2022 19:28:52 +0000 (14:28 -0500)
committerEric Sandeen <sandeen@sandeen.net>
Wed, 22 Jun 2022 19:28:52 +0000 (14:28 -0500)
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>
libxfs/defer_item.c
libxfs/xfs_defer.c
libxfs/xfs_defer.h
libxfs/xfs_format.h

index bd6ace1c4e61694b74b55a3cfcefba0d644f7e06..fc56d3bf62c804400b36e7d82a8f586ac20715a0 100644 (file)
@@ -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,
+};
index 4923b4225fbc8434e2f291010362fee8e9b3c81d..f25de52be8639a3212a3e15c50b6d35ae39ab20a 100644 (file)
@@ -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
index fcd23e5cf1ee6494be28d6b46f4bfd7255c97c8d..114a3a4930a3c47080a1e3e38bf06f3b17cb1bda 100644 (file)
@@ -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,
 };
 
index 96fd49fbc9fad94b7eb47dfccd6951cc1f2710b6..afdfc8108c5fa5736eab9c96e2c9500a1f0021ca 100644 (file)
@@ -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)