[XFS] inode items and EFI/EFDs have different ondisk format for 32bit and
authorTim Shimmin <tes@sgi.com>
Fri, 9 Jun 2006 04:55:38 +0000 (14:55 +1000)
committerNathan Scott <nathans@sgi.com>
Fri, 9 Jun 2006 04:55:38 +0000 (14:55 +1000)
64bit kernels allow recovery to handle both versions and do the necessary
decoding

SGI-PV: 952214
SGI-Modid: xfs-linux-melb:xfs-kern:26011a

Signed-off-by: Tim Shimmin <tes@sgi.com>
Signed-off-by: Nathan Scott <nathans@sgi.com>
fs/xfs/xfs_extfree_item.c
fs/xfs/xfs_extfree_item.h
fs/xfs/xfs_inode_item.c
fs/xfs/xfs_inode_item.h
fs/xfs/xfs_log_recover.c

index f19282e..8b028f1 100644 (file)
@@ -294,6 +294,62 @@ xfs_efi_init(xfs_mount_t   *mp,
 }
 
 /*
+ * Copy an EFI format buffer from the given buf, and into the destination
+ * EFI format structure.
+ * The given buffer can be in 32 bit or 64 bit form (which has different padding),
+ * one of which will be the native format for this kernel.
+ * It will handle the conversion of formats if necessary.
+ */
+int
+xfs_efi_copy_format(xfs_log_iovec_t *buf, xfs_efi_log_format_t *dst_efi_fmt)
+{
+       xfs_efi_log_format_t *src_efi_fmt = (xfs_efi_log_format_t *)buf->i_addr;
+       uint i;
+       uint len = sizeof(xfs_efi_log_format_t) + 
+               (src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_t);  
+       uint len32 = sizeof(xfs_efi_log_format_32_t) + 
+               (src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_32_t);  
+       uint len64 = sizeof(xfs_efi_log_format_64_t) + 
+               (src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_64_t);  
+
+       if (buf->i_len == len) {
+               memcpy((char *)dst_efi_fmt, (char*)src_efi_fmt, len);
+               return 0;
+       } else if (buf->i_len == len32) {
+               xfs_efi_log_format_32_t *src_efi_fmt_32 =
+                       (xfs_efi_log_format_32_t *)buf->i_addr;
+
+               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 (buf->i_len == len64) {
+               xfs_efi_log_format_64_t *src_efi_fmt_64 =
+                       (xfs_efi_log_format_64_t *)buf->i_addr;
+
+               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;
+       }
+       return EFSCORRUPTED;
+}
+
+/*
  * This is called by the efd item code below to release references to
  * the given efi item.  Each efd calls this with the number of
  * extents that it has logged, and when the sum of these reaches
index 5bf6817..0ea45ed 100644 (file)
@@ -27,6 +27,24 @@ typedef struct xfs_extent {
 } 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
  * size is given by efi_nextents.
@@ -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 7497a48..cd65a56 100644 (file)
@@ -1084,3 +1084,52 @@ xfs_istale_done(
 {
        xfs_iflush_abort(iip->ili_inode);
 }
+
+/*
+ * convert an xfs_inode_log_format struct from either 32 or 64 bit versions
+ * (which can have different field alignments) to the native version
+ */
+int
+xfs_inode_item_format_convert(
+       xfs_log_iovec_t         *buf,
+       xfs_inode_log_format_t  *in_f)
+{
+       if (buf->i_len == sizeof(xfs_inode_log_format_32_t)) {
+               xfs_inode_log_format_32_t *in_f32;
+
+               in_f32 = (xfs_inode_log_format_32_t *)buf->i_addr;
+               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.ilfu_uuid.__u_bits,
+                      in_f32->ilf_u.ilfu_uuid.__u_bits,
+                      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;
+               return 0;
+       } else if (buf->i_len == sizeof(xfs_inode_log_format_64_t)){
+               xfs_inode_log_format_64_t *in_f64;
+
+               in_f64 = (xfs_inode_log_format_64_t *)buf->i_addr;
+               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 field of ilf_u */
+               memcpy(in_f->ilf_u.ilfu_uuid.__u_bits,
+                      in_f64->ilf_u.ilfu_uuid.__u_bits,
+                      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 0;
+       }
+       return EFSCORRUPTED;
+}
index c5dbf93..5db6cd1 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 1f0016b..efffa75 100644 (file)
@@ -2292,12 +2292,22 @@ xlog_recover_do_inode_trans(
        int                     attr_index;
        uint                    fields;
        xfs_dinode_core_t       *dicp;
+       int                     need_free = 0;
 
        if (pass == XLOG_RECOVER_PASS1) {
                return 0;
        }
 
-       in_f = (xfs_inode_log_format_t *)item->ri_buf[0].i_addr;
+       if (item->ri_buf[0].i_len == sizeof(xfs_inode_log_format_t)) {
+               in_f = (xfs_inode_log_format_t *)item->ri_buf[0].i_addr;
+       } else {
+               in_f = (xfs_inode_log_format_t *)kmem_alloc(
+                       sizeof(xfs_inode_log_format_t), KM_SLEEP);
+               need_free = 1;
+               error = xfs_inode_item_format_convert(&item->ri_buf[0], in_f);
+               if (error)
+                       goto error;
+       }
        ino = in_f->ilf_ino;
        mp = log->l_mp;
        if (ITEM_TYPE(item) == XFS_LI_INODE) {
@@ -2323,8 +2333,10 @@ xlog_recover_do_inode_trans(
         * Inode buffers can be freed, look out for it,
         * and do not replay the inode.
         */
-       if (xlog_check_buffer_cancelled(log, imap.im_blkno, imap.im_len, 0))
-               return 0;
+       if (xlog_check_buffer_cancelled(log, imap.im_blkno, imap.im_len, 0)) {
+               error = 0;
+               goto error;
+       }
 
        bp = xfs_buf_read_flags(mp->m_ddev_targp, imap.im_blkno, imap.im_len,
                                                                XFS_BUF_LOCK);
@@ -2333,7 +2345,7 @@ xlog_recover_do_inode_trans(
                                  bp, imap.im_blkno);
                error = XFS_BUF_GETERROR(bp);
                xfs_buf_relse(bp);
-               return error;
+               goto error;
        }
        error = 0;
        ASSERT(in_f->ilf_fields & XFS_ILOG_CORE);
@@ -2350,7 +2362,8 @@ xlog_recover_do_inode_trans(
                        dip, bp, ino);
                XFS_ERROR_REPORT("xlog_recover_do_inode_trans(1)",
                                 XFS_ERRLEVEL_LOW, mp);
-               return XFS_ERROR(EFSCORRUPTED);
+               error = EFSCORRUPTED;
+               goto error;
        }
        dicp = (xfs_dinode_core_t*)(item->ri_buf[1].i_addr);
        if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) {
@@ -2360,7 +2373,8 @@ xlog_recover_do_inode_trans(
                        item, ino);
                XFS_ERROR_REPORT("xlog_recover_do_inode_trans(2)",
                                 XFS_ERRLEVEL_LOW, mp);
-               return XFS_ERROR(EFSCORRUPTED);
+               error = EFSCORRUPTED;
+               goto error;
        }
 
        /* Skip replay when the on disk inode is newer than the log one */
@@ -2376,7 +2390,8 @@ xlog_recover_do_inode_trans(
                        /* do nothing */
                } else {
                        xfs_buf_relse(bp);
-                       return 0;
+                       error = 0;
+                       goto error;
                }
        }
        /* Take the opportunity to reset the flush iteration count */
@@ -2391,7 +2406,8 @@ xlog_recover_do_inode_trans(
                        xfs_fs_cmn_err(CE_ALERT, mp,
                                "xfs_inode_recover: Bad regular inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
                                item, dip, bp, ino);
-                       return XFS_ERROR(EFSCORRUPTED);
+                       error = EFSCORRUPTED;
+                       goto error;
                }
        } else if (unlikely((dicp->di_mode & S_IFMT) == S_IFDIR)) {
                if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) &&
@@ -2403,7 +2419,8 @@ xlog_recover_do_inode_trans(
                        xfs_fs_cmn_err(CE_ALERT, mp,
                                "xfs_inode_recover: Bad dir inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
                                item, dip, bp, ino);
-                       return XFS_ERROR(EFSCORRUPTED);
+                       error = EFSCORRUPTED;
+                       goto error;
                }
        }
        if (unlikely(dicp->di_nextents + dicp->di_anextents > dicp->di_nblocks)){
@@ -2415,7 +2432,8 @@ xlog_recover_do_inode_trans(
                        item, dip, bp, ino,
                        dicp->di_nextents + dicp->di_anextents,
                        dicp->di_nblocks);
-               return XFS_ERROR(EFSCORRUPTED);
+               error = EFSCORRUPTED;
+               goto error;
        }
        if (unlikely(dicp->di_forkoff > mp->m_sb.sb_inodesize)) {
                XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(6)",
@@ -2424,7 +2442,8 @@ xlog_recover_do_inode_trans(
                xfs_fs_cmn_err(CE_ALERT, mp,
                        "xfs_inode_recover: Bad inode log rec ptr 0x%p, dino ptr 0x%p, dino bp 0x%p, ino %Ld, forkoff 0x%x",
                        item, dip, bp, ino, dicp->di_forkoff);
-               return XFS_ERROR(EFSCORRUPTED);
+               error = EFSCORRUPTED;
+               goto error;
        }
        if (unlikely(item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t))) {
                XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(7)",
@@ -2433,7 +2452,8 @@ xlog_recover_do_inode_trans(
                xfs_fs_cmn_err(CE_ALERT, mp,
                        "xfs_inode_recover: Bad inode log record length %d, rec ptr 0x%p",
                        item->ri_buf[1].i_len, item);
-               return XFS_ERROR(EFSCORRUPTED);
+               error = EFSCORRUPTED;
+               goto error;
        }
 
        /* The core is in in-core format */
@@ -2521,7 +2541,8 @@ xlog_recover_do_inode_trans(
                        xlog_warn("XFS: xlog_recover_do_inode_trans: Invalid flag");
                        ASSERT(0);
                        xfs_buf_relse(bp);
-                       return XFS_ERROR(EIO);
+                       error = EIO;
+                       goto error;
                }
        }
 
@@ -2537,7 +2558,10 @@ write_inode_buffer:
                error = xfs_bwrite(mp, bp);
        }
 
-       return (error);
+error:
+       if (need_free)
+               kmem_free(in_f, sizeof(*in_f));
+       return XFS_ERROR(error);
 }
 
 /*
@@ -2674,32 +2698,32 @@ xlog_recover_do_dquot_trans(
  * structure into it, and adds the efi to the AIL with the given
  * LSN.
  */
-STATIC void
+STATIC int
 xlog_recover_do_efi_trans(
        xlog_t                  *log,
        xlog_recover_item_t     *item,
        xfs_lsn_t               lsn,
        int                     pass)
 {
+       int                     error;
        xfs_mount_t             *mp;
        xfs_efi_log_item_t      *efip;
        xfs_efi_log_format_t    *efi_formatp;
        SPLDECL(s);
 
        if (pass == XLOG_RECOVER_PASS1) {
-               return;
+               return 0;
        }
 
        efi_formatp = (xfs_efi_log_format_t *)item->ri_buf[0].i_addr;
-       ASSERT(item->ri_buf[0].i_len ==
-              (sizeof(xfs_efi_log_format_t) +
-               ((efi_formatp->efi_nextents - 1) * sizeof(xfs_extent_t))));
 
        mp = log->l_mp;
        efip = xfs_efi_init(mp, efi_formatp->efi_nextents);
-       memcpy((char *)&(efip->efi_format), (char *)efi_formatp,
-             sizeof(xfs_efi_log_format_t) +
-             ((efi_formatp->efi_nextents - 1) * sizeof(xfs_extent_t)));
+       if ((error = xfs_efi_copy_format(&(item->ri_buf[0]),
+                                        &(efip->efi_format)))) {
+               xfs_efi_item_free(efip);
+               return error;
+       }
        efip->efi_next_extent = efi_formatp->efi_nextents;
        efip->efi_flags |= XFS_EFI_COMMITTED;
 
@@ -2708,6 +2732,7 @@ xlog_recover_do_efi_trans(
         * xfs_trans_update_ail() drops the AIL lock.
         */
        xfs_trans_update_ail(mp, (xfs_log_item_t *)efip, lsn, s);
+       return 0;
 }
 
 
@@ -2738,9 +2763,10 @@ xlog_recover_do_efd_trans(
        }
 
        efd_formatp = (xfs_efd_log_format_t *)item->ri_buf[0].i_addr;
-       ASSERT(item->ri_buf[0].i_len ==
-              (sizeof(xfs_efd_log_format_t) +
-               ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_t))));
+       ASSERT((item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_32_t) +
+               ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_32_t)))) ||
+              (item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_64_t) +
+               ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_64_t)))));
        efi_id = efd_formatp->efd_efi_id;
 
        /*
@@ -2810,15 +2836,14 @@ xlog_recover_do_trans(
                        if  ((error = xlog_recover_do_buffer_trans(log, item,
                                                                 pass)))
                                break;
-               } else if ((ITEM_TYPE(item) == XFS_LI_INODE) ||
-                          (ITEM_TYPE(item) == XFS_LI_6_1_INODE) ||
-                          (ITEM_TYPE(item) == XFS_LI_5_3_INODE)) {
+               } else if ((ITEM_TYPE(item) == XFS_LI_INODE)) {
                        if ((error = xlog_recover_do_inode_trans(log, item,
                                                                pass)))
                                break;
                } else if (ITEM_TYPE(item) == XFS_LI_EFI) {
-                       xlog_recover_do_efi_trans(log, item, trans->r_lsn,
-                                                 pass);
+                       if ((error = xlog_recover_do_efi_trans(log, item, trans->r_lsn,
+                                                 pass)))
+                               break;
                } else if (ITEM_TYPE(item) == XFS_LI_EFD) {
                        xlog_recover_do_efd_trans(log, item, pass);
                } else if (ITEM_TYPE(item) == XFS_LI_DQUOT) {
@@ -3798,7 +3823,7 @@ xlog_do_log_recovery(
        error = xlog_do_recovery_pass(log, head_blk, tail_blk,
                                      XLOG_RECOVER_PASS2);
 #ifdef DEBUG
-       {
+       if (!error) {
                int     i;
 
                for (i = 0; i < XLOG_BC_TABLE_SIZE; i++)