]> Gentwo Git Trees - linux/.git/commitdiff
xfs: add a on-disk log header cycle array accessor
authorChristoph Hellwig <hch@lst.de>
Mon, 27 Oct 2025 07:05:49 +0000 (08:05 +0100)
committerCarlos Maiolino <cem@kernel.org>
Wed, 12 Nov 2025 10:09:25 +0000 (11:09 +0100)
Accessing the cycle arrays in the original log record header vs the
extended header is messy and duplicated in multiple places.

Add a xlog_cycle_data helper to abstract it out.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
fs/xfs/xfs_log.c
fs/xfs/xfs_log_priv.h
fs/xfs/xfs_log_recover.c

index e09e5f71ed8c6d62ac183f11834684ce4036e435..a569a4320a3a43ed8aef129b6d3fa616a4526332 100644 (file)
@@ -1524,18 +1524,13 @@ xlog_pack_data(
        struct xlog_in_core     *iclog,
        int                     roundoff)
 {
-       int                     i, j, k;
-       int                     size = iclog->ic_offset + roundoff;
-       __be32                  cycle_lsn;
-       char                    *dp;
-
-       cycle_lsn = CYCLE_LSN_DISK(iclog->ic_header.h_lsn);
+       struct xlog_rec_header  *rhead = &iclog->ic_header;
+       __be32                  cycle_lsn = CYCLE_LSN_DISK(rhead->h_lsn);
+       char                    *dp = iclog->ic_datap;
+       int                     i;
 
-       dp = iclog->ic_datap;
-       for (i = 0; i < BTOBB(size); i++) {
-               if (i >= XLOG_CYCLE_DATA_SIZE)
-                       break;
-               iclog->ic_header.h_cycle_data[i] = *(__be32 *)dp;
+       for (i = 0; i < BTOBB(iclog->ic_offset + roundoff); i++) {
+               *xlog_cycle_data(rhead, i) = *(__be32 *)dp;
                *(__be32 *)dp = cycle_lsn;
                dp += BBSIZE;
        }
@@ -1543,14 +1538,6 @@ xlog_pack_data(
        if (xfs_has_logv2(log->l_mp)) {
                xlog_in_core_2_t *xhdr = iclog->ic_data;
 
-               for ( ; i < BTOBB(size); i++) {
-                       j = i / XLOG_CYCLE_DATA_SIZE;
-                       k = i % XLOG_CYCLE_DATA_SIZE;
-                       xhdr[j].hic_xheader.xh_cycle_data[k] = *(__be32 *)dp;
-                       *(__be32 *)dp = cycle_lsn;
-                       dp += BBSIZE;
-               }
-
                for (i = 1; i < log->l_iclog_heads; i++)
                        xhdr[i].hic_xheader.xh_cycle = cycle_lsn;
        }
@@ -3322,13 +3309,12 @@ xlog_verify_iclog(
        struct xlog_in_core     *iclog,
        int                     count)
 {
-       struct xlog_op_header   *ophead;
+       struct xlog_rec_header  *rhead = &iclog->ic_header;
        xlog_in_core_t          *icptr;
-       xlog_in_core_2_t        *xhdr;
-       void                    *base_ptr, *ptr, *p;
+       void                    *base_ptr, *ptr;
        ptrdiff_t               field_offset;
        uint8_t                 clientid;
-       int                     len, i, j, k, op_len;
+       int                     len, i, op_len;
        int                     idx;
 
        /* check validity of iclog pointers */
@@ -3342,11 +3328,10 @@ xlog_verify_iclog(
        spin_unlock(&log->l_icloglock);
 
        /* check log magic numbers */
-       if (iclog->ic_header.h_magicno != cpu_to_be32(XLOG_HEADER_MAGIC_NUM))
+       if (rhead->h_magicno != cpu_to_be32(XLOG_HEADER_MAGIC_NUM))
                xfs_emerg(log->l_mp, "%s: invalid magic num", __func__);
 
-       base_ptr = ptr = &iclog->ic_header;
-       p = &iclog->ic_header;
+       base_ptr = ptr = rhead;
        for (ptr += BBSIZE; ptr < base_ptr + count; ptr += BBSIZE) {
                if (*(__be32 *)ptr == cpu_to_be32(XLOG_HEADER_MAGIC_NUM))
                        xfs_emerg(log->l_mp, "%s: unexpected magic num",
@@ -3354,29 +3339,19 @@ xlog_verify_iclog(
        }
 
        /* check fields */
-       len = be32_to_cpu(iclog->ic_header.h_num_logops);
+       len = be32_to_cpu(rhead->h_num_logops);
        base_ptr = ptr = iclog->ic_datap;
-       ophead = ptr;
-       xhdr = iclog->ic_data;
        for (i = 0; i < len; i++) {
-               ophead = ptr;
+               struct xlog_op_header   *ophead = ptr;
+               void                    *p = &ophead->oh_clientid;
 
                /* clientid is only 1 byte */
-               p = &ophead->oh_clientid;
                field_offset = p - base_ptr;
                if (field_offset & 0x1ff) {
                        clientid = ophead->oh_clientid;
                } else {
                        idx = BTOBBT((void *)&ophead->oh_clientid - iclog->ic_datap);
-                       if (idx >= XLOG_CYCLE_DATA_SIZE) {
-                               j = idx / XLOG_CYCLE_DATA_SIZE;
-                               k = idx % XLOG_CYCLE_DATA_SIZE;
-                               clientid = xlog_get_client_id(
-                                       xhdr[j].hic_xheader.xh_cycle_data[k]);
-                       } else {
-                               clientid = xlog_get_client_id(
-                                       iclog->ic_header.h_cycle_data[idx]);
-                       }
+                       clientid = xlog_get_client_id(*xlog_cycle_data(rhead, idx));
                }
                if (clientid != XFS_TRANSACTION && clientid != XFS_LOG) {
                        xfs_warn(log->l_mp,
@@ -3392,13 +3367,7 @@ xlog_verify_iclog(
                        op_len = be32_to_cpu(ophead->oh_len);
                } else {
                        idx = BTOBBT((void *)&ophead->oh_len - iclog->ic_datap);
-                       if (idx >= XLOG_CYCLE_DATA_SIZE) {
-                               j = idx / XLOG_CYCLE_DATA_SIZE;
-                               k = idx % XLOG_CYCLE_DATA_SIZE;
-                               op_len = be32_to_cpu(xhdr[j].hic_xheader.xh_cycle_data[k]);
-                       } else {
-                               op_len = be32_to_cpu(iclog->ic_header.h_cycle_data[idx]);
-                       }
+                       op_len = be32_to_cpu(*xlog_cycle_data(rhead, idx));
                }
                ptr += sizeof(struct xlog_op_header) + op_len;
        }
index 0cfc654d8e872b8b6d1252c391092f052118a0fa..d2f17691eccac1484c61cfd213623d06640aefe7 100644 (file)
@@ -711,4 +711,22 @@ xlog_item_space(
        return round_up(nbytes, sizeof(uint64_t));
 }
 
+/*
+ * Cycles over XLOG_CYCLE_DATA_SIZE overflow into the extended header that was
+ * added for v2 logs.  Addressing for the cycles array there is off by one,
+ * because the first batch of cycles is in the original header.
+ */
+static inline __be32 *xlog_cycle_data(struct xlog_rec_header *rhead, unsigned i)
+{
+       if (i >= XLOG_CYCLE_DATA_SIZE) {
+               xlog_in_core_2_t *xhdr = (xlog_in_core_2_t *)rhead;
+               unsigned        j = i / XLOG_CYCLE_DATA_SIZE;
+               unsigned        k = i % XLOG_CYCLE_DATA_SIZE;
+
+               return &xhdr[j].hic_xheader.xh_cycle_data[k];
+       }
+
+       return &rhead->h_cycle_data[i];
+}
+
 #endif /* __XFS_LOG_PRIV_H__ */
index bb2b3f976deb3783edc57d21fd05517ec42604fc..ef0f6efc4381dfc80ddcb102b86aaa281da1c59e 100644 (file)
@@ -2863,23 +2863,12 @@ xlog_unpack_data(
        char                    *dp,
        struct xlog             *log)
 {
-       int                     i, j, k;
+       int                     i;
 
-       for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)) &&
-                 i < XLOG_CYCLE_DATA_SIZE; i++) {
-               *(__be32 *)dp = *(__be32 *)&rhead->h_cycle_data[i];
+       for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)); i++) {
+               *(__be32 *)dp = *xlog_cycle_data(rhead, i);
                dp += BBSIZE;
        }
-
-       if (xfs_has_logv2(log->l_mp)) {
-               xlog_in_core_2_t *xhdr = (xlog_in_core_2_t *)rhead;
-               for ( ; i < BTOBB(be32_to_cpu(rhead->h_len)); i++) {
-                       j = i / XLOG_CYCLE_DATA_SIZE;
-                       k = i % XLOG_CYCLE_DATA_SIZE;
-                       *(__be32 *)dp = xhdr[j].hic_xheader.xh_cycle_data[k];
-                       dp += BBSIZE;
-               }
-       }
 }
 
 /*