| // SPDX-License-Identifier: GPL-2.0 | 
 | /* | 
 |  * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. | 
 |  * All Rights Reserved. | 
 |  */ | 
 | #include "libxfs.h" | 
 | #include "libxlog.h" | 
 |  | 
 | #include "logprint.h" | 
 |  | 
 | /* | 
 |  * Start is defined to be the block pointing to the oldest valid log record. | 
 |  */ | 
 | int | 
 | xlog_print_find_oldest( | 
 | 	struct xlog	*log, | 
 | 	xfs_daddr_t	*last_blk) | 
 | { | 
 | 	xfs_buf_t	*bp; | 
 | 	xfs_daddr_t	first_blk; | 
 | 	uint		first_half_cycle, last_half_cycle; | 
 | 	int		error = 0; | 
 |  | 
 | 	if (xlog_find_zeroed(log, &first_blk)) | 
 | 		return 0; | 
 |  | 
 | 	first_blk = 0;		/* read first block */ | 
 | 	bp = xlog_get_bp(log, 1); | 
 | 	xlog_bread_noalign(log, 0, 1, bp); | 
 | 	first_half_cycle = xlog_get_cycle(bp->b_addr); | 
 | 	*last_blk = log->l_logBBsize-1;	/* read last block */ | 
 | 	xlog_bread_noalign(log, *last_blk, 1, bp); | 
 | 	last_half_cycle = xlog_get_cycle(bp->b_addr); | 
 | 	ASSERT(last_half_cycle != 0); | 
 |  | 
 | 	if (first_half_cycle == last_half_cycle) /* all cycle nos are same */ | 
 | 		*last_blk = 0; | 
 | 	else		/* have 1st and last; look for middle cycle */ | 
 | 		error = xlog_find_cycle_start(log, bp, first_blk, | 
 | 					      last_blk, last_half_cycle); | 
 |  | 
 | 	xlog_put_bp(bp); | 
 | 	return error; | 
 | } | 
 |  | 
 | void | 
 | xlog_recover_print_data( | 
 | 	char		*p, | 
 | 	int		len) | 
 | { | 
 | 	if (print_data) { | 
 | 		uint *dp  = (uint *)p; | 
 | 		int  nums = len >> 2; | 
 | 		int  j = 0; | 
 |  | 
 | 		while (j < nums) { | 
 | 			if ((j % 8) == 0) | 
 | 				printf("%2x ", j); | 
 | 			printf("%8x ", *dp); | 
 | 			dp++; | 
 | 			j++; | 
 | 			if ((j % 8) == 0) | 
 | 				printf("\n"); | 
 | 		} | 
 | 		printf("\n"); | 
 | 	} | 
 | } | 
 |  | 
 | STATIC void | 
 | xlog_recover_print_buffer( | 
 | 	xlog_recover_item_t	*item) | 
 | { | 
 | 	xfs_agi_t		*agi; | 
 | 	xfs_agf_t		*agf; | 
 | 	xfs_buf_log_format_t	*f; | 
 | 	char			*p; | 
 | 	int			len, num, i; | 
 | 	xfs_daddr_t		blkno; | 
 | 	xfs_disk_dquot_t	*ddq; | 
 |  | 
 | 	f = (xfs_buf_log_format_t *)item->ri_buf[0].i_addr; | 
 | 	printf("	"); | 
 | 	ASSERT(f->blf_type == XFS_LI_BUF); | 
 | 	printf(_("BUF:  #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; | 
 | 	num = f->blf_size-1; | 
 | 	i = 1; | 
 | 	while (num-- > 0) { | 
 | 		p = item->ri_buf[i].i_addr; | 
 | 		len = item->ri_buf[i].i_len; | 
 | 		i++; | 
 | 		if (blkno == 0) { /* super block */ | 
 | 			printf(_("	SUPER Block Buffer:\n")); | 
 | 			if (!print_buffer) | 
 | 				continue; | 
 | 		       printf(_("              icount:%llu ifree:%llu  "), | 
 | 			       (unsigned long long) | 
 | 				       be64_to_cpu(*(__be64 *)(p)), | 
 | 			       (unsigned long long) | 
 | 				       be64_to_cpu(*(__be64 *)(p+8))); | 
 | 		       printf(_("fdblks:%llu  frext:%llu\n"), | 
 | 			       (unsigned long long) | 
 | 				       be64_to_cpu(*(__be64 *)(p+16)), | 
 | 			       (unsigned long long) | 
 | 				       be64_to_cpu(*(__be64 *)(p+24))); | 
 | 			printf(_("		sunit:%u  swidth:%u\n"), | 
 | 			       be32_to_cpu(*(__be32 *)(p+56)), | 
 | 			       be32_to_cpu(*(__be32 *)(p+60))); | 
 | 		} else if (be32_to_cpu(*(__be32 *)p) == XFS_AGI_MAGIC) { | 
 | 			int bucket, buckets; | 
 | 			agi = (xfs_agi_t *)p; | 
 | 			printf(_("	AGI Buffer: (XAGI)\n")); | 
 | 			if (!print_buffer) | 
 | 				continue; | 
 | 			printf(_("		ver:%d  "), | 
 | 				be32_to_cpu(agi->agi_versionnum)); | 
 | 			printf(_("seq#:%d  len:%d  cnt:%d  root:%d\n"), | 
 | 				be32_to_cpu(agi->agi_seqno), | 
 | 				be32_to_cpu(agi->agi_length), | 
 | 				be32_to_cpu(agi->agi_count), | 
 | 				be32_to_cpu(agi->agi_root)); | 
 | 			printf(_("		level:%d  free#:0x%x  newino:0x%x\n"), | 
 | 				be32_to_cpu(agi->agi_level), | 
 | 				be32_to_cpu(agi->agi_freecount), | 
 | 				be32_to_cpu(agi->agi_newino)); | 
 | 			if (len == 128) { | 
 | 				buckets = 17; | 
 | 			} else if (len == 256) { | 
 | 				buckets = 32 + 17; | 
 | 			} else { | 
 | 				buckets = XFS_AGI_UNLINKED_BUCKETS; | 
 | 			} | 
 | 			for (bucket = 0; bucket < buckets;) { | 
 | 				int col; | 
 | 				printf(_("bucket[%d - %d]: "), bucket, bucket+3); | 
 | 				for (col = 0; col < 4; col++, bucket++) { | 
 | 					if (bucket < buckets) { | 
 | 						printf("0x%x ", | 
 | 			be32_to_cpu(agi->agi_unlinked[bucket])); | 
 | 					} | 
 | 				} | 
 | 				printf("\n"); | 
 | 			} | 
 | 		} else if (be32_to_cpu(*(__be32 *)p) == XFS_AGF_MAGIC) { | 
 | 			agf = (xfs_agf_t *)p; | 
 | 			printf(_("	AGF Buffer: (XAGF)\n")); | 
 | 			if (!print_buffer) | 
 | 				continue; | 
 | 			printf(_("		ver:%d  seq#:%d  len:%d  \n"), | 
 | 				be32_to_cpu(agf->agf_versionnum), | 
 | 				be32_to_cpu(agf->agf_seqno), | 
 | 				be32_to_cpu(agf->agf_length)); | 
 | 			printf(_("		root BNO:%d  CNT:%d\n"), | 
 | 				be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNOi]), | 
 | 				be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNTi])); | 
 | 			printf(_("		level BNO:%d  CNT:%d\n"), | 
 | 				be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]), | 
 | 				be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi])); | 
 | 			printf(_("		1st:%d  last:%d  cnt:%d  " | 
 | 				"freeblks:%d  longest:%d\n"), | 
 | 				be32_to_cpu(agf->agf_flfirst), | 
 | 				be32_to_cpu(agf->agf_fllast), | 
 | 				be32_to_cpu(agf->agf_flcount), | 
 | 				be32_to_cpu(agf->agf_freeblks), | 
 | 				be32_to_cpu(agf->agf_longest)); | 
 | 		} else if (*(uint *)p == XFS_DQUOT_MAGIC) { | 
 | 			ddq = (xfs_disk_dquot_t *)p; | 
 | 			printf(_("	DQUOT Buffer:\n")); | 
 | 			if (!print_buffer) | 
 | 				continue; | 
 | 			printf(_("		UIDs 0x%lx-0x%lx\n"), | 
 | 			       (unsigned long)be32_to_cpu(ddq->d_id), | 
 | 			       (unsigned long)be32_to_cpu(ddq->d_id) + | 
 | 			       (BBTOB(f->blf_len) / sizeof(xfs_dqblk_t)) - 1); | 
 | 		} else { | 
 | 			printf(_("	BUF DATA\n")); | 
 | 			if (!print_buffer) continue; | 
 | 			xlog_recover_print_data(p, len); | 
 | 		} | 
 | 	} | 
 | } | 
 |  | 
 | STATIC void | 
 | xlog_recover_print_quotaoff( | 
 | 	xlog_recover_item_t	*item) | 
 | { | 
 | 	xfs_qoff_logformat_t	*qoff_f; | 
 | 	char			str[32] = { 0 }; | 
 |  | 
 | 	qoff_f = (xfs_qoff_logformat_t *)item->ri_buf[0].i_addr; | 
 | 	ASSERT(qoff_f); | 
 | 	if (qoff_f->qf_flags & XFS_UQUOTA_ACCT) | 
 | 		strcat(str, "USER QUOTA"); | 
 | 	if (qoff_f->qf_flags & XFS_GQUOTA_ACCT) | 
 | 		strcat(str, "GROUP QUOTA"); | 
 | 	if (qoff_f->qf_flags & XFS_PQUOTA_ACCT) | 
 | 		strcat(str, "PROJECT QUOTA"); | 
 | 	printf(_("\tQUOTAOFF: #regs:%d   type:%s\n"), | 
 | 	       qoff_f->qf_size, str); | 
 | } | 
 |  | 
 | STATIC void | 
 | xlog_recover_print_dquot( | 
 | 	xlog_recover_item_t	*item) | 
 | { | 
 | 	xfs_dq_logformat_t	*f; | 
 | 	xfs_disk_dquot_t	*d; | 
 |  | 
 | 	f = (xfs_dq_logformat_t *)item->ri_buf[0].i_addr; | 
 | 	ASSERT(f); | 
 | 	ASSERT(f->qlf_len == 1); | 
 | 	d = (xfs_disk_dquot_t *)item->ri_buf[1].i_addr; | 
 | 	printf(_("\tDQUOT: #regs:%d  blkno:%lld  boffset:%u id: %d\n"), | 
 | 	       f->qlf_size, (long long)f->qlf_blkno, f->qlf_boffset, f->qlf_id); | 
 | 	if (!print_quota) | 
 | 		return; | 
 | 	printf(_("\t\tmagic 0x%x\tversion 0x%x\tID 0x%x (%d)\t\n"), | 
 | 	       be16_to_cpu(d->d_magic), | 
 | 	       d->d_version, | 
 | 	       be32_to_cpu(d->d_id), | 
 | 	       be32_to_cpu(d->d_id)); | 
 | 	printf(_("\t\tblk_hard 0x%x\tblk_soft 0x%x\tino_hard 0x%x" | 
 | 	       "\tino_soft 0x%x\n"), | 
 | 	       (int)be64_to_cpu(d->d_blk_hardlimit), | 
 | 	       (int)be64_to_cpu(d->d_blk_softlimit), | 
 | 	       (int)be64_to_cpu(d->d_ino_hardlimit), | 
 | 	       (int)be64_to_cpu(d->d_ino_softlimit)); | 
 | 	printf(_("\t\tbcount 0x%x (%d) icount 0x%x (%d)\n"), | 
 | 	       (int)be64_to_cpu(d->d_bcount), | 
 | 	       (int)be64_to_cpu(d->d_bcount), | 
 | 	       (int)be64_to_cpu(d->d_icount), | 
 | 	       (int)be64_to_cpu(d->d_icount)); | 
 | 	printf(_("\t\tbtimer 0x%x itimer 0x%x \n"), | 
 | 	       (int)be32_to_cpu(d->d_btimer), | 
 | 	       (int)be32_to_cpu(d->d_itimer)); | 
 | } | 
 |  | 
 | STATIC void | 
 | xlog_recover_print_inode_core( | 
 | 	struct xfs_log_dinode	*di) | 
 | { | 
 | 	printf(_("	CORE inode:\n")); | 
 | 	if (!print_inode) | 
 | 		return; | 
 | 	printf(_("		magic:%c%c  mode:0x%x  ver:%d  format:%d\n"), | 
 | 	       (di->di_magic>>8) & 0xff, di->di_magic & 0xff, | 
 | 	       di->di_mode, di->di_version, di->di_format); | 
 | 	printf(_("		uid:%d  gid:%d  nlink:%d projid:0x%04x%04x\n"), | 
 | 	       di->di_uid, di->di_gid, di->di_nlink, | 
 | 	       di->di_projid_hi, di->di_projid_lo); | 
 | 	printf(_("		atime:%d  mtime:%d  ctime:%d\n"), | 
 | 	       di->di_atime.t_sec, di->di_mtime.t_sec, di->di_ctime.t_sec); | 
 | 	printf(_("		flushiter:%d\n"), di->di_flushiter); | 
 | 	printf(_("		size:0x%llx  nblks:0x%llx  exsize:%d  " | 
 | 	     "nextents:%d  anextents:%d\n"), (unsigned long long) | 
 | 	       di->di_size, (unsigned long long)di->di_nblocks, | 
 | 	       di->di_extsize, di->di_nextents, (int)di->di_anextents); | 
 | 	printf(_("		forkoff:%d  dmevmask:0x%x  dmstate:%d  flags:0x%x  " | 
 | 	     "gen:%u\n"), | 
 | 	       (int)di->di_forkoff, di->di_dmevmask, (int)di->di_dmstate, | 
 | 	       (int)di->di_flags, di->di_gen); | 
 | 	if (di->di_version == 3) { | 
 | 		printf(_("		flags2 0x%llx cowextsize 0x%x\n"), | 
 | 			(unsigned long long)di->di_flags2, di->di_cowextsize); | 
 | 	} | 
 | } | 
 |  | 
 | STATIC void | 
 | xlog_recover_print_inode( | 
 | 	xlog_recover_item_t	*item) | 
 | { | 
 | 	struct xfs_inode_log_format	f_buf; | 
 | 	struct xfs_inode_log_format	*f; | 
 | 	int			attr_index; | 
 | 	int			hasdata; | 
 | 	int			hasattr; | 
 |  | 
 | 	ASSERT(item->ri_buf[0].i_len == sizeof(struct xfs_inode_log_format_32) || | 
 | 	       item->ri_buf[0].i_len == sizeof(struct xfs_inode_log_format)); | 
 | 	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); | 
 |  | 
 | 	/* core inode comes 2nd */ | 
 | 	ASSERT(item->ri_buf[1].i_len == xfs_log_dinode_size(2) || | 
 | 		item->ri_buf[1].i_len == xfs_log_dinode_size(3)); | 
 | 	xlog_recover_print_inode_core((struct xfs_log_dinode *) | 
 | 				      item->ri_buf[1].i_addr); | 
 |  | 
 | 	hasdata = (f->ilf_fields & XFS_ILOG_DFORK) != 0; | 
 | 	hasattr = (f->ilf_fields & XFS_ILOG_AFORK) != 0; | 
 | 	/* does anything come next */ | 
 | 	switch (f->ilf_fields & (XFS_ILOG_DFORK|XFS_ILOG_DEV|XFS_ILOG_UUID)) { | 
 | 	case XFS_ILOG_DEXT: | 
 | 		ASSERT(f->ilf_size == 3 + hasattr); | 
 | 		printf(_("		DATA FORK EXTENTS inode data:\n")); | 
 | 		if (print_inode && print_data) | 
 | 			xlog_recover_print_data(item->ri_buf[2].i_addr, | 
 | 						item->ri_buf[2].i_len); | 
 | 		break; | 
 | 	case XFS_ILOG_DBROOT: | 
 | 		ASSERT(f->ilf_size == 3 + hasattr); | 
 | 		printf(_("		DATA FORK BTREE inode data:\n")); | 
 | 		if (print_inode && print_data) | 
 | 			xlog_recover_print_data(item->ri_buf[2].i_addr, | 
 | 						item->ri_buf[2].i_len); | 
 | 		break; | 
 | 	case XFS_ILOG_DDATA: | 
 | 		ASSERT(f->ilf_size == 3 + hasattr); | 
 | 		printf(_("		DATA FORK LOCAL inode data:\n")); | 
 | 		if (print_inode && print_data) | 
 | 			xlog_recover_print_data(item->ri_buf[2].i_addr, | 
 | 						item->ri_buf[2].i_len); | 
 | 		break; | 
 | 	case XFS_ILOG_DEV: | 
 | 		ASSERT(f->ilf_size == 2 + hasattr); | 
 | 		printf(_("		DEV inode: no extra region\n")); | 
 | 		break; | 
 | 	case XFS_ILOG_UUID: | 
 | 		ASSERT(f->ilf_size == 2 + hasattr); | 
 | 		printf(_("		UUID inode: no extra region\n")); | 
 | 		break; | 
 |  | 
 | 	case 0: | 
 | 		ASSERT(f->ilf_size == 2 + hasattr); | 
 | 		break; | 
 | 	default: | 
 | 		xlog_panic("xlog_print_trans_inode: illegal inode type"); | 
 | 	} | 
 |  | 
 | 	if (hasattr) { | 
 | 		attr_index = 2 + hasdata; | 
 | 		switch (f->ilf_fields & XFS_ILOG_AFORK) { | 
 | 		case XFS_ILOG_AEXT: | 
 | 			ASSERT(f->ilf_size == 3 + hasdata); | 
 | 			printf(_("		ATTR FORK EXTENTS inode data:\n")); | 
 | 			if (print_inode && print_data) | 
 | 				xlog_recover_print_data( | 
 | 					item->ri_buf[attr_index].i_addr, | 
 | 					item->ri_buf[attr_index].i_len); | 
 | 			break; | 
 | 		case XFS_ILOG_ABROOT: | 
 | 			ASSERT(f->ilf_size == 3 + hasdata); | 
 | 			printf(_("		ATTR FORK BTREE inode data:\n")); | 
 | 			if (print_inode && print_data) | 
 | 				xlog_recover_print_data( | 
 | 					item->ri_buf[attr_index].i_addr, | 
 | 					item->ri_buf[attr_index].i_len); | 
 | 			break; | 
 | 		case XFS_ILOG_ADATA: | 
 | 			ASSERT(f->ilf_size == 3 + hasdata); | 
 | 			printf(_("		ATTR FORK LOCAL inode data:\n")); | 
 | 			if (print_inode && print_data) | 
 | 				xlog_recover_print_data( | 
 | 					item->ri_buf[attr_index].i_addr, | 
 | 					item->ri_buf[attr_index].i_len); | 
 | 			break; | 
 | 		default: | 
 | 			xlog_panic("%s: illegal inode log flag", __FUNCTION__); | 
 | 		} | 
 | 	} | 
 | } | 
 |  | 
 |  | 
 | STATIC void | 
 | xlog_recover_print_icreate( | 
 | 	struct xlog_recover_item	*item) | 
 | { | 
 | 	struct xfs_icreate_log	*icl; | 
 |  | 
 | 	icl = (struct xfs_icreate_log *)item->ri_buf[0].i_addr; | 
 |  | 
 | 	printf(_("	ICR:  #ag: %d  agbno: 0x%x  len: %d\n" | 
 | 		 "	      cnt: %d  isize: %d    gen: 0x%x\n"), | 
 | 		be32_to_cpu(icl->icl_ag), be32_to_cpu(icl->icl_agbno), | 
 | 		be32_to_cpu(icl->icl_length), be32_to_cpu(icl->icl_count), | 
 | 		be32_to_cpu(icl->icl_isize), be32_to_cpu(icl->icl_gen)); | 
 | } | 
 |  | 
 | void | 
 | xlog_recover_print_logitem( | 
 | 	xlog_recover_item_t	*item) | 
 | { | 
 | 	switch (ITEM_TYPE(item)) { | 
 | 	case XFS_LI_BUF: | 
 | 		xlog_recover_print_buffer(item); | 
 | 		break; | 
 | 	case XFS_LI_ICREATE: | 
 | 		xlog_recover_print_icreate(item); | 
 | 		break; | 
 | 	case XFS_LI_INODE: | 
 | 		xlog_recover_print_inode(item); | 
 | 		break; | 
 | 	case XFS_LI_EFD: | 
 | 		xlog_recover_print_efd(item); | 
 | 		break; | 
 | 	case XFS_LI_EFI: | 
 | 		xlog_recover_print_efi(item); | 
 | 		break; | 
 | 	case XFS_LI_RUD: | 
 | 		xlog_recover_print_rud(item); | 
 | 		break; | 
 | 	case XFS_LI_RUI: | 
 | 		xlog_recover_print_rui(item); | 
 | 		break; | 
 | 	case XFS_LI_CUD: | 
 | 		xlog_recover_print_cud(item); | 
 | 		break; | 
 | 	case XFS_LI_CUI: | 
 | 		xlog_recover_print_cui(item); | 
 | 		break; | 
 | 	case XFS_LI_BUD: | 
 | 		xlog_recover_print_bud(item); | 
 | 		break; | 
 | 	case XFS_LI_BUI: | 
 | 		xlog_recover_print_bui(item); | 
 | 		break; | 
 | 	case XFS_LI_DQUOT: | 
 | 		xlog_recover_print_dquot(item); | 
 | 		break; | 
 | 	case XFS_LI_QUOTAOFF: | 
 | 		xlog_recover_print_quotaoff(item); | 
 | 		break; | 
 | 	default: | 
 | 		printf(_("xlog_recover_print_logitem: illegal type\n")); | 
 | 		break; | 
 | 	} | 
 | } | 
 |  | 
 | static void | 
 | xlog_recover_print_item( | 
 | 	xlog_recover_item_t	*item) | 
 | { | 
 | 	int			i; | 
 |  | 
 | 	switch (ITEM_TYPE(item)) { | 
 | 	case XFS_LI_BUF: | 
 | 		printf("BUF"); | 
 | 		break; | 
 | 	case XFS_LI_ICREATE: | 
 | 		printf("ICR"); | 
 | 		break; | 
 | 	case XFS_LI_INODE: | 
 | 		printf("INO"); | 
 | 		break; | 
 | 	case XFS_LI_EFD: | 
 | 		printf("EFD"); | 
 | 		break; | 
 | 	case XFS_LI_EFI: | 
 | 		printf("EFI"); | 
 | 		break; | 
 | 	case XFS_LI_RUD: | 
 | 		printf("RUD"); | 
 | 		break; | 
 | 	case XFS_LI_RUI: | 
 | 		printf("RUI"); | 
 | 		break; | 
 | 	case XFS_LI_CUD: | 
 | 		printf("CUD"); | 
 | 		break; | 
 | 	case XFS_LI_CUI: | 
 | 		printf("CUI"); | 
 | 		break; | 
 | 	case XFS_LI_BUD: | 
 | 		printf("BUD"); | 
 | 		break; | 
 | 	case XFS_LI_BUI: | 
 | 		printf("BUI"); | 
 | 		break; | 
 | 	case XFS_LI_DQUOT: | 
 | 		printf("DQ "); | 
 | 		break; | 
 | 	case XFS_LI_QUOTAOFF: | 
 | 		printf("QOFF"); | 
 | 		break; | 
 | 	default: | 
 | 		cmn_err(CE_PANIC, _("%s: illegal type"), __FUNCTION__); | 
 | 		break; | 
 | 	} | 
 |  | 
 | /*	type isn't filled in yet | 
 | 	printf(_("ITEM: type: %d cnt: %d total: %d "), | 
 | 	       item->ri_type, item->ri_cnt, item->ri_total); | 
 | */ | 
 | 	printf(_(": cnt:%d total:%d "), item->ri_cnt, item->ri_total); | 
 | 	for (i=0; i<item->ri_cnt; i++) { | 
 | 		printf(_("a:0x%lx len:%d "), | 
 | 		       (long)item->ri_buf[i].i_addr, item->ri_buf[i].i_len); | 
 | 	} | 
 | 	printf("\n"); | 
 | 	xlog_recover_print_logitem(item); | 
 | } | 
 |  | 
 | void | 
 | xlog_recover_print_trans( | 
 | 	xlog_recover_t		*trans, | 
 | 	struct list_head	*itemq, | 
 | 	int			print) | 
 | { | 
 | 	xlog_recover_item_t	*item; | 
 |  | 
 | 	if (print < 3) | 
 | 		return; | 
 |  | 
 | 	print_xlog_record_line(); | 
 | 	xlog_recover_print_trans_head(trans); | 
 | 	list_for_each_entry(item, itemq, ri_list) | 
 | 		xlog_recover_print_item(item); | 
 | } |