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
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
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__
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__ */
* 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 */
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.
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__ */
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
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;
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) {
}
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 {
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");
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 */
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;
* 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 */
&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),
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;
+}
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",
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);
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");
}
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);
}
if (i % 4 != 0)
printf("\n");
+ free(f);
}
void