]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
Fix up logprint so that 32 bit or 64 bit versions of logprint binaries
authorTim Shimmin <tes@sgi.com>
Fri, 16 Jun 2006 03:52:27 +0000 (03:52 +0000)
committerTim Shimmin <tes@sgi.com>
Fri, 16 Jun 2006 03:52:27 +0000 (03:52 +0000)
can print a log from an XFS file system on a 64bit or 32bit os.
Merge of master-melb:xfs-cmds:26264a by kenmcd.

  Copied from kernel. 32 & 64 bit versions of EFI/EFD format items.

include/xfs_extfree_item.h
include/xfs_inode_item.h
logprint/log_misc.c
logprint/log_print_all.c
logprint/logprint.h

index 5bf681708fec915348cf0324b9392c81fa7f0287..0ea45edaab033b31ba258b2cc39c3f48634f0d70 100644 (file)
@@ -26,6 +26,24 @@ typedef struct xfs_extent {
        xfs_extlen_t    ext_len;
 } xfs_extent_t;
 
+/*
+ * Since an xfs_extent_t has types (start:64, len: 32)
+ * there are different alignments on 32 bit and 64 bit kernels.
+ * So we provide the different variants for use by a
+ * conversion routine.
+ */
+
+typedef struct xfs_extent_32 {
+       xfs_dfsbno_t    ext_start;
+       xfs_extlen_t    ext_len;
+} __attribute__((packed)) xfs_extent_32_t;
+
+typedef struct xfs_extent_64 {
+       xfs_dfsbno_t    ext_start;
+       xfs_extlen_t    ext_len;
+       __uint32_t      ext_pad;
+} xfs_extent_64_t;
+
 /*
  * This is the structure used to lay out an efi log item in the
  * log.  The efi_extents field is a variable size array whose
@@ -39,6 +57,22 @@ typedef struct xfs_efi_log_format {
        xfs_extent_t            efi_extents[1]; /* array of extents to free */
 } xfs_efi_log_format_t;
 
+typedef struct xfs_efi_log_format_32 {
+       unsigned short          efi_type;       /* efi log item type */
+       unsigned short          efi_size;       /* size of this item */
+       uint                    efi_nextents;   /* # extents to free */
+       __uint64_t              efi_id;         /* efi identifier */
+       xfs_extent_32_t         efi_extents[1]; /* array of extents to free */
+} __attribute__((packed)) xfs_efi_log_format_32_t;
+
+typedef struct xfs_efi_log_format_64 {
+       unsigned short          efi_type;       /* efi log item type */
+       unsigned short          efi_size;       /* size of this item */
+       uint                    efi_nextents;   /* # extents to free */
+       __uint64_t              efi_id;         /* efi identifier */
+       xfs_extent_64_t         efi_extents[1]; /* array of extents to free */
+} xfs_efi_log_format_64_t;
+
 /*
  * This is the structure used to lay out an efd log item in the
  * log.  The efd_extents array is a variable size array whose
@@ -52,6 +86,22 @@ typedef struct xfs_efd_log_format {
        xfs_extent_t            efd_extents[1]; /* array of extents freed */
 } xfs_efd_log_format_t;
 
+typedef struct xfs_efd_log_format_32 {
+       unsigned short          efd_type;       /* efd log item type */
+       unsigned short          efd_size;       /* size of this item */
+       uint                    efd_nextents;   /* # of extents freed */
+       __uint64_t              efd_efi_id;     /* id of corresponding efi */
+       xfs_extent_32_t         efd_extents[1]; /* array of extents freed */
+} __attribute__((packed)) xfs_efd_log_format_32_t;
+
+typedef struct xfs_efd_log_format_64 {
+       unsigned short          efd_type;       /* efd log item type */
+       unsigned short          efd_size;       /* size of this item */
+       uint                    efd_nextents;   /* # of extents freed */
+       __uint64_t              efd_efi_id;     /* id of corresponding efi */
+       xfs_extent_64_t         efd_extents[1]; /* array of extents freed */
+} xfs_efd_log_format_64_t;
+
 
 #ifdef __KERNEL__
 
@@ -103,7 +153,8 @@ extern struct kmem_zone     *xfs_efd_zone;
 xfs_efi_log_item_t     *xfs_efi_init(struct xfs_mount *, uint);
 xfs_efd_log_item_t     *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *,
                                      uint);
-
+int                    xfs_efi_copy_format(xfs_log_iovec_t *buf,
+                                           xfs_efi_log_format_t *dst_efi_fmt);
 void                   xfs_efi_item_free(xfs_efi_log_item_t *);
 
 #endif /* __KERNEL__ */
index c5dbf93b6661bf71c735954d1322d2caacfcb757..5db6cd1b4cf3278fec78975c7969492f96d67dde 100644 (file)
  * log.  The size of the inline data/extents/b-tree root to be logged
  * (if any) is indicated in the ilf_dsize field.  Changes to this structure
  * must be added on to the end.
- *
- * Convention for naming inode log item versions :  The current version
- * is always named XFS_LI_INODE.  When an inode log item gets superseded,
- * add the latest version of IRIX that will generate logs with that item
- * to the version name.
- *
- * -Version 1 of this structure (XFS_LI_5_3_INODE) included up to the first
- *     union (ilf_u) field.  This was released with IRIX 5.3-XFS.
- * -Version 2 of this structure (XFS_LI_6_1_INODE) is currently the entire
- *     structure.  This was released with IRIX 6.0.1-XFS and IRIX 6.1.
- * -Version 3 of this structure (XFS_LI_INODE) is the same as version 2
- *     so a new structure definition wasn't necessary.  However, we had
- *     to add a new type because the inode cluster size changed from 4K
- *     to 8K and the version number had to be rev'ved to keep older kernels
- *     from trying to recover logs with the 8K buffers in them.  The logging
- *     code can handle recovery on different-sized clusters now so hopefully
- *     this'll be the last time we need to change the inode log item just
- *     for a change in the inode cluster size.  This new version was
- *     released with IRIX 6.2.
  */
 typedef struct xfs_inode_log_format {
        unsigned short          ilf_type;       /* inode log item type */
@@ -59,18 +40,38 @@ typedef struct xfs_inode_log_format {
        int                     ilf_boffset;    /* off of inode in buffer */
 } xfs_inode_log_format_t;
 
-/* Initial version shipped with IRIX 5.3-XFS */
-typedef struct xfs_inode_log_format_v1 {
-       unsigned short          ilf_type;       /* inode log item type */
-       unsigned short          ilf_size;       /* size of this item */
-       uint                    ilf_fields;     /* flags for fields logged */
-       uint                    ilf_dsize;      /* size of data/ext/root */
-       xfs_ino_t               ilf_ino;        /* inode number */
+typedef struct xfs_inode_log_format_32 {
+       unsigned short          ilf_type;       /* 16: inode log item type */
+       unsigned short          ilf_size;       /* 16: size of this item */
+       uint                    ilf_fields;     /* 32: flags for fields logged */
+       ushort                  ilf_asize;      /* 32: size of attr d/ext/root */
+       ushort                  ilf_dsize;      /* 32: size of data/ext/root */
+       xfs_ino_t               ilf_ino;        /* 64: inode number */
        union {
-               xfs_dev_t       ilfu_rdev;      /* rdev value for dev inode*/
-               uuid_t          ilfu_uuid;      /* mount point value */
+               xfs_dev_t       ilfu_rdev;      /* 32: rdev value for dev inode*/
+               uuid_t          ilfu_uuid;      /* 128: mount point value */
+       } ilf_u;
+       __int64_t               ilf_blkno;      /* 64: blkno of inode buffer */
+       int                     ilf_len;        /* 32: len of inode buffer */
+       int                     ilf_boffset;    /* 32: off of inode in buffer */
+} __attribute__((packed)) xfs_inode_log_format_32_t;
+
+typedef struct xfs_inode_log_format_64 {
+       unsigned short          ilf_type;       /* 16: inode log item type */
+       unsigned short          ilf_size;       /* 16: size of this item */
+       uint                    ilf_fields;     /* 32: flags for fields logged */
+       ushort                  ilf_asize;      /* 32: size of attr d/ext/root */
+       ushort                  ilf_dsize;      /* 32: size of data/ext/root */
+       __uint32_t              ilf_pad;        /* 32: pad for 64 bit boundary */
+       xfs_ino_t               ilf_ino;        /* 64: inode number */
+       union {
+               xfs_dev_t       ilfu_rdev;      /* 32: rdev value for dev inode*/
+               uuid_t          ilfu_uuid;      /* 128: mount point value */
        } ilf_u;
-} xfs_inode_log_format_t_v1;
+       __int64_t               ilf_blkno;      /* 64: blkno of inode buffer */
+       int                     ilf_len;        /* 32: len of inode buffer */
+       int                     ilf_boffset;    /* 32: off of inode in buffer */
+} xfs_inode_log_format_64_t;
 
 /*
  * Flags for xfs_trans_log_inode flags field.
@@ -172,6 +173,8 @@ extern void xfs_inode_item_destroy(struct xfs_inode *);
 extern void xfs_iflush_done(struct xfs_buf *, xfs_inode_log_item_t *);
 extern void xfs_istale_done(struct xfs_buf *, xfs_inode_log_item_t *);
 extern void xfs_iflush_abort(struct xfs_inode *);
+extern int xfs_inode_item_format_convert(xfs_log_iovec_t *,
+                                        xfs_inode_log_format_t *);
 
 #endif /* __KERNEL__ */
 
index 35fcfc58275f1051cf7f7198fdac1d238386b459..920c7b2c967b7fcd9250bde6b4fdc8155126af26 100644 (file)
@@ -251,6 +251,7 @@ xlog_print_trans_buffer(xfs_caddr_t *ptr, int len, int *i, int num_ops)
     xfs_buf_log_format_t lbuf;
     int                         size, blen, map_size, struct_size;
     long long           x, y;
+    ushort              flags;
 
     /*
      * bcopy to ensure 8-byte alignment for the long longs in
@@ -265,6 +266,7 @@ xlog_print_trans_buffer(xfs_caddr_t *ptr, int len, int *i, int num_ops)
        size = f->blf_size;
        blen = f->blf_len;
        map_size = f->blf_map_size;
+        flags = f->blf_flags;
        struct_size = sizeof(xfs_buf_log_format_t);
     } else {
        old_f = (xfs_buf_log_format_v1_t*)f;
@@ -272,6 +274,7 @@ xlog_print_trans_buffer(xfs_caddr_t *ptr, int len, int *i, int num_ops)
        size = old_f->blf_size;
        blen = old_f->blf_len;
        map_size = old_f->blf_map_size;
+        flags = f->blf_flags;
        struct_size = sizeof(xfs_buf_log_format_v1_t);
     }
     switch (f->blf_type)  {
@@ -290,8 +293,8 @@ xlog_print_trans_buffer(xfs_caddr_t *ptr, int len, int *i, int num_ops)
     }
     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 {
@@ -470,30 +473,23 @@ 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;
+    /* size without extents at end */
+    uint core_size = sizeof(xfs_efd_log_format_t) - sizeof(xfs_extent_t);
 
     /*
      * bcopy to ensure 8-byte alignment for the long longs in
      * xfs_efd_log_format_t structure
      */
-    bcopy(*ptr, &lbuf, len);
+    bcopy(*ptr, &lbuf, MIN(core_size, len));
     f = &lbuf;
     *ptr += len;
-    if (len >= sizeof(xfs_efd_log_format_t)) {
+    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);
-       ex = f->efd_extents;
-       len -= (sizeof(xfs_efd_log_format_t) - sizeof(xfs_extent_t));
-       for (i = 0; len > 0 && i < f->efd_nextents; i++) {
-               printf("(s: 0x%llx, l: %d) ",
-                       (unsigned long long)ex->ext_start, ex->ext_len);
-               if (i % 4 == 3) printf("\n");
-               len -= sizeof(xfs_extent_t);
-               ex++;
-       }
-       if (i % 4 != 0) printf("\n");
+
+       /* don't print extents as they are not used */
+
        return 0;
     } else {
        printf("EFD: Not enough data to decode further\n");
@@ -503,38 +499,50 @@ xlog_print_trans_efd(xfs_caddr_t *ptr, uint len)
 
 
 int
-xlog_print_trans_efi(xfs_caddr_t *ptr, uint len)
+xlog_print_trans_efi(xfs_caddr_t *ptr, uint src_len)
 {
-    xfs_efi_log_format_t *f;
+    xfs_efi_log_format_t *src_f, *f;
+    uint                dst_len;
     xfs_extent_t        *ex;
     int                         i;
-    xfs_efi_log_format_t lbuf;
+    int                         error = 0;
 
     /*
      * bcopy to ensure 8-byte alignment for the long longs in
      * xfs_efi_log_format_t structure
      */
-    bcopy(*ptr, &lbuf, len);
-    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;
-       len -= (sizeof(xfs_efi_log_format_t) - sizeof(xfs_extent_t));
-       for (i=0; len > 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");
-               len -= sizeof(xfs_extent_t);
-               ex++;
-       }
-       if (i % 4 != 0) printf("\n");
-       return 0;
-    } else {
-       printf("EFI: Not enough data to decode further\n");
-       return 1;
+    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);
+    }
+    bcopy(*ptr, (char*)src_f, 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 */
 
 
@@ -616,12 +624,11 @@ xlog_print_dir_sf(xfs_dir_shortform_t *sfp, int size)
 int
 xlog_print_trans_inode(xfs_caddr_t *ptr, int len, int *i, int num_ops)
 {
-    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};
+    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;
 
@@ -631,41 +638,27 @@ xlog_print_trans_inode(xfs_caddr_t *ptr, int len, int *i, int num_ops)
      * bcopy to ensure 8-byte alignment for the long longs in
      * xfs_inode_log_format_t structure
      *
-     * len can be smaller than xfs_inode_log_format_t sometimes... (?)
+     * len can be smaller than xfs_inode_log_format_32|64_t 
+     * if format data is split over operations
      */
-    bcopy(*ptr, &lbuf, MIN(sizeof(xfs_inode_log_format_t), len));
-    version = lbuf.ilf_type;
-    f = &lbuf;
+    bcopy(*ptr, &src_lbuf, MIN(sizeof(xfs_inode_log_format_64_t), 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 (len == sizeof(xfs_inode_log_format_32_t) ||
+       len == sizeof(xfs_inode_log_format_64_t)) {
+       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 = (xfs_inode_log_format_t *)&src_lbuf;
+       printf("INODE: #regs: %d   Not printing rest of data\n",
+              f->ilf_size);
+       return f->ilf_size;
     }
 
     if (*i >= num_ops)                 /* end of LR */
@@ -1020,8 +1013,6 @@ xlog_print_record(int                       fd,
                                        &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),
@@ -1515,3 +1506,96 @@ end:
     printf("%s: logical end of log\n", progname);
     print_xlog_record_line();
 }
+
+/*
+ * 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
+ */
+xfs_inode_log_format_t *
+xfs_inode_item_format_convert(char *src_buf, uint len, xfs_inode_log_format_t *in_f)
+{
+       /* 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(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;
+}
+
+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;
+}
index f819e6b7ef1d86e0c0c21db3e5fe4840e957b671..6238bd43e2453a06b14fa7d5d0d82e32019ac932 100644 (file)
@@ -108,8 +108,8 @@ xlog_recover_print_buffer(
                break;
        }
        if (f->blf_type == XFS_LI_BUF) {
-               printf("#regs:%d   start blkno:0x%llx   len:%d   bmap size:%d\n",
-                      f->blf_size, (long long)f->blf_blkno, f->blf_len, f->blf_map_size);
+               printf("#regs:%d   start blkno:0x%llx   len:%d   bmap size:%d   flags:0x%x\n",
+                      f->blf_size, (long long)f->blf_blkno, f->blf_len, f->blf_map_size, f->blf_flags);
                blkno = (xfs_daddr_t)f->blf_blkno;
        } else {
                printf("#regs:%d   start blkno:0x%x   len:%d   bmap size:%d\n",
@@ -276,13 +276,16 @@ STATIC void
 xlog_recover_print_inode(
        xlog_recover_item_t     *item)
 {
+       xfs_inode_log_format_t  f_buf;
        xfs_inode_log_format_t  *f;
        int                     attr_index;
        int                     hasdata;
        int                     hasattr;
 
-       f = (xfs_inode_log_format_t *)item->ri_buf[0].i_addr;
-       ASSERT(item->ri_buf[0].i_len == sizeof(xfs_inode_log_format_t));
+       ASSERT(item->ri_buf[0].i_len == sizeof(xfs_inode_log_format_32_t) ||
+              item->ri_buf[0].i_len == sizeof(xfs_inode_log_format_64_t));
+       f = xfs_inode_item_format_convert(item->ri_buf[0].i_addr, item->ri_buf[0].i_len, &f_buf);
+
        printf("        INODE: #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);
@@ -371,30 +374,16 @@ xlog_recover_print_efd(
        xlog_recover_item_t     *item)
 {
        xfs_efd_log_format_t    *f;
-       xfs_extent_t            *ex;
-       int                     i;
 
        f = (xfs_efd_log_format_t *)item->ri_buf[0].i_addr;
        /*
         * An xfs_efd_log_format structure contains a variable length array
-        * as the last field.  Each element is of size xfs_extent_t.
+        * as the last field.
+        * Each element is of size xfs_extent_32_t or xfs_extent_64_t.
+        * However, the extents are never used and won't be printed.
         */
-       ASSERT(item->ri_buf[0].i_len ==
-              sizeof(xfs_efd_log_format_t) + sizeof(xfs_extent_t) *
-              (f->efd_nextents-1));
        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;
-       printf("        ");
-       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");
 }
 
 
@@ -402,18 +391,28 @@ STATIC void
 xlog_recover_print_efi(
        xlog_recover_item_t     *item)
 {
-       xfs_efi_log_format_t    *f;
+       xfs_efi_log_format_t    *f, *src_f;
        xfs_extent_t            *ex;
        int                     i;
+       uint                    src_len, dst_len;
 
-       f = (xfs_efi_log_format_t *)item->ri_buf[0].i_addr;
+       src_f = (xfs_efi_log_format_t *)item->ri_buf[0].i_addr;
+       src_len = item->ri_buf[0].i_len;
        /*
         * An xfs_efi_log_format structure contains a variable length array
-        * as the last field.  Each element is of size xfs_extent_t.
+        * as the last field.
+        * Each element is of size xfs_extent_32_t or xfs_extent_64_t.
+        * Need to convert to native format.
         */
-       ASSERT(item->ri_buf[0].i_len ==
-              sizeof(xfs_efi_log_format_t) + sizeof(xfs_extent_t) *
-              (f->efi_nextents-1));
+       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_recover_print_efi: malloc failed\n", progname);
+           exit(1);
+       }
+       if (xfs_efi_copy_format((char*)src_f, src_len, f)) {
+           free(f);
+           return;
+       }
 
        printf("        EFI:  #regs:%d    num_extents:%d  id:0x%llx\n",
               f->efi_size, f->efi_nextents, (unsigned long long)f->efi_id);
@@ -428,6 +427,7 @@ xlog_recover_print_efi(
        }
        if (i % 4 != 0)
                printf("\n");
+       free(f);
 }
 
 void
index be6e991df8cd7505dfecd58a7df9244d9ce4d829..df4cea3743199135766a2b51e08a48d0cb2c4ef4 100644 (file)
@@ -45,4 +45,8 @@ extern void print_xlog_record_line(void);
 extern void print_xlog_op_line(void);
 extern void print_stars(void);
 
+extern xfs_inode_log_format_t *
+       xfs_inode_item_format_convert(char *, uint, xfs_inode_log_format_t *);
+extern int xfs_efi_copy_format(char *, uint, xfs_efi_log_format_t *);
+
 #endif /* LOGPRINT_H */