]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
xfs: refactor AGI unlinked bucket updates
authorDarrick J. Wong <darrick.wong@oracle.com>
Thu, 7 Feb 2019 18:37:14 +0000 (10:37 -0800)
committerDarrick J. Wong <darrick.wong@oracle.com>
Tue, 12 Feb 2019 00:07:01 +0000 (16:07 -0800)
Split the AGI unlinked bucket updates into a separate function.  No
functional changes.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
fs/xfs/xfs_inode.c
fs/xfs/xfs_trace.h

index 8a39d80f48633028fff1d7cf16af5d6501822f13..f1de80e8b9a652323d44e34309a6c6b31941cc8d 100644 (file)
@@ -1906,6 +1906,43 @@ xfs_inactive(
        xfs_qm_dqdetach(ip);
 }
 
+/*
+ * Point the AGI unlinked bucket at an inode and log the results.  The caller
+ * is responsible for validating the old value.
+ */
+STATIC int
+xfs_iunlink_update_bucket(
+       struct xfs_trans        *tp,
+       xfs_agnumber_t          agno,
+       struct xfs_buf          *agibp,
+       unsigned int            bucket_index,
+       xfs_agino_t             new_agino)
+{
+       struct xfs_agi          *agi = XFS_BUF_TO_AGI(agibp);
+       xfs_agino_t             old_value;
+       int                     offset;
+
+       ASSERT(xfs_verify_agino_or_null(tp->t_mountp, agno, new_agino));
+
+       old_value = be32_to_cpu(agi->agi_unlinked[bucket_index]);
+       trace_xfs_iunlink_update_bucket(tp->t_mountp, agno, bucket_index,
+                       old_value, new_agino);
+
+       /*
+        * We should never find the head of the list already set to the value
+        * passed in because either we're adding or removing ourselves from the
+        * head of the list.
+        */
+       if (old_value == new_agino)
+               return -EFSCORRUPTED;
+
+       agi->agi_unlinked[bucket_index] = cpu_to_be32(new_agino);
+       offset = offsetof(struct xfs_agi, agi_unlinked) +
+                       (sizeof(xfs_agino_t) * bucket_index);
+       xfs_trans_log_buf(tp, agibp, offset, offset + sizeof(xfs_agino_t) - 1);
+       return 0;
+}
+
 /*
  * This is called when the inode's link count goes to 0 or we are creating a
  * tmpfile via O_TMPFILE. In the case of a tmpfile, @ignore_linkcount will be
@@ -1973,16 +2010,8 @@ xfs_iunlink(
                xfs_inobp_check(mp, ibp);
        }
 
-       /*
-        * Point the bucket head pointer at the inode being inserted.
-        */
-       ASSERT(agino != 0);
-       agi->agi_unlinked[bucket_index] = cpu_to_be32(agino);
-       offset = offsetof(xfs_agi_t, agi_unlinked) +
-               (sizeof(xfs_agino_t) * bucket_index);
-       xfs_trans_log_buf(tp, agibp, offset,
-                         (offset + sizeof(xfs_agino_t) - 1));
-       return 0;
+       /* Point the head of the list to point to this inode. */
+       return xfs_iunlink_update_bucket(tp, agno, agibp, bucket_index, agino);
 }
 
 /*
@@ -2058,16 +2087,12 @@ xfs_iunlink_remove(
                } else {
                        xfs_trans_brelse(tp, ibp);
                }
-               /*
-                * Point the bucket head pointer at the next inode.
-                */
-               ASSERT(next_agino != 0);
-               ASSERT(next_agino != agino);
-               agi->agi_unlinked[bucket_index] = cpu_to_be32(next_agino);
-               offset = offsetof(xfs_agi_t, agi_unlinked) +
-                       (sizeof(xfs_agino_t) * bucket_index);
-               xfs_trans_log_buf(tp, agibp, offset,
-                                 (offset + sizeof(xfs_agino_t) - 1));
+
+               /* Point the head of the list to the next unlinked inode. */
+               error = xfs_iunlink_update_bucket(tp, agno, agibp, bucket_index,
+                               next_agino);
+               if (error)
+                       return error;
        } else {
                /*
                 * We need to search the list for the inode being freed.
index 6fcc893dfc91358e7da174e4bf4126112cb2a1e2..c10478e7e49a6ec3870b07d0598a262990b8471e 100644 (file)
@@ -3371,6 +3371,32 @@ DEFINE_TRANS_EVENT(xfs_trans_roll);
 DEFINE_TRANS_EVENT(xfs_trans_add_item);
 DEFINE_TRANS_EVENT(xfs_trans_free_items);
 
+TRACE_EVENT(xfs_iunlink_update_bucket,
+       TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, unsigned int bucket,
+                xfs_agino_t old_ptr, xfs_agino_t new_ptr),
+       TP_ARGS(mp, agno, bucket, old_ptr, new_ptr),
+       TP_STRUCT__entry(
+               __field(dev_t, dev)
+               __field(xfs_agnumber_t, agno)
+               __field(unsigned int, bucket)
+               __field(xfs_agino_t, old_ptr)
+               __field(xfs_agino_t, new_ptr)
+       ),
+       TP_fast_assign(
+               __entry->dev = mp->m_super->s_dev;
+               __entry->agno = agno;
+               __entry->bucket = bucket;
+               __entry->old_ptr = old_ptr;
+               __entry->new_ptr = new_ptr;
+       ),
+       TP_printk("dev %d:%d agno %u bucket %u old 0x%x new 0x%x",
+                 MAJOR(__entry->dev), MINOR(__entry->dev),
+                 __entry->agno,
+                 __entry->bucket,
+                 __entry->old_ptr,
+                 __entry->new_ptr)
+);
+
 #endif /* _TRACE_XFS_H */
 
 #undef TRACE_INCLUDE_PATH