]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blobdiff - logprint/log_misc.c
xfsprogs: Release v6.8.0
[thirdparty/xfsprogs-dev.git] / logprint / log_misc.c
index 55f7d279b8379f9392fb6e2ddcbbf42f75508636..836156e0d58628564be10399080cd73b04bd2ead 100644 (file)
@@ -1,37 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright (c) 2000-2001 Silicon Graphics, Inc.  All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 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.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like.  Any license provided herein, whether implied or
- * otherwise, applies only to this software file.  Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA  94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
  */
+#include "libxfs.h"
+#include "libxlog.h"
 
 #include "logprint.h"
 
+#define CLEARED_BLKS   (-5)
 #define ZEROED_LOG     (-4)
 #define FULL_READ      (-3)
 #define PARTIAL_READ   (-2)
 #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",
-};
 
 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 = 0;
+static xlog_split_item_t *split_list = NULL;
 
 void
 print_xlog_op_line(void)
@@ -99,6 +33,13 @@ print_xlog_op_line(void)
           "--------------------------------------\n");
 }      /* print_xlog_op_line */
 
+static void
+print_xlog_xhdr_line(void)
+{
+    printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
+          "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
+}      /* print_xlog_xhdr_line */
+
 void
 print_xlog_record_line(void)
 {
@@ -111,7 +52,43 @@ print_stars(void)
 {
     printf("***********************************"
           "***********************************\n");
-}      /* print_xlog_record_line */
+}      /* print_stars */
+
+void
+print_hex_dump(char *ptr, int len) {
+       int i = 0;
+
+       for (i = 0; i < len; i++) {
+               if (i % 16 == 0)
+                       printf("%08x ", i);
+
+               printf("%02x", ptr[i]);
+
+               if ((i+1)%16 == 0)
+                       printf("\n");
+               else if ((i+1)%2 == 0)
+                       printf(" ");
+       }
+       printf("\n");
+}
+
+bool
+is_printable(char *ptr, int len) {
+       int i = 0;
+
+       for (i = 0; i < len; i++)
+               if (!isprint(ptr[i]) )
+                       return false;
+       return true;
+}
+
+void
+print_or_dump(char *ptr, int len) {
+       if (is_printable(ptr, len))
+               printf("%.*s\n", len, ptr);
+       else
+               print_hex_dump(ptr, len);
+}
 
 /*
  * Given a pointer to a data segment, print out the data as if it were
@@ -120,23 +97,23 @@ print_stars(void)
 void
 xlog_print_op_header(xlog_op_header_t  *op_head,
                     int                i,
-                    xfs_caddr_t        *ptr)
+                    char               **ptr)
 {
     xlog_op_header_t hbuf;
 
     /*
-     * bcopy because on 64/n32, partial reads can cause the op_head
+     * memmove because on 64/n32, partial reads can cause the op_head
      * pointer to come in pointing to an odd-numbered byte
      */
-    bcopy(op_head, &hbuf, sizeof(xlog_op_header_t));
+    memmove(&hbuf, op_head, sizeof(xlog_op_header_t));
     op_head = &hbuf;
     *ptr += sizeof(xlog_op_header_t);
-    printf("Oper (%d): tid: %x  len: %d  clientid: %s  ", i,
-           INT_GET(op_head->oh_tid, ARCH_CONVERT),
-           INT_GET(op_head->oh_len, ARCH_CONVERT),
+    printf(_("Oper (%d): tid: %x  len: %d  clientid: %s  "), i,
+           be32_to_cpu(op_head->oh_tid),
+           be32_to_cpu(op_head->oh_len),
            (op_head->oh_clientid == XFS_TRANSACTION ? "TRANS" :
            (op_head->oh_clientid == XFS_LOG ? "LOG" : "ERROR")));
-    printf("flags: ");
+    printf(_("flags: "));
     if (op_head->oh_flags) {
        if (op_head->oh_flags & XLOG_START_TRANS)
            printf("START ");
@@ -151,30 +128,30 @@ xlog_print_op_header(xlog_op_header_t     *op_head,
        if (op_head->oh_flags & XLOG_END_TRANS)
            printf("END ");
     } else {
-       printf("none");
+       printf(_("none"));
     }
     printf("\n");
 }      /* 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 = 0;
+    item->si_prev = NULL;
     if (split_list)
        split_list->si_prev = item;
     split_list   = item;
 }      /* 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;
@@ -186,7 +163,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;
     }
@@ -208,17 +185,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 INT_GET soon */
+    magic = *(uint32_t *)cptr; /* XXX be32_to_cpu soon */
 
     if (len >= 4) {
 #if __BYTE_ORDER == __LITTLE_ENDIAN
@@ -230,78 +207,61 @@ xlog_print_trans_header(xfs_caddr_t *ptr, int len)
 #endif
     }
     if (len != sizeof(xfs_trans_header_t)) {
-       printf("   Not enough data to decode further\n");
+       printf(_("   Not enough data to decode further\n"));
        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_buf_log_format_v1_t *old_f;
-    xfs_agi_t           *agi;
-    xfs_agf_t           *agf;
-    xfs_disk_dquot_t    *dq;
-    xlog_op_header_t    *head = 0;
+    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;
-    long long           x, y;
+    unsigned short      flags;
 
     /*
-     * bcopy to ensure 8-byte alignment for the long longs in
+     * memmove to ensure 8-byte alignment for the long longs in
      * buf_log_format_t structure
      */
-    bcopy(*ptr, &lbuf, MIN(sizeof(xfs_buf_log_format_t), len));
+    memmove(&lbuf, *ptr, min(sizeof(xfs_buf_log_format_t), len));
     f = &lbuf;
     *ptr += len;
 
-    if (f->blf_type == XFS_LI_BUF) {
-       blkno = f->blf_blkno;
-       size = f->blf_size;
-       blen = f->blf_len;
-       map_size = f->blf_map_size;
-       struct_size = sizeof(xfs_buf_log_format_t);
-    } else {
-       old_f = (xfs_buf_log_format_v1_t*)f;
-       blkno = old_f->blf_blkno;
-       size = old_f->blf_size;
-       blen = old_f->blf_len;
-       map_size = old_f->blf_map_size;
-       struct_size = sizeof(xfs_buf_log_format_v1_t);
-    }
-    switch (f->blf_type)  {
-    case XFS_LI_BUF:
-       printf("BUF:  ");
-       break;
-    case XFS_LI_6_1_BUF:
-       printf("6.1 BUF:  ");
-       break;
-    case XFS_LI_5_3_BUF:
-       printf("5.3 BUF:  ");
-       break;
-    default:
-       printf("UNKNOWN BUF:  ");
-       break;
-    }
+    ASSERT(f->blf_type == XFS_LI_BUF);
+    printf("BUF:  ");
+    blkno = f->blf_blkno;
+    size = f->blf_size;
+    blen = f->blf_len;
+    map_size = f->blf_map_size;
+    flags = f->blf_flags;
+
+    /*
+     * size of the format header is dependent on the size of the bitmap, not
+     * the size of the in-memory structure. Hence the slightly obtuse
+     * calculation.
+     */
+    struct_size = offsetof(struct xfs_buf_log_format, blf_map_size) + map_size;
+
     if (len >= struct_size) {
        ASSERT((len - sizeof(struct_size)) % sizeof(int) == 0);
-       printf("#regs: %d   start blkno: %lld (0x%llx)  len: %d  bmap size: %d\n",
-              size, (long long)blkno, (unsigned long long)blkno, blen, map_size);
+       printf(_("#regs: %d   start blkno: %lld (0x%llx)  len: %d  bmap size: %d  flags: 0x%x\n"),
+              size, (long long)blkno, (unsigned long long)blkno, blen, map_size, flags);
        if (blkno == 0)
            super_block = 1;
     } else {
        ASSERT(len >= 4);       /* must have at least 4 bytes if != 0 */
-       printf("#regs: %d   Not printing rest of data\n", f->blf_size);
+       printf(_("#regs: %d   Not printing rest of data\n"), f->blf_size);
        return size;
     }
     num = size-1;
@@ -318,152 +278,174 @@ xlog_print_trans_buffer(xfs_caddr_t *ptr, int len, int *i, int num_ops)
        head = (xlog_op_header_t *)*ptr;
        xlog_print_op_header(head, *i, ptr);
        if (super_block) {
-               printf("SUPER BLOCK Buffer: ");
-               if (INT_GET(head->oh_len, ARCH_CONVERT) < 4*8) {
-                       printf("Out of space\n");
+               printf(_("SUPER BLOCK Buffer: "));
+               if (be32_to_cpu(head->oh_len) < 4*8) {
+                       printf(_("Out of space\n"));
                } else {
+                       __be64           a, b;
+
                        printf("\n");
                        /*
-                        * bcopy because *ptr may not be 8-byte aligned
+                        * memmove because *ptr may not be 8-byte aligned
                         */
-                       bcopy(*ptr, &x, sizeof(long long));
-                       bcopy(*ptr+8, &y, sizeof(long long));
-                       printf("icount: %lld  ifree: %lld  ",
-                               INT_GET(x, ARCH_CONVERT),
-                               INT_GET(y, ARCH_CONVERT));
-                       bcopy(*ptr+16, &x, sizeof(long long));
-                       bcopy(*ptr+24, &y, sizeof(long long));
-                       printf("fdblks: %lld  frext: %lld\n",
-                               INT_GET(x, ARCH_CONVERT),
-                               INT_GET(y, ARCH_CONVERT));
+                       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 (INT_GET(*(uint *)(*ptr), ARCH_CONVERT) == XFS_AGI_MAGIC) {
-               agi = (xfs_agi_t *)(*ptr);
-               printf("AGI Buffer: XAGI  ");
-               if (INT_GET(head->oh_len, ARCH_CONVERT) <
-                   sizeof(xfs_agi_t) -
-                   XFS_AGI_UNLINKED_BUCKETS*sizeof(xfs_agino_t)) {
-                       printf("out of space\n");
+       } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_AGI_MAGIC) {
+               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  "));
+               /*
+                * 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 {
                        printf("\n");
-                       printf("ver: %d  ",
-                               INT_GET(agi->agi_versionnum, ARCH_CONVERT));
-                       printf("seq#: %d  len: %d  cnt: %d  root: %d\n",
-                               INT_GET(agi->agi_seqno, ARCH_CONVERT),
-                               INT_GET(agi->agi_length, ARCH_CONVERT),
-                               INT_GET(agi->agi_count, ARCH_CONVERT),
-                               INT_GET(agi->agi_root, ARCH_CONVERT));
-                       printf("level: %d  free#: 0x%x  newino: 0x%x\n",
-                               INT_GET(agi->agi_level, ARCH_CONVERT),
-                               INT_GET(agi->agi_freecount, ARCH_CONVERT),
-                               INT_GET(agi->agi_newino, ARCH_CONVERT));
-                       if (INT_GET(head->oh_len, ARCH_CONVERT) == 128) {
+                       printf(_("ver: %d  "),
+                               be32_to_cpu(agi->agi_versionnum));
+                       printf(_("seq#: %d  len: %d  cnt: %d  root: %d\n"),
+                               be32_to_cpu(agi->agi_seqno),
+                               be32_to_cpu(agi->agi_length),
+                               be32_to_cpu(agi->agi_count),
+                               be32_to_cpu(agi->agi_root));
+                       printf(_("level: %d  free#: 0x%x  newino: 0x%x\n"),
+                               be32_to_cpu(agi->agi_level),
+                               be32_to_cpu(agi->agi_freecount),
+                               be32_to_cpu(agi->agi_newino));
+                       if (be32_to_cpu(head->oh_len) == 128) {
                                buckets = 17;
-                       } else if (INT_GET(head->oh_len, ARCH_CONVERT) == 256) {
+                       } else if (be32_to_cpu(head->oh_len) == 256) {
                                buckets = 32 + 17;
                        } else {
                                if (head->oh_flags & XLOG_CONTINUE_TRANS) {
-                                       printf("AGI unlinked data skipped ");
-                                       printf("(CONTINUE set, no space)\n");
+                                       printf(_("AGI unlinked data skipped "));
+                                       printf(_("(CONTINUE set, no space)\n"));
                                        continue;
                                }
                                buckets = XFS_AGI_UNLINKED_BUCKETS;
                        }
                        for (bucket = 0; bucket < buckets;) {
-                               printf("bucket[%d - %d]: ", bucket, bucket+3);
+                               printf(_("bucket[%d - %d]: "), bucket, bucket+3);
                                for (col = 0; col < 4; col++, bucket++) {
                                        if (bucket < buckets) {
                                                printf("0x%x ",
-                       INT_GET(agi->agi_unlinked[bucket], ARCH_CONVERT));
+                       be32_to_cpu(agi->agi_unlinked[bucket]));
                                        }
                                }
                                printf("\n");
                        }
                }
-       } else if (INT_GET(*(uint *)(*ptr), ARCH_CONVERT) == XFS_AGF_MAGIC) {
-               agf = (xfs_agf_t *)(*ptr);
-               printf("AGF Buffer: XAGF  ");
-               if (INT_GET(head->oh_len, ARCH_CONVERT) < sizeof(xfs_agf_t)) {
-                       printf("Out of space\n");
+       } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_AGF_MAGIC) {
+               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  "));
+               /*
+                * 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");
-                       printf("ver: %d  seq#: %d  len: %d  \n",
-                               INT_GET(agf->agf_versionnum, ARCH_CONVERT),
-                               INT_GET(agf->agf_seqno, ARCH_CONVERT),
-                               INT_GET(agf->agf_length, ARCH_CONVERT));
-                       printf("root BNO: %d  CNT: %d\n",
-                               INT_GET(agf->agf_roots[XFS_BTNUM_BNOi],
-                                       ARCH_CONVERT),
-                               INT_GET(agf->agf_roots[XFS_BTNUM_CNTi],
-                                       ARCH_CONVERT));
-                       printf("level BNO: %d  CNT: %d\n",
-                               INT_GET(agf->agf_levels[XFS_BTNUM_BNOi],
-                                       ARCH_CONVERT),
-                               INT_GET(agf->agf_levels[XFS_BTNUM_CNTi],
-                                       ARCH_CONVERT));
-                       printf("1st: %d  last: %d  cnt: %d  "
-                              "freeblks: %d  longest: %d\n",
-                               INT_GET(agf->agf_flfirst, ARCH_CONVERT),
-                               INT_GET(agf->agf_fllast, ARCH_CONVERT),
-                               INT_GET(agf->agf_flcount, ARCH_CONVERT),
-                               INT_GET(agf->agf_freeblks, ARCH_CONVERT),
-                               INT_GET(agf->agf_longest, ARCH_CONVERT));
+                       printf(_("ver: %d  seq#: %d  len: %d  \n"),
+                               be32_to_cpu(agf->agf_versionnum),
+                               be32_to_cpu(agf->agf_seqno),
+                               be32_to_cpu(agf->agf_length));
+                       printf(_("root BNO: %d  CNT: %d\n"),
+                               be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNOi]),
+                               be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNTi]));
+                       printf(_("level BNO: %d  CNT: %d\n"),
+                               be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]),
+                               be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]));
+                       printf(_("1st: %d  last: %d  cnt: %d  "
+                              "freeblks: %d  longest: %d\n"),
+                               be32_to_cpu(agf->agf_flfirst),
+                               be32_to_cpu(agf->agf_fllast),
+                               be32_to_cpu(agf->agf_flcount),
+                               be32_to_cpu(agf->agf_freeblks),
+                               be32_to_cpu(agf->agf_longest));
                }
-       } else if (INT_GET(*(uint *)(*ptr), ARCH_CONVERT) == XFS_DQUOT_MAGIC) {
-               dq = (xfs_disk_dquot_t *)(*ptr);
-               printf("DQUOT Buffer: DQ  ");
-               if (INT_GET(head->oh_len, ARCH_CONVERT) <
-                               sizeof(xfs_disk_dquot_t)) {
-                       printf("Out of space\n");
+       } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_DQUOT_MAGIC) {
+               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(struct xfs_disk_dquot)) {
+                       printf(_("Out of space\n"));
                }
                else {
                        printf("\n");
-                       printf("ver: %d  flags: 0x%x  id: %d  \n",
-                               INT_GET(dq->d_version, ARCH_CONVERT),
-                               INT_GET(dq->d_flags, ARCH_CONVERT),
-                               INT_GET(dq->d_id, ARCH_CONVERT));
-                       printf("blk limits  hard: %llu  soft: %llu\n",
-                               (unsigned long long)
-                               INT_GET(dq->d_blk_hardlimit, ARCH_CONVERT),
-                               (unsigned long long)
-                               INT_GET(dq->d_blk_softlimit, ARCH_CONVERT));
-                       printf("blk  count: %llu  warns: %d  timer: %d\n",
-                               (unsigned long long)
-                               INT_GET(dq->d_bcount, ARCH_CONVERT),
-                               INT_GET(dq->d_bwarns, ARCH_CONVERT),
-                               INT_GET(dq->d_btimer, ARCH_CONVERT));
-                       printf("ino limits  hard: %llu  soft: %llu\n",
-                               (unsigned long long)
-                               INT_GET(dq->d_ino_hardlimit, ARCH_CONVERT),
-                               (unsigned long long)
-                               INT_GET(dq->d_ino_softlimit, ARCH_CONVERT));
-                       printf("ino  count: %llu  warns: %d  timer: %d\n",
-                               (unsigned long long)
-                               INT_GET(dq->d_icount, ARCH_CONVERT),
-                               INT_GET(dq->d_iwarns, ARCH_CONVERT),
-                               INT_GET(dq->d_itimer, ARCH_CONVERT));
+                       printf(_("ver: %d  flags: 0x%x  id: %d  \n"),
+                               dq->d_version, dq->d_type,
+                               be32_to_cpu(dq->d_id));
+                       printf(_("blk limits  hard: %llu  soft: %llu\n"),
+                              (unsigned long long)
+                                      be64_to_cpu(dq->d_blk_hardlimit),
+                              (unsigned long long)
+                                      be64_to_cpu(dq->d_blk_softlimit));
+                       printf(_("blk  count: %llu  warns: %d  timer: %d\n"),
+                              (unsigned long long) be64_to_cpu(dq->d_bcount),
+                              (int) be16_to_cpu(dq->d_bwarns),
+                               be32_to_cpu(dq->d_btimer));
+                       printf(_("ino limits  hard: %llu  soft: %llu\n"),
+                              (unsigned long long)
+                                      be64_to_cpu(dq->d_ino_hardlimit),
+                              (unsigned long long)
+                                      be64_to_cpu(dq->d_ino_softlimit));
+                       printf(_("ino  count: %llu  warns: %d  timer: %d\n"),
+                              (unsigned long long) be64_to_cpu(dq->d_icount),
+                              (int) be16_to_cpu(dq->d_iwarns),
+                               be32_to_cpu(dq->d_itimer));
                }
        } else {
-               printf("BUF DATA\n");
+               printf(_("BUF DATA\n"));
                if (print_data) {
                        uint *dp  = (uint *)*ptr;
-                       int  nums = INT_GET(head->oh_len, ARCH_CONVERT) >> 2;
-                       int  i = 0;
+                       int  nums = be32_to_cpu(head->oh_len) >> 2;
+                       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");
                }
        }
-       *ptr += INT_GET(head->oh_len, ARCH_CONVERT);
+       *ptr += be32_to_cpu(head->oh_len);
     }
     if (head && head->oh_flags & XLOG_CONTINUE_TRANS)
        skip++;
@@ -471,349 +453,278 @@ 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_extent_t        *ex;
-    int                         i;
-    xfs_efd_log_format_t lbuf;
-
-    /*
-     * bcopy to ensure 8-byte alignment for the long longs in
-     * xfs_efd_log_format_t structure
-     */
-    bcopy(*ptr, &lbuf, sizeof(xfs_efd_log_format_t));
-    f = &lbuf;
-    *ptr += len;
-    if (len >= sizeof(xfs_efd_log_format_t)) {
-       printf("EFD:  #regs: %d    num_extents: %d  id: 0x%llx\n",
-              f->efd_size, f->efd_nextents, (unsigned long long)f->efd_efi_id);
-       ex = f->efd_extents;
-       for (i=0; i< f->efd_size; 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");
-       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 len)
-{
-    xfs_efi_log_format_t *f;
-    xfs_extent_t        *ex;
-    int                         i;
-    xfs_efi_log_format_t lbuf;
-
-    /*
-     * bcopy to ensure 8-byte alignment for the long longs in
-     * xfs_efi_log_format_t structure
-     */
-    bcopy(*ptr, &lbuf, sizeof(xfs_efi_log_format_t));
-    f = &lbuf;
-    *ptr += len;
-    if (len >= sizeof(xfs_efi_log_format_t)) {
-       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_size; 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");
-       return 0;
-    } else {
-       printf("EFI: Not enough data to decode further\n");
-       return 1;
-    }
-}      /* 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;
 
-    bcopy(*ptr, &lbuf, sizeof(xfs_qoff_logformat_t));
+    memmove(&lbuf, *ptr, min(sizeof(xfs_qoff_logformat_t), len));
     f = &lbuf;
     *ptr += len;
     if (len >= sizeof(xfs_qoff_logformat_t)) {
-       printf("QOFF:  #regs: %d    flags: 0x%x\n", f->qf_size, f->qf_flags);
+       printf(_("QOFF:  #regs: %d    flags: 0x%x\n"), f->qf_size, f->qf_flags);
        return 0;
     } else {
-       printf("QOFF: Not enough data to decode further\n");
+       printf(_("QOFF: Not enough data to decode further\n"));
        return 1;
     }
 }      /* xlog_print_trans_qoff */
 
 
-void
-xlog_print_trans_inode_core(xfs_dinode_core_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",
+    xfs_extnum_t               nextents;
+
+    printf(_("INODE CORE\n"));
+    printf(_("magic 0x%hx mode 0%ho version %d format %d\n"),
           ip->di_magic, ip->di_mode, (int)ip->di_version,
           (int)ip->di_format);
-    printf("nlink %hd uid %d gid %d\n",
+    printf(_("nlink %" PRIu32 " uid %d gid %d\n"),
           ip->di_nlink, ip->di_uid, ip->di_gid);
-    printf("atime 0x%x mtime 0x%x ctime 0x%x\n",
-          ip->di_atime.t_sec, ip->di_mtime.t_sec, ip->di_ctime.t_sec);
-    printf("size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%x\n",
+    printf(_("atime 0x%llx mtime 0x%llx ctime 0x%llx\n"),
+               xlog_extract_dinode_ts(ip->di_atime),
+               xlog_extract_dinode_ts(ip->di_mtime),
+               xlog_extract_dinode_ts(ip->di_ctime));
+
+    if (ip->di_flags2 & XFS_DIFLAG2_NREXT64)
+       nextents = ip->di_big_nextents;
+    else
+       nextents = ip->di_nextents;
+    printf(_("size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%llx\n"),
           (unsigned long long)ip->di_size, (unsigned long long)ip->di_nblocks,
-          ip->di_extsize, ip->di_nextents);
-    printf("naextents 0x%x forkoff %d dmevmask 0x%x dmstate 0x%hx\n",
-          ip->di_anextents, (int)ip->di_forkoff, ip->di_dmevmask,
-          ip->di_dmstate);
-    printf("flags 0x%x gen 0x%x\n",
+          ip->di_extsize, (unsigned long long)nextents);
+
+    if (ip->di_flags2 & XFS_DIFLAG2_NREXT64)
+       nextents = ip->di_big_anextents;
+    else
+       nextents = ip->di_anextents;
+    printf(_("naextents 0x%llx forkoff %d dmevmask 0x%x dmstate 0x%hx\n"),
+          (unsigned long long)nextents, (int)ip->di_forkoff, ip->di_dmevmask, 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_dir_sf(xfs_dir_shortform_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;
        char            namebuf[257];
-       xfs_dir_sf_entry_t      *sfep;
+       xfs_dir2_sf_entry_t     *sfep;
 
-       /* XXX need to determine whether this is v1 or v2, then
-          print appropriate structure */
-
-       printf("SHORTFORM DIRECTORY size %d\n",
+       printf(_("SHORTFORM DIRECTORY size %d\n"),
                size);
        /* bail out for now */
 
        return;
 
-       printf("SHORTFORM DIRECTORY size %d count %d\n",
-              size, sfp->hdr.count);
-       bcopy(&(sfp->hdr.parent), &ino, sizeof(ino));
-       printf(".. ino 0x%llx\n", (unsigned long long)INT_GET(ino, ARCH_CONVERT));
+       printf(_("SHORTFORM DIRECTORY size %d count %d\n"),
+              size, sfp->count);
+       memmove(&pino, &(sfp->parent), sizeof(pino));
+       printf(_(".. ino 0x%llx\n"), (unsigned long long) be64_to_cpu(pino));
 
-       count = (uint)(sfp->hdr.count);
-       sfep = &(sfp->list[0]);
+       count = sfp->count;
+       sfep = xfs_dir2_sf_firstentry(sfp);
        for (i = 0; i < count; i++) {
-               bcopy(&(sfep->inumber), &ino, sizeof(ino));
-               bcopy((sfep->name), namebuf, sfep->namelen);
+               ino = libxfs_dir2_sf_get_ino(log->l_mp, sfp, sfep);
+               memmove(namebuf, (sfep->name), sfep->namelen);
                namebuf[sfep->namelen] = '\0';
-               printf("%s ino 0x%llx namelen %d\n",
+               printf(_("%s ino 0x%llx namelen %d\n"),
                       namebuf, (unsigned long long)ino, sfep->namelen);
-               sfep = XFS_DIR_SF_NEXTENTRY(sfep);
+               sfep = libxfs_dir2_sf_nextentry(log->l_mp, sfp, sfep);
        }
 }
 
-int
-xlog_print_trans_inode(xfs_caddr_t *ptr, int len, int *i, int num_ops)
+static int
+xlog_print_trans_inode(
+       struct xlog             *log,
+       char                    **ptr,
+       int                     len,
+       int                     *i,
+       int                     num_ops,
+       int                     continued)
 {
-    xfs_inode_log_format_t *f;
-    xfs_inode_log_format_t_v1 *old_f;
-    xfs_dinode_core_t     dino;
-    xlog_op_header_t      *op_head;
-    int                           version;
-    xfs_inode_log_format_t lbuf = {0};
-    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
      *
-     * bcopy to ensure 8-byte alignment for the long longs in
-     * xfs_inode_log_format_t structure
+     * memmove to ensure 8-byte alignment for the long longs in
+     * struct xfs_inode_log_format structure
      *
-     * len can be smaller than xfs_inode_log_format_t sometimes... (?)
+     * len can be smaller than struct xfs_inode_log_format
+     * if format data is split over operations
      */
-    bcopy(*ptr, &lbuf, MIN(sizeof(xfs_inode_log_format_t), len));
-    version = lbuf.ilf_type;
-    f = &lbuf;
+    memmove(&src_lbuf, *ptr, min(sizeof(src_lbuf), len));
     (*i)++;                                    /* bump index */
     *ptr += len;
-    if (version == XFS_LI_5_3_INODE) {
-       old_f = (xfs_inode_log_format_t_v1 *)f;
-       if (len == sizeof(xfs_inode_log_format_t_v1)) {
-           printf("5.3 INODE: #regs: %d   ino: 0x%llx  flags: 0x%x   dsize: %d\n",
-                  old_f->ilf_size, (unsigned long long)old_f->ilf_ino,
-                  old_f->ilf_fields, old_f->ilf_dsize);
-       } else {
-           ASSERT(len >= 4);   /* must have at least 4 bytes if != 0 */
-           printf("5.3 INODE: #regs: %d   Not printing rest of data\n",
-                  old_f->ilf_size);
-           return old_f->ilf_size;
-       }
+    if (!continued &&
+       (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"),
+              f->ilf_size, (unsigned long long)f->ilf_ino,
+              f->ilf_fields, f->ilf_dsize);
+       printf(_("        blkno: %lld  len: %d  boff: %d\n"),
+              (long long)f->ilf_blkno, f->ilf_len, f->ilf_boffset);
     } else {
-       if (len == sizeof(xfs_inode_log_format_t)) {
-           if (version == XFS_LI_6_1_INODE)
-               printf("6.1 INODE: ");
-           else printf("INODE: ");
-           printf("#regs: %d   ino: 0x%llx  flags: 0x%x   dsize: %d\n",
-                  f->ilf_size, (unsigned long long)f->ilf_ino,
-                  f->ilf_fields, f->ilf_dsize);
-           printf("        blkno: %lld  len: %d  boff: %d\n",
-                  (long long)f->ilf_blkno, f->ilf_len, f->ilf_boffset);
-       } else {
-           ASSERT(len >= 4);   /* must have at least 4 bytes if != 0 */
-           printf("INODE: #regs: %d   Not printing rest of data\n",
-                  f->ilf_size);
-           return f->ilf_size;
-       }
+       ASSERT(len >= 4);       /* must have at least 4 bytes if != 0 */
+       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 (XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS))  {
-       return f->ilf_size-1;
+    if (op_head->oh_flags & XLOG_CONTINUE_TRANS)  {
+        return skip_count;
     }
 
-    bcopy(*ptr, &dino, sizeof(dino));
-    mode = dino.di_mode & IFMT;
+    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_dinode_core_t);
+    *ptr += xfs_log_dinode_size(log->l_mp);
+    skip_count--;
 
-    if (*i == num_ops-1 && f->ilf_size == 3)  {
-       return 1;
+    switch (f->ilf_fields & (XFS_ILOG_DEV | XFS_ILOG_UUID)) {
+    case XFS_ILOG_DEV:
+       printf(_("DEV inode: no extra region\n"));
+       break;
+    case XFS_ILOG_UUID:
+       printf(_("UUID inode: no extra region\n"));
+       break;
     }
 
+    /* Only the inode core is logged */
+    if (f->ilf_size == 2)
+       return 0;
+
+    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;
-    switch (f->ilf_fields & XFS_ILOG_NONCORE) {
-       case XFS_ILOG_DEXT: {
-           ASSERT(f->ilf_size == 3);
-           (*i)++;
-           xlog_print_op_header(op_head, *i, ptr);
-           printf("EXTENTS inode data\n");
-           *ptr += INT_GET(op_head->oh_len, ARCH_CONVERT);
-           if (XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS))  {
-               return 1;
-           }
-           break;
-       }
-       case XFS_ILOG_DBROOT: {
-           ASSERT(f->ilf_size == 3);
-           (*i)++;
-           xlog_print_op_header(op_head, *i, ptr);
-           printf("BTREE inode data\n");
-           *ptr += INT_GET(op_head->oh_len, ARCH_CONVERT);
-           if (XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS))  {
-               return 1;
-           }
-           break;
-       }
-       case XFS_ILOG_DDATA: {
-           ASSERT(f->ilf_size == 3);
-           (*i)++;
-           xlog_print_op_header(op_head, *i, ptr);
-           printf("LOCAL inode data\n");
-           if (mode == IFDIR) {
-               xlog_print_dir_sf((xfs_dir_shortform_t*)*ptr, size);
-           }
-           *ptr += INT_GET(op_head->oh_len, ARCH_CONVERT);
-           if (XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS)) {
-               return 1;
-           }
-           break;
-       }
-       case XFS_ILOG_AEXT: {
-           ASSERT(f->ilf_size == 3);
-           (*i)++;
-           xlog_print_op_header(op_head, *i, ptr);
-           printf("EXTENTS inode attr\n");
-           *ptr += INT_GET(op_head->oh_len, ARCH_CONVERT);
-           if (XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS))  {
-               return 1;
-           }
-           break;
-       }
-       case XFS_ILOG_ABROOT: {
-           ASSERT(f->ilf_size == 3);
+
+    if (f->ilf_fields & XFS_ILOG_DFORK) {
+           if (*i == num_ops-1)
+               return skip_count;
            (*i)++;
            xlog_print_op_header(op_head, *i, ptr);
-           printf("BTREE inode attr\n");
-           *ptr += INT_GET(op_head->oh_len, ARCH_CONVERT);
-           if (XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS))  {
-               return 1;
+
+           switch (f->ilf_fields & XFS_ILOG_DFORK) {
+           case XFS_ILOG_DEXT:
+               printf(_("EXTENTS inode data\n"));
+               break;
+           case XFS_ILOG_DBROOT:
+               printf(_("BTREE inode data\n"));
+               break;
+           case XFS_ILOG_DDATA:
+               printf(_("LOCAL inode data\n"));
+               if (mode == S_IFDIR)
+                   xlog_print_dir2_sf(log, (xfs_dir2_sf_hdr_t *)*ptr, size);
+               break;
+           default:
+               ASSERT((f->ilf_fields & XFS_ILOG_DFORK) == 0);
+               break;
            }
-           break;
-       }
-       case XFS_ILOG_ADATA: {
-           ASSERT(f->ilf_size == 3);
+
+           *ptr += be32_to_cpu(op_head->oh_len);
+           if (op_head->oh_flags & XLOG_CONTINUE_TRANS)
+               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);
-           printf("LOCAL inode attr\n");
-           if (mode == IFDIR) {
-               xlog_print_dir_sf((xfs_dir_shortform_t*)*ptr, size);
-           }
-           *ptr += INT_GET(op_head->oh_len, ARCH_CONVERT);
-           if (XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS)) {
-               return 1;
+
+           switch (f->ilf_fields & XFS_ILOG_AFORK) {
+           case XFS_ILOG_AEXT:
+               printf(_("EXTENTS attr data\n"));
+               break;
+           case XFS_ILOG_ABROOT:
+               printf(_("BTREE attr data\n"));
+               break;
+           case XFS_ILOG_ADATA:
+               printf(_("LOCAL attr data\n"));
+               if (mode == S_IFDIR)
+                   xlog_print_dir2_sf(log, (xfs_dir2_sf_hdr_t *)*ptr, size);
+               break;
+           default:
+               ASSERT((f->ilf_fields & XFS_ILOG_AFORK) == 0);
+               break;
            }
-           break;
-       }
-       case XFS_ILOG_DEV: {
-           ASSERT(f->ilf_size == 2);
-           printf("DEV inode: no extra region\n");
-           break;
-       }
-       case XFS_ILOG_UUID: {
-           ASSERT(f->ilf_size == 2);
-           printf("UUID inode: no extra region\n");
-           break;
-       }
-       case 0: {
-           ASSERT(f->ilf_size == 2);
-           break;
-       }
-       default: {
-           xlog_panic("xlog_print_trans_inode: illegal inode type");
-       }
+           *ptr += be32_to_cpu(op_head->oh_len);
+           if (op_head->oh_flags & XLOG_CONTINUE_TRANS)
+               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};
-    xfs_disk_dquot_t   ddq;
-    xlog_op_header_t   *head = NULL;
-    int                        num, skip;
+    xfs_dq_logformat_t         *f;
+    xfs_dq_logformat_t         lbuf = {0};
+    struct xfs_disk_dquot      ddq;
+    xlog_op_header_t           *head = NULL;
+    int                                num, skip;
 
     /*
      * print dquot header region
      *
-     * bcopy to ensure 8-byte alignment for the long longs in
+     * memmove to ensure 8-byte alignment for the long longs in
      * xfs_dq_logformat_t structure
      */
-    bcopy(*ptr, &lbuf, MIN(sizeof(xfs_dq_logformat_t), len));
+    memmove(&lbuf, *ptr, min(sizeof(xfs_dq_logformat_t), len));
     f = &lbuf;
     (*i)++;                                    /* bump index */
     *ptr += len;
 
     if (len == sizeof(xfs_dq_logformat_t)) {
-       printf("#regs: %d   id: 0x%x", f->qlf_size, f->qlf_id);
-       printf("  blkno: %lld  len: %d  boff: %d\n",
+       printf(_("#regs: %d   id: 0x%x"), f->qlf_size, f->qlf_id);
+       printf(_("  blkno: %lld  len: %d  boff: %d\n"),
                (long long)f->qlf_blkno, f->qlf_len, f->qlf_boffset);
     } else {
        ASSERT(len >= 4);       /* must have at least 4 bytes if != 0 */
-       printf("DQUOT: #regs: %d   Not printing rest of data\n",
+       printf(_("DQUOT: #regs: %d   Not printing rest of data\n"),
                f->qlf_size);
        return f->qlf_size;
     }
@@ -830,12 +741,11 @@ xlog_print_trans_dquot(xfs_caddr_t *ptr, int len, int *i, int num_ops)
     while (num-- > 0) {
        head = (xlog_op_header_t *)*ptr;
        xlog_print_op_header(head, *i, ptr);
-       ASSERT(INT_GET(head->oh_len, ARCH_CONVERT) == sizeof(xfs_disk_dquot_t));
-       bcopy(*ptr, &ddq, sizeof(xfs_disk_dquot_t));
-       printf("DQUOT: magic 0x%hx flags 0%ho\n",
-              INT_GET(ddq.d_magic, ARCH_CONVERT),
-              INT_GET(ddq.d_flags, ARCH_CONVERT));
-       *ptr += INT_GET(head->oh_len, ARCH_CONVERT);
+       ASSERT(be32_to_cpu(head->oh_len) == sizeof(struct xfs_disk_dquot));
+       memmove(&ddq, *ptr, sizeof(struct xfs_disk_dquot));
+       printf(_("DQUOT: magic 0x%hx flags 0%ho\n"),
+              be16_to_cpu(ddq.d_magic), ddq.d_type);
+       *ptr += be32_to_cpu(head->oh_len);
     }
     if (head && head->oh_flags & XLOG_CONTINUE_TRANS)
        skip++;
@@ -843,6 +753,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
@@ -850,8 +788,18 @@ xlog_print_trans_dquot(xfs_caddr_t *ptr, int len, int *i, int num_ops)
  ******************************************************************************
  */
 
+time64_t
+xlog_extract_dinode_ts(
+       const xfs_log_timestamp_t       its)
+{
+       struct xfs_log_legacy_timestamp *lits;
+
+       lits = (struct xfs_log_legacy_timestamp *)&its;
+       return (time64_t)lits->t_sec;
+}
+
 void
-xlog_print_lseek(xlog_t *log, int fd, xfs_daddr_t blkno, int whence)
+xlog_print_lseek(struct xlog *log, int fd, xfs_daddr_t blkno, int whence)
 {
 #define BBTOOFF64(bbs) (((xfs_off_t)(bbs)) << BBSHIFT)
        xfs_off_t offset;
@@ -860,37 +808,38 @@ xlog_print_lseek(xlog_t *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 %llu failed: %s\n",
-                       progname, (unsigned long long)offset, strerror(errno));
+       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,
-         xfs_lsn_t     *lsn,
-         xfs_arch_t    arch)
+static void
+print_lsn(char         *string,
+         __be64        *lsn)
 {
     printf("%s: %u,%u", string,
-           CYCLE_LSN(*lsn, arch), BLOCK_LSN(*lsn, arch));
+           CYCLE_LSN(be64_to_cpu(*lsn)), BLOCK_LSN(be64_to_cpu(*lsn)));
 }
 
 
-int
-xlog_print_record(int            fd,
-                int              num_ops,
-                int              len,
-                int              *read_type,
-                xfs_caddr_t      *partial_buf,
-                xlog_rec_header_t *rhead)
+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)
 {
-    xlog_op_header_t   *op_head;
-    xlog_rec_header_t  *rechead;
-    xfs_caddr_t                buf, ptr;
-    int                        read_len, skip;
-    int                        ret, n, i;
+    char               *buf, *ptr;
+    int                        read_len, skip, lost_context = 0;
+    int                        ret, n, i, j, k;
 
     if (print_no_print)
            return NO_ERROR;
@@ -905,23 +854,24 @@ 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) {
-           fprintf(stderr, "xlog_print_record: malloc failed\n");
+       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) {
-       fprintf(stderr, "xlog_print_record: read error\n");
+       fprintf(stderr, _("%s: xlog_print_record: read error\n"), progname);
        exit(1);
     }
     /* Did we overflow the end? */
     if (*read_type == FULL_READ &&
-       BLOCK_LSN(rhead->h_lsn, ARCH_CONVERT)+BTOBB(read_len) >= logBBsize) {
-       *read_type = BBTOB(logBBsize-BLOCK_LSN(rhead->h_lsn, ARCH_CONVERT)-1);
+       BLOCK_LSN(be64_to_cpu(rhead->h_lsn)) + BTOBB(read_len) >=
+               logBBsize) {
+       *read_type = BBTOB(logBBsize - BLOCK_LSN(be64_to_cpu(rhead->h_lsn))-1);
        *partial_buf = buf;
        return PARTIAL_READ;
     }
@@ -935,109 +885,204 @@ xlog_print_record(int             fd,
     if (*read_type != FULL_READ)
        read_len += *read_type;
 
-    /* Everything read in.  Start from beginning of buffer */
+    /* Everything read in.  Start from beginning of buffer
+     * Unpack the data, by putting the saved cycle-data back
+     * into the first word of each BB.
+     * Do some checks.
+     */
     buf = ptr;
     for (i = 0; ptr < buf + read_len; ptr += BBSIZE, i++) {
-       rechead = (xlog_rec_header_t *)ptr;
-       if (INT_GET(rechead->h_magicno, ARCH_CONVERT) == XLOG_HEADER_MAGIC_NUM) {
-           xlog_print_lseek(0, fd, -read_len+i*BBSIZE, SEEK_CUR);
+       xlog_rec_header_t *rechead = (xlog_rec_header_t *)ptr;
+
+       /* sanity checks */
+       if (be32_to_cpu(rechead->h_magicno) == XLOG_HEADER_MAGIC_NUM) {
+           /* data should not have magicno as first word
+            * as it should by cycle#
+            */
            free(buf);
            return -1;
        } else {
-           if (INT_GET(rhead->h_cycle, ARCH_CONVERT) !=
-                       INT_GET(*(uint *)ptr, ARCH_CONVERT)) {
-               if (*read_type == FULL_READ)
-                   return -1;
-               else if (INT_GET(rhead->h_cycle, ARCH_CONVERT) + 1 !=
-                       INT_GET(*(uint *)ptr, ARCH_CONVERT))
-                   return -1;
+           /* verify cycle#
+            * FIXME: cycle+1 should be a macro pv#900369
+            */
+           if (be32_to_cpu(rhead->h_cycle) !=
+                       be32_to_cpu(*(__be32 *)ptr)) {
+               if ((*read_type == FULL_READ) ||
+                   (be32_to_cpu(rhead->h_cycle) + 1 !=
+                               be32_to_cpu(*(__be32 *)ptr))) {
+                       free(buf);
+                       return -1;
+               }
            }
        }
-       INT_SET(*(uint *)ptr, ARCH_CONVERT,
-               INT_GET(rhead->h_cycle_data[i], ARCH_CONVERT));
+
+       /* copy back the data from the header */
+       if (i < XLOG_HEADER_CYCLE_SIZE / BBSIZE) {
+               /* from 1st header */
+               *(__be32 *)ptr = rhead->h_cycle_data[i];
+       }
+       else {
+               ASSERT(xhdrs != NULL);
+               /* from extra headers */
+               j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
+               k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
+               *(__be32 *)ptr = xhdrs[j-1].xh_cycle_data[k];
+       }
+
     }
+
     ptr = buf;
     for (i=0; i<num_ops; i++) {
+       int continued;
+
+       xlog_op_header_t *op_head = (xlog_op_header_t *)ptr;
+
        print_xlog_op_line();
-       op_head = (xlog_op_header_t *)ptr;
        xlog_print_op_header(op_head, i, &ptr);
+       continued = ((op_head->oh_flags & XLOG_WAS_CONT_TRANS) ||
+                    (op_head->oh_flags & XLOG_CONTINUE_TRANS));
 
-       /* print transaction data */
-       if (print_no_data ||
-           ((XLOG_SET(op_head->oh_flags, XLOG_WAS_CONT_TRANS) ||
-             XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS)) &&
-            INT_GET(op_head->oh_len, ARCH_CONVERT) == 0)) {
-           for (n = 0; n < INT_GET(op_head->oh_len, ARCH_CONVERT); n++) {
-               printf("%c", *ptr);
+       if (continued && be32_to_cpu(op_head->oh_len) == 0)
+               continue;
+
+       if (print_no_data) {
+           for (n = 0; n < be32_to_cpu(op_head->oh_len); n++) {
+               printf("0x%02x ", (unsigned int)*ptr);
+               if (n % 16 == 15)
+                       printf("\n");
                ptr++;
            }
            printf("\n");
            continue;
        }
-       if (xlog_print_find_tid(INT_GET(op_head->oh_tid, ARCH_CONVERT),
+
+       /* print transaction data */
+       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");
-           ptr += INT_GET(op_head->oh_len, ARCH_CONVERT);
+           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;
        }
-       if (INT_GET(op_head->oh_len, ARCH_CONVERT) != 0) {
+
+       if (be32_to_cpu(op_head->oh_len) != 0) {
            if (*(uint *)ptr == XFS_TRANS_HEADER_MAGIC) {
                skip = xlog_print_trans_header(&ptr,
-                                       INT_GET(op_head->oh_len, ARCH_CONVERT));
+                                       be32_to_cpu(op_head->oh_len));
            } else {
                switch (*(unsigned short *)ptr) {
-                   case XFS_LI_5_3_BUF:
-                   case XFS_LI_6_1_BUF:
                    case XFS_LI_BUF: {
                        skip = xlog_print_trans_buffer(&ptr,
-                                       INT_GET(op_head->oh_len, ARCH_CONVERT),
+                                       be32_to_cpu(op_head->oh_len),
                                        &i, num_ops);
                        break;
                    }
-                   case XFS_LI_5_3_INODE:
-                   case XFS_LI_6_1_INODE:
-                   case XFS_LI_INODE: {
-                       skip = xlog_print_trans_inode(&ptr,
-                                       INT_GET(op_head->oh_len, ARCH_CONVERT),
+                   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(log, &ptr,
+                                       be32_to_cpu(op_head->oh_len),
+                                       &i, num_ops, continued);
+                       break;
+                   }
                    case XFS_LI_DQUOT: {
                        skip = xlog_print_trans_dquot(&ptr,
-                                       INT_GET(op_head->oh_len, ARCH_CONVERT),
+                                       be32_to_cpu(op_head->oh_len),
                                        &i, num_ops);
                        break;
                    }
                    case XFS_LI_EFI: {
                        skip = xlog_print_trans_efi(&ptr,
-                                       INT_GET(op_head->oh_len, ARCH_CONVERT));
+                                       be32_to_cpu(op_head->oh_len),
+                                       continued);
                        break;
                    }
                    case XFS_LI_EFD: {
                        skip = xlog_print_trans_efd(&ptr,
-                                       INT_GET(op_head->oh_len, ARCH_CONVERT));
+                                       be32_to_cpu(op_head->oh_len));
+                       break;
+                   }
+                   case XFS_LI_ATTRI: {
+                       skip = xlog_print_trans_attri(&ptr,
+                                       be32_to_cpu(op_head->oh_len),
+                                       &i);
+                       break;
+                   }
+                   case XFS_LI_ATTRD: {
+                       skip = xlog_print_trans_attrd(&ptr,
+                                       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,
-                                       INT_GET(op_head->oh_len, ARCH_CONVERT));
+                                       be32_to_cpu(op_head->oh_len));
                        break;
                    }
                    case XLOG_UNMOUNT_TYPE: {
-                       printf("Unmount filesystem\n");
+                       printf(_("Unmount filesystem\n"));
                        skip = 0;
                        break;
                    }
                    default: {
-                       fprintf(stderr, "%s: unknown log operation type (%x)\n",
-                               progname, *(unsigned short *)ptr);
+                       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 += INT_GET(op_head->oh_len, ARCH_CONVERT);
+                       ptr += be32_to_cpu(op_head->oh_len);
+                       lost_context = 0;
                    }
                } /* switch */
            } /* else */
            if (skip != 0)
-               xlog_print_add_to_trans(INT_GET(op_head->oh_tid, ARCH_CONVERT), skip);
+               xlog_print_add_to_trans(be32_to_cpu(op_head->oh_tid), skip);
        }
     }
     printf("\n");
@@ -1046,78 +1091,103 @@ 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];
     int datalen,bbs;
 
     if (print_no_print)
-           return INT_GET(head->h_num_logops, ARCH_CONVERT);
+           return be32_to_cpu(head->h_num_logops);
 
-    if (INT_ISZERO(head->h_magicno, ARCH_CONVERT))
+    if (!head->h_magicno)
        return ZEROED_LOG;
 
-    if (INT_GET(head->h_magicno, ARCH_CONVERT) != XLOG_HEADER_MAGIC_NUM) {
-       printf("Header 0x%x wanted 0x%x\n",
-               INT_GET(head->h_magicno, ARCH_CONVERT),
-               XLOG_HEADER_MAGIC_NUM);
+    if (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;
     }
 
-    datalen=INT_GET(head->h_len, ARCH_CONVERT);
-    bbs=(datalen/BBSIZE)+(datalen%BBSIZE)?1:0;
+    /* check for cleared blocks written by xlog_clear_stale_blocks() */
+    if (!head->h_len && !head->h_crc && !head->h_prev_block &&
+       !head->h_num_logops && !head->h_size)
+       return CLEARED_BLKS;
 
-    printf("cycle: %d  version: %d     ",
-           INT_GET(head->h_cycle, ARCH_CONVERT),
-           INT_GET(head->h_version, ARCH_CONVERT));
-    print_lsn("        lsn", &head->h_lsn, ARCH_CONVERT);
-    print_lsn("        tail_lsn", &head->h_tail_lsn, ARCH_CONVERT);
+    datalen=be32_to_cpu(head->h_len);
+    bbs=BTOBB(datalen);
+
+    printf(_("cycle: %d        version: %d     "),
+           be32_to_cpu(head->h_cycle),
+           be32_to_cpu(head->h_version));
+    print_lsn("        lsn", &head->h_lsn);
+    print_lsn("        tail_lsn", &head->h_tail_lsn);
     printf("\n");
-    printf("length of Log Record: %d   prev offset: %d         num ops: %d\n",
+    printf(_("length of Log Record: %d prev offset: %d         num ops: %d\n"),
           datalen,
-           INT_GET(head->h_prev_block, ARCH_CONVERT),
-           INT_GET(head->h_num_logops, ARCH_CONVERT));
+           be32_to_cpu(head->h_prev_block),
+           be32_to_cpu(head->h_num_logops));
 
     if (print_overwrite) {
-       printf("cycle num overwrites: ");
-       for (i=0; i< bbs; i++)
+       printf(_("cycle num overwrites: "));
+       for (i=0; i< min(bbs, XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++)
            printf("%d - 0x%x  ",
                    i,
-                   INT_GET(head->h_cycle_data[i], ARCH_CONVERT));
+                   be32_to_cpu(head->h_cycle_data[i]));
        printf("\n");
     }
 
-    uuid_unparse(head->h_fs_uuid, uub);
-    printf("uuid: %s   format: ", uub);
-    switch (INT_GET(head->h_fmt, ARCH_CONVERT)) {
+    platform_uuid_unparse(&head->h_fs_uuid, uub);
+    printf(_("uuid: %s   format: "), uub);
+    switch (be32_to_cpu(head->h_fmt)) {
        case XLOG_FMT_UNKNOWN:
-           printf("unknown\n");
+           printf(_("unknown\n"));
            break;
        case XLOG_FMT_LINUX_LE:
-           printf("little endian linux\n");
+           printf(_("little endian linux\n"));
            break;
        case XLOG_FMT_LINUX_BE:
-           printf("big endian linux\n");
+           printf(_("big endian linux\n"));
            break;
        case XLOG_FMT_IRIX_BE:
-           printf("big endian irix\n");
+           printf(_("big endian irix\n"));
            break;
        default:
-           printf("? (%d)\n", INT_GET(head->h_fmt, ARCH_CONVERT));
+           printf("? (%d)\n", be32_to_cpu(head->h_fmt));
            break;
     }
+    printf(_("h_size: %d\n"), be32_to_cpu(head->h_size));
 
-    *len = INT_GET(head->h_len, ARCH_CONVERT);
-    return(INT_GET(head->h_num_logops, ARCH_CONVERT));
+    *len = be32_to_cpu(head->h_len);
+    return(be32_to_cpu(head->h_num_logops));
 }      /* xlog_print_rec_head */
 
+static void
+xlog_print_rec_xhead(xlog_rec_ext_header_t *head, int coverage)
+{
+    int i;
+
+    print_xlog_xhdr_line();
+    printf(_("extended-header: cycle: %d\n"), be32_to_cpu(head->xh_cycle));
+
+    if (print_overwrite) {
+       printf(_("cycle num overwrites: "));
+       for (i = 0; i < coverage; i++)
+           printf("%d - 0x%x  ",
+                   i,
+                   be32_to_cpu(head->xh_cycle_data[i]));
+       printf("\n");
+    }
+}      /* xlog_print_rec_xhead */
+
 static void
 print_xlog_bad_zeroed(xfs_daddr_t blkno)
 {
        print_stars();
-       printf("* ERROR: found data after zeroed blocks block=%-21lld  *\n",
+       printf(_("* ERROR: found data after zeroed blocks block=%-21lld  *\n"),
                (long long)blkno);
        print_stars();
        if (print_exit)
@@ -1125,41 +1195,150 @@ 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",
-               GET_CYCLE(buf, ARCH_CONVERT), (long long)blkno);
+       printf(_("* ERROR: header cycle=%-11d block=%-21lld        *\n"),
+               xlog_get_cycle(buf), (long long)blkno);
        print_stars();
        if (print_exit)
            xlog_exit("Bad log record header");
 }      /* print_xlog_bad_header */
 
-void
+static void
 print_xlog_bad_data(xfs_daddr_t blkno)
 {
        print_stars();
-       printf("* ERROR: data block=%-21lld                             *\n",
+       printf(_("* ERROR: data block=%-21lld                             *\n"),
                (long long)blkno);
        print_stars();
        if (print_exit)
            xlog_exit("Bad data in log");
 }      /* print_xlog_bad_data */
 
+static void
+print_xlog_bad_reqd_hdrs(xfs_daddr_t blkno, int num_reqd, int num_hdrs)
+{
+       print_stars();
+       printf(_("* ERROR: for header block=%lld\n"
+              "*        not enough hdrs for data length, "
+               "required num = %d, hdr num = %d\n"),
+               (long long)blkno, num_reqd, num_hdrs);
+       print_stars();
+       if (print_exit)
+           xlog_exit(_("Not enough headers for data length."));
+}      /* print_xlog_bad_reqd_hdrs */
+
+static void
+xlog_reallocate_xhdrs(int num_hdrs, xlog_rec_ext_header_t **ret_xhdrs)
+{
+       int len = (num_hdrs-1) * sizeof(xlog_rec_ext_header_t);
+
+       *ret_xhdrs = (xlog_rec_ext_header_t *)realloc(*ret_xhdrs, len);
+       if (*ret_xhdrs == NULL) {
+               fprintf(stderr, _("%s: xlog_print: malloc failed for ext hdrs\n"), progname);
+               exit(1);
+       }
+}
+
+/* for V2 logs read each extra hdr and print it out */
+static int
+xlog_print_extended_headers(
+       int                     fd,
+       int                     len,
+       xfs_daddr_t             *blkno,
+       xlog_rec_header_t       *hdr,
+       int                     *ret_num_hdrs,
+       xlog_rec_ext_header_t   **ret_xhdrs)
+{
+       int                     i, j;
+       int                     coverage_bb;
+       int                     num_hdrs;
+       int                     num_required;
+       char                    xhbuf[XLOG_HEADER_SIZE];
+       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);
+       }
+
+       if (num_hdrs == 1) {
+           free(*ret_xhdrs);
+           *ret_xhdrs = NULL;
+           *ret_num_hdrs = 1;
+           return 0;
+       }
+
+       if (*ret_xhdrs == NULL || num_hdrs > *ret_num_hdrs) {
+           xlog_reallocate_xhdrs(num_hdrs, ret_xhdrs);
+       }
+
+       *ret_num_hdrs = num_hdrs;
+
+       /* don't include 1st header */
+       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);
+               print_xlog_record_line();
+               /* reached the end so return 1 */
+               return 1;
+           }
+           if (print_only_data) {
+               printf(_("BLKNO: %lld\n"), (long long)*blkno);
+               xlog_recover_print_data(xhbuf, 512);
+           }
+           else {
+               if (i == num_hdrs - 1) {
+                   /* last header */
+                   coverage_bb = BTOBB(len) %
+                                   (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
+               }
+               else {
+                   /* earliear header */
+                   coverage_bb = XLOG_HEADER_CYCLE_SIZE / BBSIZE;
+               }
+               xlog_print_rec_xhead((xlog_rec_ext_header_t*)xhbuf, coverage_bb);
+           }
+
+           /* Copy from buffer into xhdrs array for later.
+            * Could endian convert here but then code later on
+            * will look asymmetric with the 1 hdr normal case
+            * which does endian coversion on access.
+            */
+           xhdr->xh_cycle = ((xlog_rec_ext_header_t*)xhbuf)->xh_cycle;
+           for (j = 0; j < XLOG_HEADER_CYCLE_SIZE / BBSIZE; j++) {
+               xhdr->xh_cycle_data[j] =
+                   ((xlog_rec_ext_header_t*)xhbuf)->xh_cycle_data[j];
+           }
+       }
+       return 0;
+}
+
 
 /*
  * This code is gross and needs to be rewritten.
  */
-void xfs_log_print(xlog_t       *log,
+void xfs_log_print(struct xlog  *log,
                   int          fd,
                   int          print_block_start)
 {
-    char       hbuf[XLOG_HEADER_SIZE];
-    int                num_ops, len;
-    xfs_daddr_t        block_end = 0, block_start, blkno, error;
-    int                read_type = FULL_READ;
-    xfs_caddr_t        partial_buf;
-    int         zeroed = 0;
+    char                       hbuf[XLOG_HEADER_SIZE];
+    xlog_rec_header_t          *hdr = (xlog_rec_header_t *)&hbuf[0];
+    xlog_rec_ext_header_t      *xhdrs = NULL;
+    int                                num_ops, len, num_hdrs = 1;
+    xfs_daddr_t                        block_end = 0, block_start, blkno, error;
+    xfs_daddr_t                        zeroed_blkno = 0, cleared_blkno = 0;
+    int                                read_type = FULL_READ;
+    char                       *partial_buf;
+    int                                zeroed = 0;
+    int                                cleared = 0;
+    int                                first_hdr_found = 0;
 
     logBBsize = log->l_logBBsize;
 
@@ -1169,33 +1348,33 @@ void xfs_log_print(xlog_t       *log,
      * we still end at the end of the logical log.
      */
     if ((error = xlog_print_find_oldest(log, &block_end))) {
-           fprintf(stderr, "%s: problem finding oldest LR\n", progname);
-           return;
+       fprintf(stderr, _("%s: problem finding oldest LR\n"), progname);
+       return;
     }
     if (print_block_start == -1)
-           block_start = block_end;
+       block_start = block_end;
     else
-           block_start = print_block_start;
+       block_start = print_block_start;
     xlog_print_lseek(log, fd, block_start, SEEK_SET);
-    blkno    = block_start;
+    blkno = block_start;
 
     for (;;) {
        if (read(fd, hbuf, 512) == 0) {
-           printf("%s: physical end of log\n", progname);
+           printf(_("%s: physical end of log\n"), progname);
            print_xlog_record_line();
            break;
        }
        if (print_only_data) {
-               printf("BLKNO: %lld\n", (long long)blkno);
-               xlog_recover_print_data(hbuf, 512);
-               blkno++;
-               goto loop;
+           printf(_("BLKNO: %lld\n"), (long long)blkno);
+           xlog_recover_print_data(hbuf, 512);
+           blkno++;
+           goto loop;
        }
-       num_ops = xlog_print_rec_head((xlog_rec_header_t *)hbuf, &len);
+       num_ops = xlog_print_rec_head(hdr, &len, first_hdr_found);
        blkno++;
 
        if (zeroed && num_ops != ZEROED_LOG) {
-           printf("%s: after %d zeroed blocks\n", progname, zeroed);
+           printf(_("%s: after %d zeroed blocks\n"), progname, zeroed);
            /* once we find zeroed blocks - that's all we expect */
            print_xlog_bad_zeroed(blkno-1);
            /* reset count since we're assuming previous zeroed blocks
@@ -1204,18 +1383,36 @@ void xfs_log_print(xlog_t       *log,
            zeroed = 0;
        }
 
-       if (num_ops == ZEROED_LOG || num_ops == BAD_HEADER) {
+       if (num_ops == ZEROED_LOG ||
+           num_ops == CLEARED_BLKS ||
+           num_ops == BAD_HEADER) {
            if (num_ops == ZEROED_LOG) {
+               if (zeroed == 0)
+                   zeroed_blkno = blkno-1;
                zeroed++;
+           }
+           else if (num_ops == CLEARED_BLKS) {
+               if (cleared == 0)
+                   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;
        }
 
-       error = xlog_print_record(fd, num_ops, len, &read_type, &partial_buf,
-                                 (xlog_rec_header_t *)hbuf);
+       if (be32_to_cpu(hdr->h_version) == 2) {
+           if (xlog_print_extended_headers(fd, len, &blkno, hdr, &num_hdrs, &xhdrs) != 0)
+               break;
+       }
+
+       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);
@@ -1234,7 +1431,7 @@ void xfs_log_print(xlog_t       *log,
            }
            case PARTIAL_READ: {
                print_xlog_record_line();
-               printf("%s: physical end of log\n", progname);
+               printf(_("%s: physical end of log\n"), progname);
                print_xlog_record_line();
                blkno = 0;
                xlog_print_lseek(log, fd, 0, SEEK_SET);
@@ -1246,21 +1443,34 @@ void xfs_log_print(xlog_t       *log,
                        goto end;
                goto partial_log_read;
            }
-           default: xlog_panic("illegal value");
+           default: xlog_panic(_("illegal value"));
        }
        print_xlog_record_line();
 loop:
        if (blkno >= logBBsize) {
-               if (zeroed) {
-                   printf("%s: skipped %d zeroed blocks\n", progname, zeroed);
-                   if (zeroed == logBBsize)
-                       printf("%s: totally zeroed log\n", progname);
-
-                   zeroed=0;
-               }
-               printf("%s: physical end of log\n", progname);
-               print_xlog_record_line();
-               break;
+           if (cleared) {
+               printf(_("%s: skipped %d cleared blocks in range: %lld - %lld\n"),
+                       progname, cleared,
+                       (long long)(cleared_blkno),
+                       (long long)(cleared + cleared_blkno - 1));
+               if (cleared == logBBsize)
+                   printf(_("%s: totally cleared log\n"), progname);
+
+               cleared=0;
+           }
+           if (zeroed) {
+               printf(_("%s: skipped %d zeroed blocks in range: %lld - %lld\n"),
+                       progname, zeroed,
+                       (long long)(zeroed_blkno),
+                       (long long)(zeroed + zeroed_blkno - 1));
+               if (zeroed == logBBsize)
+                   printf(_("%s: totally zeroed log\n"), progname);
+
+               zeroed=0;
+           }
+           printf(_("%s: physical end of log\n"), progname);
+           print_xlog_record_line();
+           break;
        }
     }
 
@@ -1270,21 +1480,23 @@ loop:
        xlog_print_lseek(log, fd, 0, SEEK_SET);
        for (;;) {
            if (read(fd, hbuf, 512) == 0) {
-               xlog_panic("xlog_find_head: bad read");
+               xlog_panic(_("xlog_find_head: bad read"));
            }
            if (print_only_data) {
-               printf("BLKNO: %lld\n", (long long)blkno);
+               printf(_("BLKNO: %lld\n"), (long long)blkno);
                xlog_recover_print_data(hbuf, 512);
                blkno++;
                goto loop2;
            }
-           num_ops = xlog_print_rec_head((xlog_rec_header_t *)hbuf, &len);
+           num_ops = xlog_print_rec_head(hdr, &len, first_hdr_found);
            blkno++;
 
-           if (num_ops == ZEROED_LOG || num_ops == BAD_HEADER) {
-               /* we only expect zeroed log entries at the end
-                * of the _physical_ log, so treat them the same
-                * as bad blocks here
+           if (num_ops == ZEROED_LOG ||
+               num_ops == CLEARED_BLKS ||
+               num_ops == BAD_HEADER) {
+               /* we only expect zeroed log entries  or cleared log
+                * entries at the end of the _physical_ log,
+                * so treat them the same as bad blocks here
                 */
                print_xlog_bad_header(blkno-1, hbuf);
 
@@ -1292,9 +1504,16 @@ loop:
                    break;
                continue;
            }
+
+           if (be32_to_cpu(hdr->h_version) == 2) {
+               if (xlog_print_extended_headers(fd, len, &blkno, hdr, &num_hdrs, &xhdrs) != 0)
+                   break;
+           }
+
 partial_log_read:
-           error= xlog_print_record(fd, num_ops, len, &read_type,
-                                   &partial_buf, (xlog_rec_header_t *)hbuf);
+           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;
@@ -1313,6 +1532,37 @@ loop2:
     }
 
 end:
-    printf("%s: logical end of log\n", progname);
+    printf(_("%s: logical end of log\n"), progname);
     print_xlog_record_line();
 }
+
+/*
+ * 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
+ */
+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(struct xfs_inode_log_format)) {
+               return (struct xfs_inode_log_format *)src_buf;
+       }
+
+       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;
+
+       return in_f;
+}