From: Tim Shimmin Date: Fri, 16 Jun 2006 03:52:27 +0000 (+0000) Subject: Fix up logprint so that 32 bit or 64 bit versions of logprint binaries X-Git-Tag: v2.9.0~83 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=299173ff65160a5d8ce977264d065c9bfb520155;p=thirdparty%2Fxfsprogs-dev.git Fix up logprint so that 32 bit or 64 bit versions of logprint binaries 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. --- diff --git a/include/xfs_extfree_item.h b/include/xfs_extfree_item.h index 5bf681708..0ea45edaa 100644 --- a/include/xfs_extfree_item.h +++ b/include/xfs_extfree_item.h @@ -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__ */ diff --git a/include/xfs_inode_item.h b/include/xfs_inode_item.h index c5dbf93b6..5db6cd1b4 100644 --- a/include/xfs_inode_item.h +++ b/include/xfs_inode_item.h @@ -23,25 +23,6 @@ * 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__ */ diff --git a/logprint/log_misc.c b/logprint/log_misc.c index 35fcfc582..920c7b2c9 100644 --- a/logprint/log_misc.c +++ b/logprint/log_misc.c @@ -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; +} diff --git a/logprint/log_print_all.c b/logprint/log_print_all.c index f819e6b7e..6238bd43e 100644 --- a/logprint/log_print_all.c +++ b/logprint/log_print_all.c @@ -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 diff --git a/logprint/logprint.h b/logprint/logprint.h index be6e991df..df4cea374 100644 --- a/logprint/logprint.h +++ b/logprint/logprint.h @@ -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 */