/*
 * Copyright (C) 2000-2003 ASANO Masahiro
 */

#include "def.h"

#define __KERNEL__
#include <xfs.h>
#include <xfs_log.h>
#include <xfs_trans.h>

void
prhead_xfs_log_item()
{
	mprintf(SPTR"      LSN "SPTR" "SPTR" "SPTR" "SPTR" "SPTR" TYPE     FLAGS\n",
		"ADDR", "DESC", "MOUNTP", "BIO_LIST", "CB", "OPS");
}

addr_t
print_xfs_log_item(addr)
	addr_t addr;
{
	xfs_log_item_t li;
	static const struct bitname liflags[] = {
		{ XFS_LI_IN_AIL,	"in_ail" },
		{ XFS_LI_ABORTED,	"aborted" },
		{ 0,			NULL }
	};

	memread(addr, sizeof(li), &li, "xfs_log_item_t");
	mprintf(FPTR " ", addr);

	mprintf("%8lx ", (long)li.li_lsn);
	mprintf(FPTR " " FPTR, li.li_desc, li.li_mountp);
	mprintf(" " FPTR " " FPTR " " FPTR " ",
		li.li_bio_list, li.li_cb, li.li_ops);

	switch (li.li_type) {
	case XFS_LI_5_3_BUF:	mprintf("5.3BUF  ");	break;
	case XFS_LI_5_3_INODE:	mprintf("5.3INODE");	break;
	case XFS_LI_EFI:	mprintf("EFI     ");	break;
	case XFS_LI_EFD:	mprintf("EFD     ");	break;
	case XFS_LI_IUNLINK:	mprintf("IUNLINK ");	break;
	case XFS_LI_6_1_INODE:	mprintf("6.1INODE");	break;
	case XFS_LI_6_1_BUF:	mprintf("6.1BUF  ");	break;
	case XFS_LI_INODE:	mprintf("INODE   ");	break;
	case XFS_LI_BUF:	mprintf("BUF     ");	break;
	case XFS_LI_DQUOT:	mprintf("DQUOT   ");	break;
	case XFS_LI_QUOTAOFF:	mprintf("QUOTAOFF");	break;
#ifdef XFS_LI_RPC
	case XFS_LI_RPC:	mprintf("RPC     ");	break;
#endif
	}
	mprintbit(liflags, li.li_flags);
	mprintf("\n");

	return (addr_t)li.li_ail.ail_forw;
}

const char *
xfs_transaction_type(t)
	int t;
{
	switch (t) {
	case XFS_TRANS_SETATTR_NOT_SIZE:	return "setattr_not_size";
	case XFS_TRANS_SETATTR_SIZE:		return "setattr_size";
	case XFS_TRANS_INACTIVE:		return "inactive";
	case XFS_TRANS_CREATE:			return "create";
	case XFS_TRANS_CREATE_TRUNC:		return "create_trunc";
	case XFS_TRANS_TRUNCATE_FILE:		return "truncate_file";
	case XFS_TRANS_REMOVE:			return "remove";
	case XFS_TRANS_LINK:			return "link";
	case XFS_TRANS_RENAME:			return "rename";
	case XFS_TRANS_MKDIR:			return "mkdir";
	case XFS_TRANS_RMDIR:			return "rmdir";
	case XFS_TRANS_SYMLINK:			return "symlink";
	case XFS_TRANS_SET_DMATTRS:		return "set_dmattrs";
	case XFS_TRANS_GROWFS:			return "growfs";
	case XFS_TRANS_STRAT_WRITE:		return "strat_write";
	case XFS_TRANS_DIOSTRAT:		return "diostrat";
	case XFS_TRANS_WRITE_SYNC:		return "write_sync";
	case XFS_TRANS_WRITEID:			return "writeio";
	case XFS_TRANS_ADDAFORK:		return "addafork";
	case XFS_TRANS_ATTRINVAL:		return "attrinval";
	case XFS_TRANS_ATRUNCATE:		return "atruncate";
	case XFS_TRANS_ATTR_SET:		return "attr_set";
	case XFS_TRANS_ATTR_RM:			return "attr_rm";
	case XFS_TRANS_CLEAR_AGI_BUCKET:	return "clear_agi_bucket";
	case XFS_TRANS_QM_SBCHANGE:		return "qm_sbchange";
	case XFS_TRANS_DUMMY1:			return "dummy1";
	case XFS_TRANS_DUMMY2:			return "dummy2";
	case XFS_TRANS_QM_QUOTAOFF:		return "qm_quotaoff";
	case XFS_TRANS_QM_DQALLOC:		return "qm_dqalloc";
	case XFS_TRANS_QM_SETQLIM:		return "qm_setqlim";
	case XFS_TRANS_QM_DQCLUSTER:		return "qm_dqcluster";
	case XFS_TRANS_QM_QINOCREATE:		return "qm_qinocreate";
	case XFS_TRANS_QM_QUOTAOFF_END:		return "qm_quotaoff_end";
	case XFS_TRANS_SB_UNIT:			return "sb_unit";
	case XFS_TRANS_FSYNC_TS:		return "fsync_ts";
	case XFS_TRANS_GROWFSRT_ALLOC:		return "growfsrt_alloc";	
	case XFS_TRANS_GROWFSRT_ZERO:		return "growfsrt_zero";
	case XFS_TRANS_GROWFSRT_FREE:		return "growfsrt_Free";
	case XFS_TRANS_SWAPEXT:			return "swapext";
	default:				return "<unknown>";
	}
}

addr_t
print_xfs_trans(addr)
	addr_t addr;
{
	struct xfs_trans trans;

	memread(addr, sizeof(trans), &trans, "xfs_trans_t");
	mprintf("addr:         " FPTR "\n", addr);

	mprintf("magic:        %x\n", trans.t_magic);
	mprintf("logcb:        " FPTR "\n", trans.t_logcb);
	mprintf("forw:         " FPTR "\n", trans.t_forw);
	mprintf("back:         " FPTR "\n", trans.t_back);
	mprintf("type:         %x  %s\n", trans.t_type, xfs_transaction_type(trans.t_type));
	mprintf("log_res:      %x\n", trans.t_log_res);
	mprintf("log_count:    %x\n", trans.t_log_count);
	mprintf("blk_res:      %x\n", trans.t_blk_res);
	mprintf("blk_res_used: %x\n", trans.t_blk_res_used);
	mprintf("rtx_res:      %x\n", trans.t_rtx_res);
	mprintf("rtx_res_used: %x\n", trans.t_rtx_res_used);
	mprintf("ticket:       " FPTR "\n", addr + OFFSET(struct xfs_trans, t_ticket));
	mprintf("sema:         \n");	/*XXX*/
	mprintf("lsn:          %lx\n", (long)trans.t_ticket);
	mprintf("mountp:       " FPTR "\n", trans.t_mountp);
	mprintf("dqinfo:       " FPTR "\n", trans.t_dqinfo);
	mprintf("callback:     " FPTR "\n", trans.t_callback);
	mprintf("flags:        %x\n", trans.t_flags);
	mprintf("icount_delta:        %lx\n", trans.t_icount_delta);
	mprintf("ifree_delta:         %lx\n", trans.t_ifree_delta);
	mprintf("fdblocks_delta:      %lx\n", trans.t_fdblocks_delta);
	mprintf("res_fdblocks_delta:  %lx\n", trans.t_res_fdblocks_delta);
	mprintf("frextents_delta:     %lx\n", trans.t_frextents_delta);
	mprintf("res_frextents_delta: %lx\n", trans.t_res_frextents_delta);
	mprintf("ag_freeblks_delta    %lx\n", trans.t_ag_freeblks_delta);
	mprintf("ag_flist_delta:      %lx\n", trans.t_ag_flist_delta);
	mprintf("ag_btree_delta:      %lx\n", trans.t_ag_btree_delta);
	mprintf("dblocks_delta:       %lx\n", trans.t_dblocks_delta);
	mprintf("agcount_delta:       %lx\n", trans.t_agcount_delta);
	mprintf("imaxpct_delta:       %lx\n", trans.t_imaxpct_delta);
	mprintf("rextsize_delta:      %lx\n", trans.t_rextsize_delta);
	mprintf("rbmblocks_delta:     %lx\n", trans.t_rbmblocks_delta);
	mprintf("rblocks_delta:       %lx\n", trans.t_rblocks_delta);
	mprintf("rextents_delta:      %lx\n", trans.t_rextents_delta);
	mprintf("rextslog_delta:      %lx\n", trans.t_rextslog_delta);
	mprintf("items_free:   %x\n", trans.t_items_free);
	mprintf("...\n");
	return 0;
}
