]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: Add xfs_attr_set_deferred and xfs_attr_remove_deferred
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: f3f36c893f260275eb9229cdc3dabb4c79650591

These routines set up and queue a new deferred attribute operations.
These functions are meant to be called by any routine needing to
initiate a deferred attribute operation as opposed to the existing
inline operations. New helper function xfs_attr_item_init also added.

Finally enable delayed attributes in xfs_attr_set and xfs_attr_remove.

Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
libxfs/libxfs_priv.h
libxfs/xfs_attr.c
libxfs/xfs_attr.h

index 4bad869c94a8eabeb3c752acf4bd9cc7f0c550db..f71c7d8e6a1a82ea045019802fe7a944ec3c41e2 100644 (file)
@@ -602,10 +602,12 @@ typedef int (*xfs_rtalloc_query_range_fn)(
 int libxfs_zero_extent(struct xfs_inode *ip, xfs_fsblock_t start_fsb,
                         xfs_off_t count_fsb);
 
-
+/* xfs_log.c */
 bool xfs_log_check_lsn(struct xfs_mount *, xfs_lsn_t);
 void xfs_log_item_init(struct xfs_mount *, struct xfs_log_item *, int);
-#define xfs_log_in_recovery(mp)        (false)
+#define xfs_attr_use_log_assist(mp)    (0)
+#define xlog_drop_incompat_feat(log)   do { } while (0)
+#define xfs_log_in_recovery(mp)                (false)
 
 /* xfs_icache.c */
 #define xfs_inode_set_cowblocks_tag(ip)        do { } while (0)
index 49c7ddb2fa4a882ceb5017cea04179fc675093b2..67a4cddd3e5e0705dbc78743aecba150c4f740ae 100644 (file)
@@ -728,6 +728,7 @@ xfs_attr_set(
        int                     error, local;
        int                     rmt_blks = 0;
        unsigned int            total;
+       int                     delayed = xfs_has_larp(mp);
 
        if (xfs_is_shutdown(dp->i_mount))
                return -EIO;
@@ -784,13 +785,19 @@ xfs_attr_set(
                rmt_blks = xfs_attr3_rmt_blocks(mp, XFS_XATTR_SIZE_MAX);
        }
 
+       if (delayed) {
+               error = xfs_attr_use_log_assist(mp);
+               if (error)
+                       return error;
+       }
+
        /*
         * Root fork attributes can use reserved data blocks for this
         * operation if necessary
         */
        error = xfs_trans_alloc_inode(dp, &tres, total, 0, rsvd, &args->trans);
        if (error)
-               return error;
+               goto drop_incompat;
 
        if (args->value || xfs_inode_hasattr(dp)) {
                error = xfs_iext_count_may_overflow(dp, XFS_ATTR_FORK,
@@ -811,9 +818,10 @@ xfs_attr_set(
                if (error != -ENOATTR && error != -EEXIST)
                        goto out_trans_cancel;
 
-               error = xfs_attr_set_args(args);
+               error = xfs_attr_set_deferred(args);
                if (error)
                        goto out_trans_cancel;
+
                /* shortform attribute has already been committed */
                if (!args->trans)
                        goto out_unlock;
@@ -821,7 +829,7 @@ xfs_attr_set(
                if (error != -EEXIST)
                        goto out_trans_cancel;
 
-               error = xfs_attr_remove_args(args);
+               error = xfs_attr_remove_deferred(args);
                if (error)
                        goto out_trans_cancel;
        }
@@ -843,6 +851,9 @@ xfs_attr_set(
        error = xfs_trans_commit(args->trans);
 out_unlock:
        xfs_iunlock(dp, XFS_ILOCK_EXCL);
+drop_incompat:
+       if (delayed)
+               xlog_drop_incompat_feat(mp->m_log);
        return error;
 
 out_trans_cancel:
@@ -885,6 +896,58 @@ xfs_attrd_destroy_cache(void)
        xfs_attrd_cache = NULL;
 }
 
+STATIC int
+xfs_attr_item_init(
+       struct xfs_da_args      *args,
+       unsigned int            op_flags,       /* op flag (set or remove) */
+       struct xfs_attr_item    **attr)         /* new xfs_attr_item */
+{
+
+       struct xfs_attr_item    *new;
+
+       new = kmem_zalloc(sizeof(struct xfs_attr_item), KM_NOFS);
+       new->xattri_op_flags = op_flags;
+       new->xattri_dac.da_args = args;
+
+       *attr = new;
+       return 0;
+}
+
+/* Sets an attribute for an inode as a deferred operation */
+int
+xfs_attr_set_deferred(
+       struct xfs_da_args      *args)
+{
+       struct xfs_attr_item    *new;
+       int                     error = 0;
+
+       error = xfs_attr_item_init(args, XFS_ATTR_OP_FLAGS_SET, &new);
+       if (error)
+               return error;
+
+       xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
+
+       return 0;
+}
+
+/* Removes an attribute for an inode as a deferred operation */
+int
+xfs_attr_remove_deferred(
+       struct xfs_da_args      *args)
+{
+
+       struct xfs_attr_item    *new;
+       int                     error;
+
+       error  = xfs_attr_item_init(args, XFS_ATTR_OP_FLAGS_REMOVE, &new);
+       if (error)
+               return error;
+
+       xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
+
+       return 0;
+}
+
 /*========================================================================
  * External routines when attribute list is inside the inode
  *========================================================================*/
index 80b6f28b0d1ad043160c55fe1c8e879179adf31c..b52156ad8e6ee47ae07d7c703f3c44fd1217298c 100644 (file)
@@ -525,6 +525,8 @@ bool xfs_attr_namecheck(const void *name, size_t length);
 void xfs_delattr_context_init(struct xfs_delattr_context *dac,
                              struct xfs_da_args *args);
 int xfs_attr_calc_size(struct xfs_da_args *args, int *local);
+int xfs_attr_set_deferred(struct xfs_da_args *args);
+int xfs_attr_remove_deferred(struct xfs_da_args *args);
 
 extern struct kmem_cache       *xfs_attri_cache;
 extern struct kmem_cache       *xfs_attrd_cache;