xfs: don't hold xattr leaf buffers across transaction rolls
authorDarrick J. Wong <djwong@kernel.org>
Sat, 25 Jun 2022 17:01:20 +0000 (10:01 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Wed, 29 Jun 2022 15:47:56 +0000 (08:47 -0700)
Now that we've established (again!) that empty xattr leaf buffers are
ok, we no longer need to bhold them to transactions when we're creating
new leaf blocks.  Get rid of the entire mechanism, which should simplify
the xattr code quite a bit.

The original justification for using bhold here was to prevent the AIL
from trying to write the empty leaf block into the fs during the brief
time that we release the buffer lock.  The reason for /that/ was to
prevent recovery from tripping over the empty ondisk block.

Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
fs/xfs/libxfs/xfs_attr.c
fs/xfs/libxfs/xfs_attr.h
fs/xfs/libxfs/xfs_attr_leaf.c
fs/xfs/libxfs/xfs_attr_leaf.h
fs/xfs/xfs_attr_item.c

index 1824f61621a24496ccffc83a642b2c43a19a81ad..224649a76cbbb84e8852a1917e45c123f231789d 100644 (file)
@@ -50,7 +50,7 @@ STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args);
 STATIC int xfs_attr_leaf_get(xfs_da_args_t *args);
 STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args);
 STATIC int xfs_attr_leaf_hasname(struct xfs_da_args *args, struct xfs_buf **bp);
-STATIC int xfs_attr_leaf_try_add(struct xfs_da_args *args, struct xfs_buf *bp);
+STATIC int xfs_attr_leaf_try_add(struct xfs_da_args *args);
 
 /*
  * Internal routines when attribute list is more than one block.
@@ -393,16 +393,10 @@ xfs_attr_sf_addname(
         * It won't fit in the shortform, transform to a leaf block.  GROT:
         * another possible req'mt for a double-split btree op.
         */
-       error = xfs_attr_shortform_to_leaf(args, &attr->xattri_leaf_bp);
+       error = xfs_attr_shortform_to_leaf(args);
        if (error)
                return error;
 
-       /*
-        * Prevent the leaf buffer from being unlocked so that a concurrent AIL
-        * push cannot grab the half-baked leaf buffer and run into problems
-        * with the write verifier.
-        */
-       xfs_trans_bhold(args->trans, attr->xattri_leaf_bp);
        attr->xattri_dela_state = XFS_DAS_LEAF_ADD;
 out:
        trace_xfs_attr_sf_addname_return(attr->xattri_dela_state, args->dp);
@@ -447,11 +441,9 @@ xfs_attr_leaf_addname(
 
        /*
         * Use the leaf buffer we may already hold locked as a result of
-        * a sf-to-leaf conversion. The held buffer is no longer valid
-        * after this call, regardless of the result.
+        * a sf-to-leaf conversion.
         */
-       error = xfs_attr_leaf_try_add(args, attr->xattri_leaf_bp);
-       attr->xattri_leaf_bp = NULL;
+       error = xfs_attr_leaf_try_add(args);
 
        if (error == -ENOSPC) {
                error = xfs_attr3_leaf_to_node(args);
@@ -497,8 +489,6 @@ xfs_attr_node_addname(
        struct xfs_da_args      *args = attr->xattri_da_args;
        int                     error;
 
-       ASSERT(!attr->xattri_leaf_bp);
-
        error = xfs_attr_node_addname_find_attr(attr);
        if (error)
                return error;
@@ -1215,24 +1205,14 @@ xfs_attr_restore_rmt_blk(
  */
 STATIC int
 xfs_attr_leaf_try_add(
-       struct xfs_da_args      *args,
-       struct xfs_buf          *bp)
+       struct xfs_da_args      *args)
 {
+       struct xfs_buf          *bp;
        int                     error;
 
-       /*
-        * If the caller provided a buffer to us, it is locked and held in
-        * the transaction because it just did a shortform to leaf conversion.
-        * Hence we don't need to read it again. Otherwise read in the leaf
-        * buffer.
-        */
-       if (bp) {
-               xfs_trans_bhold_release(args->trans, bp);
-       } else {
-               error = xfs_attr3_leaf_read(args->trans, args->dp, 0, &bp);
-               if (error)
-                       return error;
-       }
+       error = xfs_attr3_leaf_read(args->trans, args->dp, 0, &bp);
+       if (error)
+               return error;
 
        /*
         * Look up the xattr name to set the insertion point for the new xattr.
index b4a2fc77017e0608b333c177e480addef844a48a..dfb47fa63c6d52785f0566056ad98435efc57b53 100644 (file)
@@ -515,11 +515,6 @@ struct xfs_attr_intent {
         */
        struct xfs_attri_log_nameval    *xattri_nameval;
 
-       /*
-        * Used by xfs_attr_set to hold a leaf buffer across a transaction roll
-        */
-       struct xfs_buf                  *xattri_leaf_bp;
-
        /* Used to keep track of current state of delayed operation */
        enum xfs_delattr_state          xattri_dela_state;
 
index f6629960e17b36127d487d5e9664fdedc9c13ec0..8f47396f8dd23bbfbe8cd93a25a9a9f60e724228 100644 (file)
@@ -930,14 +930,10 @@ xfs_attr_shortform_getvalue(
        return -ENOATTR;
 }
 
-/*
- * Convert from using the shortform to the leaf.  On success, return the
- * buffer so that we can keep it locked until we're totally done with it.
- */
+/* Convert from using the shortform to the leaf format. */
 int
 xfs_attr_shortform_to_leaf(
-       struct xfs_da_args              *args,
-       struct xfs_buf                  **leaf_bp)
+       struct xfs_da_args              *args)
 {
        struct xfs_inode                *dp;
        struct xfs_attr_shortform       *sf;
@@ -999,7 +995,6 @@ xfs_attr_shortform_to_leaf(
                sfe = xfs_attr_sf_nextentry(sfe);
        }
        error = 0;
-       *leaf_bp = bp;
 out:
        kmem_free(tmpbuffer);
        return error;
index efa757f1e912c7ac8ba642c6a9586c02479d1064..368f4d9fa1d596a43649c307676597b05a74e656 100644 (file)
@@ -49,8 +49,7 @@ void  xfs_attr_shortform_create(struct xfs_da_args *args);
 void   xfs_attr_shortform_add(struct xfs_da_args *args, int forkoff);
 int    xfs_attr_shortform_lookup(struct xfs_da_args *args);
 int    xfs_attr_shortform_getvalue(struct xfs_da_args *args);
-int    xfs_attr_shortform_to_leaf(struct xfs_da_args *args,
-                       struct xfs_buf **leaf_bp);
+int    xfs_attr_shortform_to_leaf(struct xfs_da_args *args);
 int    xfs_attr_sf_removename(struct xfs_da_args *args);
 int    xfs_attr_sf_findname(struct xfs_da_args *args,
                             struct xfs_attr_sf_entry **sfep,
index 6ee905a09eb24f7e031994dfbac19168660aa541..5077a7ad56460f78cffb578f3bddc381e2da8cd3 100644 (file)
@@ -455,8 +455,6 @@ static inline void
 xfs_attr_free_item(
        struct xfs_attr_intent          *attr)
 {
-       ASSERT(attr->xattri_leaf_bp == NULL);
-
        if (attr->xattri_da_state)
                xfs_da_state_free(attr->xattri_da_state);
        xfs_attri_log_nameval_put(attr->xattri_nameval);
@@ -511,10 +509,6 @@ xfs_attr_cancel_item(
        struct xfs_attr_intent          *attr;
 
        attr = container_of(item, struct xfs_attr_intent, xattri_list);
-       if (attr->xattri_leaf_bp) {
-               xfs_buf_relse(attr->xattri_leaf_bp);
-               attr->xattri_leaf_bp = NULL;
-       }
        xfs_attr_free_item(attr);
 }
 
@@ -672,16 +666,6 @@ xfs_attri_item_recover(
                if (error)
                        goto out_unlock;
 
-               /*
-                * The defer capture structure took its own reference to the
-                * attr leaf buffer and will give that to the continuation
-                * transaction.  The attr intent struct drives the continuation
-                * work, so release our refcount on the attr leaf buffer but
-                * retain the pointer in the intent structure.
-                */
-               if (attr->xattri_leaf_bp)
-                       xfs_buf_relse(attr->xattri_leaf_bp);
-
                xfs_iunlock(ip, XFS_ILOCK_EXCL);
                xfs_irele(ip);
                return 0;
@@ -692,13 +676,7 @@ xfs_attri_item_recover(
        }
 
        error = xfs_defer_ops_capture_and_commit(tp, capture_list);
-
 out_unlock:
-       if (attr->xattri_leaf_bp) {
-               xfs_buf_relse(attr->xattri_leaf_bp);
-               attr->xattri_leaf_bp = NULL;
-       }
-
        xfs_iunlock(ip, XFS_ILOCK_EXCL);
        xfs_irele(ip);
 out: