]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blobdiff - logprint/log_misc.c
xfs_logprint: fix shadow var in xlog_print_trans_buffer
[thirdparty/xfsprogs-dev.git] / logprint / log_misc.c
index d08f90068a90f557aae09fa0d29cb8fd6888a3eb..c325f046069af178029a869642134bb519bf84fb 100644 (file)
@@ -1,20 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
  * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
+#include "libxfs.h"
+#include "libxlog.h"
 
 #include "logprint.h"
 
 #define NO_ERROR       (0)
 
 static int logBBsize;
-char *trans_type[] = {
-       "",
-       "SETATTR",
-       "SETATTR_SIZE",
-       "INACTIVE",
-       "CREATE",
-       "CREATE_TRUNC",
-       "TRUNCATE_FILE",
-       "REMOVE",
-       "LINK",
-       "RENAME",
-       "MKDIR",
-       "RMDIR",
-       "SYMLINK",
-       "SET_DMATTRS",
-       "GROWFS",
-       "STRAT_WRITE",
-       "DIOSTRAT",
-       "WRITE_SYNC",
-       "WRITEID",
-       "ADDAFORK",
-       "ATTRINVAL",
-       "ATRUNCATE",
-       "ATTR_SET",
-       "ATTR_RM",
-       "ATTR_FLAG",
-       "CLEAR_AGI_BUCKET",
-       "QM_SBCHANGE",
-       "DUMMY1",
-       "DUMMY2",
-       "QM_QUOTAOFF",
-       "QM_DQALLOC",
-       "QM_SETQLIM",
-       "QM_DQCLUSTER",
-       "QM_QINOCREATE",
-       "QM_QUOTAOFF_END",
-       "SB_UNIT",
-       "FSYNC_TS",
-       "GROWFSRT_ALLOC",
-       "GROWFSRT_ZERO",
-       "GROWFSRT_FREE",
-       "SWAPEXT",
-       "SB_COUNT",
-       "CHECKPOINT",
-};
 
 typedef struct xlog_split_item {
        struct xlog_split_item  *si_next;
        struct xlog_split_item  *si_prev;
-       xlog_tid_t              si_tid;
+       xlog_tid_t              si_xtid;
        int                     si_skip;
 } xlog_split_item_t;
 
-xlog_split_item_t *split_list = NULL;
+static xlog_split_item_t *split_list = NULL;
 
 void
 print_xlog_op_line(void)
@@ -88,7 +33,7 @@ print_xlog_op_line(void)
           "--------------------------------------\n");
 }      /* print_xlog_op_line */
 
-void
+static void
 print_xlog_xhdr_line(void)
 {
     printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
@@ -113,10 +58,10 @@ print_stars(void)
  * Given a pointer to a data segment, print out the data as if it were
  * a log operation header.
  */
-void
+static void
 xlog_print_op_header(xlog_op_header_t  *op_head,
                     int                i,
-                    xfs_caddr_t        *ptr)
+                    char               **ptr)
 {
     xlog_op_header_t hbuf;
 
@@ -153,14 +98,14 @@ xlog_print_op_header(xlog_op_header_t      *op_head,
 }      /* xlog_print_op_header */
 
 
-void
+static void
 xlog_print_add_to_trans(xlog_tid_t     tid,
                        int             skip)
 {
     xlog_split_item_t *item;
 
     item         = (xlog_split_item_t *)calloc(sizeof(xlog_split_item_t), 1);
-    item->si_tid  = tid;
+    item->si_xtid  = tid;
     item->si_skip = skip;
     item->si_next = split_list;
     item->si_prev = NULL;
@@ -170,7 +115,7 @@ xlog_print_add_to_trans(xlog_tid_t  tid,
 }      /* xlog_print_add_to_trans */
 
 
-int
+static int
 xlog_print_find_tid(xlog_tid_t tid, uint was_cont)
 {
     xlog_split_item_t *listp = split_list;
@@ -182,7 +127,7 @@ xlog_print_find_tid(xlog_tid_t tid, uint was_cont)
            return 0;
     }
     while (listp) {
-       if (listp->si_tid == tid)
+       if (listp->si_xtid == tid)
            break;
        listp = listp->si_next;
     }
@@ -204,17 +149,17 @@ xlog_print_find_tid(xlog_tid_t tid, uint was_cont)
     return 1;
 }      /* xlog_print_find_tid */
 
-int
-xlog_print_trans_header(xfs_caddr_t *ptr, int len)
+static int
+xlog_print_trans_header(char **ptr, int len)
 {
     xfs_trans_header_t  *h;
-    xfs_caddr_t                cptr = *ptr;
-    __uint32_t          magic;
+    char               *cptr = *ptr;
+    uint32_t          magic;
     char                *magic_c = (char *)&magic;
 
     *ptr += len;
 
-    magic=*(__uint32_t*)cptr; /* XXX be32_to_cpu soon */
+    magic = *(uint32_t *)cptr; /* XXX be32_to_cpu soon */
 
     if (len >= 4) {
 #if __BYTE_ORDER == __LITTLE_ENDIAN
@@ -230,34 +175,30 @@ xlog_print_trans_header(xfs_caddr_t *ptr, int len)
        return 1;
     }
     h = (xfs_trans_header_t *)cptr;
-    printf(_("    type: %s       tid: %x       num_items: %d\n"),
-          trans_type[h->th_type], h->th_tid, h->th_num_items);
+    printf(_("     tid: %x  num_items: %d\n"),
+          h->th_tid, h->th_num_items);
     return 0;
 }      /* xlog_print_trans_header */
 
 
-int
-xlog_print_trans_buffer(xfs_caddr_t *ptr, int len, int *i, int num_ops)
+static int
+xlog_print_trans_buffer(char **ptr, int len, int *i, int num_ops)
 {
     xfs_buf_log_format_t *f;
-    xfs_agi_t           *agi;
-    xfs_agf_t           *agf;
-    xfs_disk_dquot_t    *dq;
     xlog_op_header_t    *head = NULL;
     int                         num, skip;
     int                         super_block = 0;
     int                         bucket, col, buckets;
-    __int64_t           blkno;
+    int64_t                     blkno;
     xfs_buf_log_format_t lbuf;
     int                         size, blen, map_size, struct_size;
-    __be64              x, y;
-    ushort              flags;
+    unsigned short      flags;
 
     /*
      * memmove to ensure 8-byte alignment for the long longs in
      * buf_log_format_t structure
      */
-    memmove(&lbuf, *ptr, MIN(sizeof(xfs_buf_log_format_t), len));
+    memmove(&lbuf, *ptr, min(sizeof(xfs_buf_log_format_t), len));
     f = &lbuf;
     *ptr += len;
 
@@ -305,26 +246,40 @@ xlog_print_trans_buffer(xfs_caddr_t *ptr, int len, int *i, int num_ops)
                if (be32_to_cpu(head->oh_len) < 4*8) {
                        printf(_("Out of space\n"));
                } else {
+                       __be64           a, b;
+
                        printf("\n");
                        /*
                         * memmove because *ptr may not be 8-byte aligned
                         */
-                       memmove(&x, *ptr, sizeof(__be64));
-                       memmove(&y, *ptr+8, sizeof(__be64));
-                      printf(_("icount: %llu  ifree: %llu  "),
-                              (unsigned long long) be64_to_cpu(x),
-                              (unsigned long long) be64_to_cpu(y));
-                       memmove(&x, *ptr+16, sizeof(__be64));
-                       memmove(&y, *ptr+24, sizeof(__be64));
-                      printf(_("fdblks: %llu  frext: %llu\n"),
-                              (unsigned long long) be64_to_cpu(x),
-                              (unsigned long long) be64_to_cpu(y));
+                       memmove(&a, *ptr, sizeof(__be64));
+                       memmove(&b, *ptr+8, sizeof(__be64));
+                       printf(_("icount: %llu  ifree: %llu  "),
+                              (unsigned long long) be64_to_cpu(a),
+                              (unsigned long long) be64_to_cpu(b));
+                       memmove(&a, *ptr+16, sizeof(__be64));
+                       memmove(&b, *ptr+24, sizeof(__be64));
+                       printf(_("fdblks: %llu  frext: %llu\n"),
+                              (unsigned long long) be64_to_cpu(a),
+                              (unsigned long long) be64_to_cpu(b));
                }
                super_block = 0;
        } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_AGI_MAGIC) {
-               agi = (xfs_agi_t *)(*ptr);
+               struct xfs_agi  *agi, agi_s;
+
+               /* memmove because *ptr may not be 8-byte aligned */
+               agi = &agi_s;
+               memmove(agi, *ptr, sizeof(struct xfs_agi));
                printf(_("AGI Buffer: XAGI  "));
-               if (be32_to_cpu(head->oh_len) < sizeof(xfs_agi_t) -
+               /*
+                * v4 filesystems only contain the fields before the uuid.
+                * Even v5 filesystems don't log any field beneath it. That
+                * means that the size that is logged is almost always going to
+                * be smaller than the structure itself. Hence we need to make
+                * sure that the buffer contains all the data we want to print
+                * rather than just check against the structure size.
+                */
+               if (be32_to_cpu(head->oh_len) < offsetof(xfs_agi_t, agi_uuid) -
                                XFS_AGI_UNLINKED_BUCKETS*sizeof(xfs_agino_t)) {
                        printf(_("out of space\n"));
                } else {
@@ -364,9 +319,21 @@ xlog_print_trans_buffer(xfs_caddr_t *ptr, int len, int *i, int num_ops)
                        }
                }
        } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_AGF_MAGIC) {
-               agf = (xfs_agf_t *)(*ptr);
+               struct xfs_agf  *agf, agf_s;
+
+               /* memmove because *ptr may not be 8-byte aligned */
+               agf = &agf_s;
+               memmove(agf, *ptr, sizeof(struct xfs_agf));
                printf(_("AGF Buffer: XAGF  "));
-               if (be32_to_cpu(head->oh_len) < sizeof(xfs_agf_t)) {
+               /*
+                * v4 filesystems only contain the fields before the uuid.
+                * Even v5 filesystems don't log any field beneath it. That
+                * means that the size that is logged is almost always going to
+                * be smaller than the structure itself. Hence we need to make
+                * sure that the buffer contains all the data we want to print
+                * rather than just check against the structure size.
+                */
+               if (be32_to_cpu(head->oh_len) < offsetof(xfs_agf_t, agf_uuid)) {
                        printf(_("Out of space\n"));
                } else {
                        printf("\n");
@@ -389,7 +356,11 @@ xlog_print_trans_buffer(xfs_caddr_t *ptr, int len, int *i, int num_ops)
                                be32_to_cpu(agf->agf_longest));
                }
        } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_DQUOT_MAGIC) {
-               dq = (xfs_disk_dquot_t *)(*ptr);
+               struct xfs_disk_dquot *dq, dq_s;
+
+               /* memmove because *ptr may not be 8-byte aligned */
+               dq = &dq_s;
+               memmove(dq, *ptr, sizeof(struct xfs_disk_dquot));
                printf(_("DQUOT Buffer: DQ  "));
                if (be32_to_cpu(head->oh_len) <
                                sizeof(xfs_disk_dquot_t)) {
@@ -424,15 +395,15 @@ xlog_print_trans_buffer(xfs_caddr_t *ptr, int len, int *i, int num_ops)
                if (print_data) {
                        uint *dp  = (uint *)*ptr;
                        int  nums = be32_to_cpu(head->oh_len) >> 2;
-                       int  i = 0;
+                       int  byte = 0;
 
-                       while (i < nums) {
-                               if ((i % 8) == 0)
-                                       printf("%2x ", i);
+                       while (byte < nums) {
+                               if ((byte % 8) == 0)
+                                       printf("%2x ", byte);
                                printf("%8x ", *dp);
                                dp++;
-                               i++;
-                               if ((i % 8) == 0)
+                               byte++;
+                               if ((byte % 8) == 0)
                                        printf("\n");
                        }
                        printf("\n");
@@ -446,90 +417,13 @@ xlog_print_trans_buffer(xfs_caddr_t *ptr, int len, int *i, int num_ops)
 }      /* xlog_print_trans_buffer */
 
 
-int
-xlog_print_trans_efd(xfs_caddr_t *ptr, uint len)
-{
-    xfs_efd_log_format_t *f;
-    xfs_efd_log_format_t lbuf;
-    /* size without extents at end */
-    uint core_size = sizeof(xfs_efd_log_format_t) - sizeof(xfs_extent_t);
-
-    /*
-     * memmove to ensure 8-byte alignment for the long longs in
-     * xfs_efd_log_format_t structure
-     */
-    memmove(&lbuf, *ptr, MIN(core_size, len));
-    f = &lbuf;
-    *ptr += len;
-    if (len >= core_size) {
-       printf(_("EFD:  #regs: %d    num_extents: %d  id: 0x%llx\n"),
-              f->efd_size, f->efd_nextents, (unsigned long long)f->efd_efi_id);
-
-       /* don't print extents as they are not used */
-
-       return 0;
-    } else {
-       printf(_("EFD: Not enough data to decode further\n"));
-       return 1;
-    }
-}      /* xlog_print_trans_efd */
-
-
-int
-xlog_print_trans_efi(xfs_caddr_t *ptr, uint src_len)
-{
-    xfs_efi_log_format_t *src_f, *f;
-    uint                dst_len;
-    xfs_extent_t        *ex;
-    int                         i;
-    int                         error = 0;
-
-    /*
-     * memmove to ensure 8-byte alignment for the long longs in
-     * xfs_efi_log_format_t structure
-     */
-    if ((src_f = (xfs_efi_log_format_t *)malloc(src_len)) == NULL) {
-       fprintf(stderr, _("%s: xlog_print_trans_efi: malloc failed\n"), progname);
-       exit(1);
-    }
-    memmove((char*)src_f, *ptr, src_len);
-    *ptr += src_len;
-
-    /* convert to native format */
-    dst_len = sizeof(xfs_efi_log_format_t) + (src_f->efi_nextents - 1) * sizeof(xfs_extent_t);
-    if ((f = (xfs_efi_log_format_t *)malloc(dst_len)) == NULL) {
-       fprintf(stderr, _("%s: xlog_print_trans_efi: malloc failed\n"), progname);
-       exit(1);
-    }
-    if (xfs_efi_copy_format((char*)src_f, src_len, f)) {
-       error = 1;
-       goto error;
-    }
-
-    printf(_("EFI:  #regs: %d    num_extents: %d  id: 0x%llx\n"),
-          f->efi_size, f->efi_nextents, (unsigned long long)f->efi_id);
-    ex = f->efi_extents;
-    for (i=0; i < f->efi_nextents; i++) {
-           printf("(s: 0x%llx, l: %d) ",
-                   (unsigned long long)ex->ext_start, ex->ext_len);
-           if (i % 4 == 3) printf("\n");
-           ex++;
-    }
-    if (i % 4 != 0) printf("\n");
-error:
-    free(src_f);
-    free(f);
-    return error;
-}      /* xlog_print_trans_efi */
-
-
-int
-xlog_print_trans_qoff(xfs_caddr_t *ptr, uint len)
+static int
+xlog_print_trans_qoff(char **ptr, uint len)
 {
     xfs_qoff_logformat_t *f;
     xfs_qoff_logformat_t lbuf;
 
-    memmove(&lbuf, *ptr, MIN(sizeof(xfs_qoff_logformat_t), len));
+    memmove(&lbuf, *ptr, min(sizeof(xfs_qoff_logformat_t), len));
     f = &lbuf;
     *ptr += len;
     if (len >= sizeof(xfs_qoff_logformat_t)) {
@@ -542,8 +436,9 @@ xlog_print_trans_qoff(xfs_caddr_t *ptr, uint len)
 }      /* xlog_print_trans_qoff */
 
 
-void
-xlog_print_trans_inode_core(xfs_icdinode_t *ip)
+static void
+xlog_print_trans_inode_core(
+       struct xfs_log_dinode   *ip)
 {
     printf(_("INODE CORE\n"));
     printf(_("magic 0x%hx mode 0%ho version %d format %d\n"),
@@ -561,11 +456,19 @@ xlog_print_trans_inode_core(xfs_icdinode_t *ip)
           ip->di_dmstate);
     printf(_("flags 0x%x gen 0x%x\n"),
           ip->di_flags, ip->di_gen);
+    if (ip->di_version == 3) {
+        printf(_("flags2 0x%llx cowextsize 0x%x\n"),
+            (unsigned long long)ip->di_flags2, ip->di_cowextsize);
+    }
 }
 
-void
-xlog_print_dir2_sf(xfs_dir2_sf_hdr_t *sfp, int size)
+static void
+xlog_print_dir2_sf(
+       struct xlog     *log,
+       xfs_dir2_sf_hdr_t *sfp,
+       int             size)
 {
+       __be64          pino;   /* parent inode nr */
        xfs_ino_t       ino;
        int             count;
        int             i;
@@ -580,51 +483,54 @@ xlog_print_dir2_sf(xfs_dir2_sf_hdr_t *sfp, int size)
 
        printf(_("SHORTFORM DIRECTORY size %d count %d\n"),
               size, sfp->count);
-       memmove(&ino, &(sfp->parent), sizeof(ino));
-       printf(_(".. ino 0x%llx\n"), (unsigned long long) be64_to_cpu(ino));
+       memmove(&pino, &(sfp->parent), sizeof(pino));
+       printf(_(".. ino 0x%llx\n"), (unsigned long long) be64_to_cpu(pino));
 
        count = sfp->count;
        sfep = xfs_dir2_sf_firstentry(sfp);
        for (i = 0; i < count; i++) {
-               ino = xfs_dir2_sfe_get_ino(sfp, sfep);
+               ino = M_DIROPS(log->l_mp)->sf_get_ino(sfp, sfep);
                memmove(namebuf, (sfep->name), sfep->namelen);
                namebuf[sfep->namelen] = '\0';
                printf(_("%s ino 0x%llx namelen %d\n"),
                       namebuf, (unsigned long long)ino, sfep->namelen);
-               sfep = xfs_dir2_sf_nextentry(sfp, sfep);
+               sfep = M_DIROPS(log->l_mp)->sf_nextentry(sfp, sfep);
        }
 }
 
-int
-xlog_print_trans_inode(xfs_caddr_t *ptr,
-                      int len,
-                      int *i,
-                      int num_ops,
-                      boolean_t continued)
+static int
+xlog_print_trans_inode(
+       struct xlog             *log,
+       char                    **ptr,
+       int                     len,
+       int                     *i,
+       int                     num_ops,
+       int                     continued)
 {
-    xfs_icdinode_t        dino;
-    xlog_op_header_t      *op_head;
-    xfs_inode_log_format_t dst_lbuf;
-    xfs_inode_log_format_64_t src_lbuf; /* buffer of biggest one */
-    xfs_inode_log_format_t *f;
-    int                           mode;
-    int                           size;
+    struct xfs_log_dinode      dino;
+    struct xlog_op_header      *op_head;
+    struct xfs_inode_log_format        dst_lbuf;
+    struct xfs_inode_log_format        src_lbuf;
+    struct xfs_inode_log_format *f;
+    int                                mode;
+    int                                size;
+    int                                skip_count;
 
     /*
      * print inode type header region
      *
      * memmove to ensure 8-byte alignment for the long longs in
-     * xfs_inode_log_format_t structure
+     * struct xfs_inode_log_format structure
      *
-     * len can be smaller than xfs_inode_log_format_32|64_t
+     * len can be smaller than struct xfs_inode_log_format
      * if format data is split over operations
      */
-    memmove(&src_lbuf, *ptr, MIN(sizeof(xfs_inode_log_format_64_t), len));
+    memmove(&src_lbuf, *ptr, min(sizeof(src_lbuf), len));
     (*i)++;                                    /* bump index */
     *ptr += len;
     if (!continued &&
-       (len == sizeof(xfs_inode_log_format_32_t) ||
-        len == sizeof(xfs_inode_log_format_64_t))) {
+       (len == sizeof(struct xfs_inode_log_format_32) ||
+        len == sizeof(struct xfs_inode_log_format))) {
        f = xfs_inode_item_format_convert((char*)&src_lbuf, len, &dst_lbuf);
        printf(_("INODE: "));
        printf(_("#regs: %d   ino: 0x%llx  flags: 0x%x   dsize: %d\n"),
@@ -634,35 +540,31 @@ xlog_print_trans_inode(xfs_caddr_t *ptr,
               (long long)f->ilf_blkno, f->ilf_len, f->ilf_boffset);
     } else {
        ASSERT(len >= 4);       /* must have at least 4 bytes if != 0 */
-       f = (xfs_inode_log_format_t *)&src_lbuf;
+       f = (struct xfs_inode_log_format *)&src_lbuf;
        printf(_("INODE: #regs: %d   Not printing rest of data\n"),
               f->ilf_size);
        return f->ilf_size;
     }
 
+    skip_count = f->ilf_size-1;
+
     if (*i >= num_ops)                 /* end of LR */
-           return f->ilf_size-1;
+           return skip_count;
 
     /* core inode comes 2nd */
     op_head = (xlog_op_header_t *)*ptr;
     xlog_print_op_header(op_head, *i, ptr);
 
     if (op_head->oh_flags & XLOG_CONTINUE_TRANS)  {
-       return f->ilf_size-1;
+        return skip_count;
     }
 
     memmove(&dino, *ptr, sizeof(dino));
     mode = dino.di_mode & S_IFMT;
     size = (int)dino.di_size;
     xlog_print_trans_inode_core(&dino);
-    *ptr += sizeof(xfs_icdinode_t);
-
-    if (*i == num_ops-1 && f->ilf_size == 3)  {
-       return 1;
-    }
-
-    /* does anything come next */
-    op_head = (xlog_op_header_t *)*ptr;
+    *ptr += xfs_log_dinode_size(dino.di_version);
+    skip_count--;
 
     switch (f->ilf_fields & (XFS_ILOG_DEV | XFS_ILOG_UUID)) {
     case XFS_ILOG_DEV:
@@ -680,7 +582,12 @@ xlog_print_trans_inode(xfs_caddr_t *ptr,
     ASSERT(f->ilf_size <= 4);
     ASSERT((f->ilf_size == 3) || (f->ilf_fields & XFS_ILOG_AFORK));
 
+    /* does anything come next */
+    op_head = (xlog_op_header_t *)*ptr;
+
     if (f->ilf_fields & XFS_ILOG_DFORK) {
+           if (*i == num_ops-1)
+               return skip_count;
            (*i)++;
            xlog_print_op_header(op_head, *i, ptr);
 
@@ -694,7 +601,7 @@ xlog_print_trans_inode(xfs_caddr_t *ptr,
            case XFS_ILOG_DDATA:
                printf(_("LOCAL inode data\n"));
                if (mode == S_IFDIR)
-                   xlog_print_dir2_sf((xfs_dir2_sf_hdr_t *)*ptr, size);
+                   xlog_print_dir2_sf(log, (xfs_dir2_sf_hdr_t *)*ptr, size);
                break;
            default:
                ASSERT((f->ilf_fields & XFS_ILOG_DFORK) == 0);
@@ -703,11 +610,14 @@ xlog_print_trans_inode(xfs_caddr_t *ptr,
 
            *ptr += be32_to_cpu(op_head->oh_len);
            if (op_head->oh_flags & XLOG_CONTINUE_TRANS)
-               return 1;
+               return skip_count;
            op_head = (xlog_op_header_t *)*ptr;
+           skip_count--;
     }
 
     if (f->ilf_fields & XFS_ILOG_AFORK) {
+           if (*i == num_ops-1)
+               return skip_count;
            (*i)++;
            xlog_print_op_header(op_head, *i, ptr);
 
@@ -721,7 +631,7 @@ xlog_print_trans_inode(xfs_caddr_t *ptr,
            case XFS_ILOG_ADATA:
                printf(_("LOCAL attr data\n"));
                if (mode == S_IFDIR)
-                   xlog_print_dir2_sf((xfs_dir2_sf_hdr_t *)*ptr, size);
+                   xlog_print_dir2_sf(log, (xfs_dir2_sf_hdr_t *)*ptr, size);
                break;
            default:
                ASSERT((f->ilf_fields & XFS_ILOG_AFORK) == 0);
@@ -729,16 +639,18 @@ xlog_print_trans_inode(xfs_caddr_t *ptr,
            }
            *ptr += be32_to_cpu(op_head->oh_len);
            if (op_head->oh_flags & XLOG_CONTINUE_TRANS)
-               return 1;
-           op_head = (xlog_op_header_t *)*ptr;
+               return skip_count;
+           skip_count--;
     }
 
+    ASSERT(skip_count == 0);
+
     return 0;
 }      /* xlog_print_trans_inode */
 
 
-int
-xlog_print_trans_dquot(xfs_caddr_t *ptr, int len, int *i, int num_ops)
+static int
+xlog_print_trans_dquot(char **ptr, int len, int *i, int num_ops)
 {
     xfs_dq_logformat_t *f;
     xfs_dq_logformat_t lbuf = {0};
@@ -752,7 +664,7 @@ xlog_print_trans_dquot(xfs_caddr_t *ptr, int len, int *i, int num_ops)
      * memmove to ensure 8-byte alignment for the long longs in
      * xfs_dq_logformat_t structure
      */
-    memmove(&lbuf, *ptr, MIN(sizeof(xfs_dq_logformat_t), len));
+    memmove(&lbuf, *ptr, min(sizeof(xfs_dq_logformat_t), len));
     f = &lbuf;
     (*i)++;                                    /* bump index */
     *ptr += len;
@@ -792,6 +704,34 @@ xlog_print_trans_dquot(xfs_caddr_t *ptr, int len, int *i, int num_ops)
 }      /* xlog_print_trans_dquot */
 
 
+STATIC int
+xlog_print_trans_icreate(
+       char            **ptr,
+       int             len,
+       int             *i,
+       int             num_ops)
+{
+       struct xfs_icreate_log  icl_buf = {0};
+       struct xfs_icreate_log  *icl;
+
+       memmove(&icl_buf, *ptr, min(sizeof(struct xfs_icreate_log), len));
+       icl = &icl_buf;
+       *ptr += len;
+
+       /* handle complete header only */
+       if (len != sizeof(struct xfs_icreate_log)) {
+               printf(_("ICR: split header, not printing\n"));
+               return 1; /* to skip leftover in next region */
+       }
+
+       printf(_("ICR:  #ag: %d  agbno: 0x%x  len: %d\n"
+                "      cnt: %d  isize: %d    gen: 0x%x\n"),
+               be32_to_cpu(icl->icl_ag), be32_to_cpu(icl->icl_agbno),
+               be32_to_cpu(icl->icl_length), be32_to_cpu(icl->icl_count),
+               be32_to_cpu(icl->icl_isize), be32_to_cpu(icl->icl_gen));
+       return 0;
+}
+
 /******************************************************************************
  *
  *             Log print routines
@@ -809,16 +749,16 @@ xlog_print_lseek(struct xlog *log, int fd, xfs_daddr_t blkno, int whence)
                offset = BBTOOFF64(blkno+log->l_logBBstart);
        else
                offset = BBTOOFF64(blkno);
-       if (lseek64(fd, offset, whence) < 0) {
-               fprintf(stderr, _("%s: lseek64 to %lld failed: %s\n"),
+       if (lseek(fd, offset, whence) < 0) {
+               fprintf(stderr, _("%s: lseek to %lld failed: %s\n"),
                        progname, (long long)offset, strerror(errno));
                exit(1);
        }
 }      /* xlog_print_lseek */
 
 
-void
-print_lsn(xfs_caddr_t  string,
+static void
+print_lsn(char         *string,
          __be64        *lsn)
 {
     printf("%s: %u,%u", string,
@@ -826,17 +766,20 @@ print_lsn(xfs_caddr_t     string,
 }
 
 
-int
-xlog_print_record(int                    fd,
-                int                      num_ops,
-                int                      len,
-                int                      *read_type,
-                xfs_caddr_t              *partial_buf,
-                xlog_rec_header_t        *rhead,
-                xlog_rec_ext_header_t    *xhdrs)
+static int
+xlog_print_record(
+       struct xlog             *log,
+       int                     fd,
+       int                     num_ops,
+       int                     len,
+       int                     *read_type,
+       char                    **partial_buf,
+       xlog_rec_header_t       *rhead,
+       xlog_rec_ext_header_t   *xhdrs,
+       int                     bad_hdr_warn)
 {
-    xfs_caddr_t                buf, ptr;
-    int                        read_len, skip;
+    char               *buf, *ptr;
+    int                        read_len, skip, lost_context = 0;
     int                        ret, n, i, j, k;
 
     if (print_no_print)
@@ -852,13 +795,13 @@ xlog_print_record(int                       fd,
 
     /* read_type => don't malloc() new buffer, use old one */
     if (*read_type == FULL_READ) {
-       if ((ptr = buf = (xfs_caddr_t)malloc(read_len)) == NULL) {
+       if ((ptr = buf = malloc(read_len)) == NULL) {
            fprintf(stderr, _("%s: xlog_print_record: malloc failed\n"), progname);
            exit(1);
        }
     } else {
        read_len -= *read_type;
-       buf = (xfs_caddr_t)((__psint_t)(*partial_buf) + (__psint_t)(*read_type));
+       buf = (char *)((intptr_t)(*partial_buf) + (intptr_t)(*read_type));
        ptr = *partial_buf;
     }
     if ((ret = (int) read(fd, buf, read_len)) == -1) {
@@ -905,11 +848,12 @@ xlog_print_record(int                       fd,
             */
            if (be32_to_cpu(rhead->h_cycle) !=
                        be32_to_cpu(*(__be32 *)ptr)) {
-               if (*read_type == FULL_READ)
-                   return -1;
-               else if (be32_to_cpu(rhead->h_cycle) + 1 !=
-                       be32_to_cpu(*(__be32 *)ptr))
-                   return -1;
+               if ((*read_type == FULL_READ) ||
+                   (be32_to_cpu(rhead->h_cycle) + 1 !=
+                               be32_to_cpu(*(__be32 *)ptr))) {
+                       free(buf);
+                       return -1;
+               }
            }
        }
 
@@ -957,7 +901,10 @@ xlog_print_record(int                        fd,
        if (xlog_print_find_tid(be32_to_cpu(op_head->oh_tid),
                                op_head->oh_flags & XLOG_WAS_CONT_TRANS)) {
            printf(_("Left over region from split log item\n"));
+           /* Skip this leftover bit */
            ptr += be32_to_cpu(op_head->oh_len);
+           /* We've lost context; don't complain if next one looks bad too */
+           lost_context = 1;
            continue;
        }
 
@@ -973,8 +920,14 @@ xlog_print_record(int                        fd,
                                        &i, num_ops);
                        break;
                    }
+                   case XFS_LI_ICREATE: {
+                       skip = xlog_print_trans_icreate(&ptr,
+                                       be32_to_cpu(op_head->oh_len),
+                                       &i, num_ops);
+                       break;
+                   }
                    case XFS_LI_INODE: {
-                       skip = xlog_print_trans_inode(&ptr,
+                       skip = xlog_print_trans_inode(log, &ptr,
                                        be32_to_cpu(op_head->oh_len),
                                        &i, num_ops, continued);
                        break;
@@ -987,7 +940,8 @@ xlog_print_record(int                         fd,
                    }
                    case XFS_LI_EFI: {
                        skip = xlog_print_trans_efi(&ptr,
-                                       be32_to_cpu(op_head->oh_len));
+                                       be32_to_cpu(op_head->oh_len),
+                                       continued);
                        break;
                    }
                    case XFS_LI_EFD: {
@@ -995,6 +949,39 @@ xlog_print_record(int                        fd,
                                        be32_to_cpu(op_head->oh_len));
                        break;
                    }
+                   case XFS_LI_RUI: {
+                       skip = xlog_print_trans_rui(&ptr,
+                                       be32_to_cpu(op_head->oh_len),
+                                       continued);
+                       break;
+                   }
+                   case XFS_LI_RUD: {
+                       skip = xlog_print_trans_rud(&ptr,
+                                       be32_to_cpu(op_head->oh_len));
+                       break;
+                   }
+                   case XFS_LI_CUI: {
+                       skip = xlog_print_trans_cui(&ptr,
+                                       be32_to_cpu(op_head->oh_len),
+                                       continued);
+                       break;
+                   }
+                   case XFS_LI_CUD: {
+                       skip = xlog_print_trans_cud(&ptr,
+                                       be32_to_cpu(op_head->oh_len));
+                       break;
+                   }
+                   case XFS_LI_BUI: {
+                       skip = xlog_print_trans_bui(&ptr,
+                                       be32_to_cpu(op_head->oh_len),
+                                       continued);
+                       break;
+                   }
+                   case XFS_LI_BUD: {
+                       skip = xlog_print_trans_bud(&ptr,
+                                       be32_to_cpu(op_head->oh_len));
+                       break;
+                   }
                    case XFS_LI_QUOTAOFF: {
                        skip = xlog_print_trans_qoff(&ptr,
                                        be32_to_cpu(op_head->oh_len));
@@ -1006,14 +993,21 @@ xlog_print_record(int                      fd,
                        break;
                    }
                    default: {
-                       fprintf(stderr, _("%s: unknown log operation type (%x)\n"),
-                               progname, *(unsigned short *)ptr);
-                       if (print_exit) {
-                               free(buf);
-                               return BAD_HEADER;
+                       if (bad_hdr_warn && !lost_context) {
+                               fprintf(stderr,
+                       _("%s: unknown log operation type (%x)\n"),
+                                       progname, *(unsigned short *)ptr);
+                               if (print_exit) {
+                                       free(buf);
+                                       return BAD_HEADER;
+                               }
+                       } else {
+                               printf(
+                       _("Left over region from split log item\n"));
                        }
                        skip = 0;
                        ptr += be32_to_cpu(op_head->oh_len);
+                       lost_context = 0;
                    }
                } /* switch */
            } /* else */
@@ -1027,8 +1021,8 @@ xlog_print_record(int                       fd,
 }      /* xlog_print_record */
 
 
-int
-xlog_print_rec_head(xlog_rec_header_t *head, int *len)
+static int
+xlog_print_rec_head(xlog_rec_header_t *head, int *len, int bad_hdr_warn)
 {
     int i;
     char uub[64];
@@ -1041,9 +1035,10 @@ xlog_print_rec_head(xlog_rec_header_t *head, int *len)
        return ZEROED_LOG;
 
     if (be32_to_cpu(head->h_magicno) != XLOG_HEADER_MAGIC_NUM) {
-       printf(_("Header 0x%x wanted 0x%x\n"),
-               be32_to_cpu(head->h_magicno),
-               XLOG_HEADER_MAGIC_NUM);
+       if (bad_hdr_warn)
+               printf(_("Header 0x%x wanted 0x%x\n"),
+                       be32_to_cpu(head->h_magicno),
+                       XLOG_HEADER_MAGIC_NUM);
        return BAD_HEADER;
     }
 
@@ -1068,7 +1063,7 @@ xlog_print_rec_head(xlog_rec_header_t *head, int *len)
 
     if (print_overwrite) {
        printf(_("cycle num overwrites: "));
-       for (i=0; i< MIN(bbs, XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++)
+       for (i=0; i< min(bbs, XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++)
            printf("%d - 0x%x  ",
                    i,
                    be32_to_cpu(head->h_cycle_data[i]));
@@ -1100,7 +1095,7 @@ xlog_print_rec_head(xlog_rec_header_t *head, int *len)
     return(be32_to_cpu(head->h_num_logops));
 }      /* xlog_print_rec_head */
 
-void
+static void
 xlog_print_rec_xhead(xlog_rec_ext_header_t *head, int coverage)
 {
     int i;
@@ -1130,7 +1125,7 @@ print_xlog_bad_zeroed(xfs_daddr_t blkno)
 }      /* print_xlog_bad_zeroed */
 
 static void
-print_xlog_bad_header(xfs_daddr_t blkno, xfs_caddr_t buf)
+print_xlog_bad_header(xfs_daddr_t blkno, char *buf)
 {
        print_stars();
        printf(_("* ERROR: header cycle=%-11d block=%-21lld        *\n"),
@@ -1140,7 +1135,7 @@ print_xlog_bad_header(xfs_daddr_t blkno, xfs_caddr_t buf)
            xlog_exit("Bad log record header");
 }      /* print_xlog_bad_header */
 
-void
+static void
 print_xlog_bad_data(xfs_daddr_t blkno)
 {
        print_stars();
@@ -1191,10 +1186,12 @@ xlog_print_extended_headers(
        int                     num_hdrs;
        int                     num_required;
        char                    xhbuf[XLOG_HEADER_SIZE];
-       xlog_rec_ext_header_t   *x;
+       xlog_rec_ext_header_t   *xhdr;
 
        num_required = howmany(len, XLOG_HEADER_CYCLE_SIZE);
        num_hdrs = be32_to_cpu(hdr->h_size) / XLOG_HEADER_CYCLE_SIZE;
+       if (be32_to_cpu(hdr->h_size) % XLOG_HEADER_CYCLE_SIZE)
+               num_hdrs++;
 
        if (num_required > num_hdrs) {
            print_xlog_bad_reqd_hdrs((*blkno)-1, num_required, num_hdrs);
@@ -1214,7 +1211,7 @@ xlog_print_extended_headers(
        *ret_num_hdrs = num_hdrs;
 
        /* don't include 1st header */
-       for (i = 1, x = *ret_xhdrs; i < num_hdrs; i++, (*blkno)++, x++) {
+       for (i = 1, xhdr = *ret_xhdrs; i < num_hdrs; i++, (*blkno)++, xhdr++) {
            /* read one extra header blk */
            if (read(fd, xhbuf, 512) == 0) {
                printf(_("%s: physical end of log\n"), progname);
@@ -1244,9 +1241,9 @@ xlog_print_extended_headers(
             * will look asymmetric with the 1 hdr normal case
             * which does endian coversion on access.
             */
-           x->xh_cycle = ((xlog_rec_ext_header_t*)xhbuf)->xh_cycle;
+           xhdr->xh_cycle = ((xlog_rec_ext_header_t*)xhbuf)->xh_cycle;
            for (j = 0; j < XLOG_HEADER_CYCLE_SIZE / BBSIZE; j++) {
-               x->xh_cycle_data[j] =
+               xhdr->xh_cycle_data[j] =
                    ((xlog_rec_ext_header_t*)xhbuf)->xh_cycle_data[j];
            }
        }
@@ -1268,9 +1265,10 @@ void xfs_log_print(struct xlog  *log,
     xfs_daddr_t                        block_end = 0, block_start, blkno, error;
     xfs_daddr_t                        zeroed_blkno = 0, cleared_blkno = 0;
     int                                read_type = FULL_READ;
-    xfs_caddr_t                        partial_buf;
-    int                        zeroed = 0;
-    int                        cleared = 0;
+    char                       *partial_buf;
+    int                                zeroed = 0;
+    int                                cleared = 0;
+    int                                first_hdr_found = 0;
 
     logBBsize = log->l_logBBsize;
 
@@ -1302,7 +1300,7 @@ void xfs_log_print(struct xlog  *log,
            blkno++;
            goto loop;
        }
-       num_ops = xlog_print_rec_head(hdr, &len);
+       num_ops = xlog_print_rec_head(hdr, &len, first_hdr_found);
        blkno++;
 
        if (zeroed && num_ops != ZEROED_LOG) {
@@ -1328,7 +1326,10 @@ void xfs_log_print(struct xlog  *log,
                    cleared_blkno = blkno-1;
                cleared++;
            } else {
-               print_xlog_bad_header(blkno-1, hbuf);
+               if (!first_hdr_found)
+                       block_start = blkno;
+               else
+                       print_xlog_bad_header(blkno-1, hbuf);
            }
 
            goto loop;
@@ -1339,7 +1340,9 @@ void xfs_log_print(struct xlog  *log,
                break;
        }
 
-       error = xlog_print_record(fd, num_ops, len, &read_type, &partial_buf, hdr, xhdrs);
+       error = xlog_print_record(log, fd, num_ops, len, &read_type, &partial_buf,
+                                 hdr, xhdrs, first_hdr_found);
+       first_hdr_found++;
        switch (error) {
            case 0: {
                blkno += BTOBB(len);
@@ -1415,7 +1418,7 @@ loop:
                blkno++;
                goto loop2;
            }
-           num_ops = xlog_print_rec_head(hdr, &len);
+           num_ops = xlog_print_rec_head(hdr, &len, first_hdr_found);
            blkno++;
 
            if (num_ops == ZEROED_LOG ||
@@ -1438,13 +1441,9 @@ loop:
            }
 
 partial_log_read:
-           error= xlog_print_record(fd,
-                                   num_ops,
-                                   len,
-                                   &read_type,
-                                   &partial_buf,
-                                   (xlog_rec_header_t *)hbuf,
-                                   xhdrs);
+           error= xlog_print_record(log, fd, num_ops, len, &read_type,
+                                   &partial_buf, (xlog_rec_header_t *)hbuf,
+                                   xhdrs, first_hdr_found);
            if (read_type != FULL_READ)
                len -= read_type;
            read_type = FULL_READ;
@@ -1468,94 +1467,32 @@ end:
 }
 
 /*
- * if necessary, convert an xfs_inode_log_format struct from 32bit or 64 bit versions
- * (which can have different field alignments) to the native version
+ * if necessary, convert an xfs_inode_log_format struct from the old 32bit version
+ * (which can have different field alignments) to the native 64 bit version
  */
-xfs_inode_log_format_t *
-xfs_inode_item_format_convert(char *src_buf, uint len, xfs_inode_log_format_t *in_f)
+struct xfs_inode_log_format *
+xfs_inode_item_format_convert(char *src_buf, uint len, struct xfs_inode_log_format *in_f)
 {
+       struct xfs_inode_log_format_32  *in_f32;
+
        /* if we have native format then just return buf without copying data */
-       if (len == sizeof(xfs_inode_log_format_t)) {
-               return (xfs_inode_log_format_t *)src_buf;
+       if (len == sizeof(struct xfs_inode_log_format)) {
+               return (struct xfs_inode_log_format *)src_buf;
        }
 
-       if (len == sizeof(xfs_inode_log_format_32_t)) {
-               xfs_inode_log_format_32_t *in_f32;
-
-               in_f32 = (xfs_inode_log_format_32_t *)src_buf;
-               in_f->ilf_type = in_f32->ilf_type;
-               in_f->ilf_size = in_f32->ilf_size;
-               in_f->ilf_fields = in_f32->ilf_fields;
-               in_f->ilf_asize = in_f32->ilf_asize;
-               in_f->ilf_dsize = in_f32->ilf_dsize;
-               in_f->ilf_ino = in_f32->ilf_ino;
-               /* copy biggest */
-               memcpy(&in_f->ilf_u.ilfu_uuid, &in_f32->ilf_u.ilfu_uuid, sizeof(uuid_t));
-               in_f->ilf_blkno = in_f32->ilf_blkno;
-               in_f->ilf_len = in_f32->ilf_len;
-               in_f->ilf_boffset = in_f32->ilf_boffset;
-       } else {
-               xfs_inode_log_format_64_t *in_f64;
-
-               ASSERT(len == sizeof(xfs_inode_log_format_64_t));
-               in_f64 = (xfs_inode_log_format_64_t *)src_buf;
-               in_f->ilf_type = in_f64->ilf_type;
-               in_f->ilf_size = in_f64->ilf_size;
-               in_f->ilf_fields = in_f64->ilf_fields;
-               in_f->ilf_asize = in_f64->ilf_asize;
-               in_f->ilf_dsize = in_f64->ilf_dsize;
-               in_f->ilf_ino = in_f64->ilf_ino;
-               /* copy biggest */
-               memcpy(&in_f->ilf_u.ilfu_uuid, &in_f64->ilf_u.ilfu_uuid, sizeof(uuid_t));
-               in_f->ilf_blkno = in_f64->ilf_blkno;
-               in_f->ilf_len = in_f64->ilf_len;
-               in_f->ilf_boffset = in_f64->ilf_boffset;
-       }
-       return in_f;
-}
+       in_f32 = (struct xfs_inode_log_format_32 *)src_buf;
+       in_f->ilf_type = in_f32->ilf_type;
+       in_f->ilf_size = in_f32->ilf_size;
+       in_f->ilf_fields = in_f32->ilf_fields;
+       in_f->ilf_asize = in_f32->ilf_asize;
+       in_f->ilf_dsize = in_f32->ilf_dsize;
+       in_f->ilf_ino = in_f32->ilf_ino;
+       /* copy biggest field of ilf_u */
+       memcpy(&in_f->ilf_u.__pad, &in_f32->ilf_u.__pad,
+                                       sizeof(in_f->ilf_u.__pad));
+       in_f->ilf_blkno = in_f32->ilf_blkno;
+       in_f->ilf_len = in_f32->ilf_len;
+       in_f->ilf_boffset = in_f32->ilf_boffset;
 
-int
-xfs_efi_copy_format(char *buf, uint len, xfs_efi_log_format_t *dst_efi_fmt)
-{
-        uint i;
-       uint nextents = ((xfs_efi_log_format_t *)buf)->efi_nextents;
-        uint dst_len = sizeof(xfs_efi_log_format_t) + (nextents - 1) * sizeof(xfs_extent_t);
-        uint len32 = sizeof(xfs_efi_log_format_32_t) + (nextents - 1) * sizeof(xfs_extent_32_t);
-        uint len64 = sizeof(xfs_efi_log_format_64_t) + (nextents - 1) * sizeof(xfs_extent_64_t);
-
-        if (len == dst_len) {
-                memcpy((char *)dst_efi_fmt, buf, len);
-                return 0;
-        } else if (len == len32) {
-                xfs_efi_log_format_32_t *src_efi_fmt_32 = (xfs_efi_log_format_32_t *)buf;
-
-                dst_efi_fmt->efi_type     = src_efi_fmt_32->efi_type;
-                dst_efi_fmt->efi_size     = src_efi_fmt_32->efi_size;
-                dst_efi_fmt->efi_nextents = src_efi_fmt_32->efi_nextents;
-                dst_efi_fmt->efi_id       = src_efi_fmt_32->efi_id;
-                for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
-                        dst_efi_fmt->efi_extents[i].ext_start =
-                                src_efi_fmt_32->efi_extents[i].ext_start;
-                        dst_efi_fmt->efi_extents[i].ext_len =
-                                src_efi_fmt_32->efi_extents[i].ext_len;
-                }
-                return 0;
-        } else if (len == len64) {
-                xfs_efi_log_format_64_t *src_efi_fmt_64 = (xfs_efi_log_format_64_t *)buf;
-
-                dst_efi_fmt->efi_type     = src_efi_fmt_64->efi_type;
-                dst_efi_fmt->efi_size     = src_efi_fmt_64->efi_size;
-                dst_efi_fmt->efi_nextents = src_efi_fmt_64->efi_nextents;
-                dst_efi_fmt->efi_id       = src_efi_fmt_64->efi_id;
-                for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
-                        dst_efi_fmt->efi_extents[i].ext_start =
-                                src_efi_fmt_64->efi_extents[i].ext_start;
-                        dst_efi_fmt->efi_extents[i].ext_len =
-                                src_efi_fmt_64->efi_extents[i].ext_len;
-                }
-                return 0;
-        }
-       fprintf(stderr, _("%s: bad size of efi format: %u; expected %u or %u; nextents = %u\n"),
-               progname, len, len32, len64, nextents);
-        return 1;
+       return in_f;
 }