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

#include "def.h"

#define __KERNEL__
#include <xfs.h>
#include <xfs_inum.h>
#include <xfs_log.h>
#include <xfs_trans.h>
#include <xfs_sb.h>
#include <xfs_dir.h>
#include <xfs_dir2.h>
#include <xfs_dmapi.h>
#include <xfs_mount.h>
#include <xfs_bmap_btree.h>
#include <xfs_attr_sf.h>
#include <xfs_dir_sf.h>
#include <xfs_dir2_sf.h>
#include <xfs_dinode.h>
#include <xfs_inode.h>

#include "flags_mount.h"

#define	IFLAG	1
#define	LFLAG	2
#define HFLAG	4

extern void prhead_xfs_inode();
extern void prhead_xfs_log_item();
extern addr_t print_xfs_inode();
extern addr_t print_xfs_log_item();

addr_t
print_xfs_mount(addr, flag)
	addr_t addr;
	int flag;
{
	xfs_mount_t m;
	char name[32];
#if 0
	static const struct bitname mflags[] = {
		{ XFS_MOUNT_WSYNC,		"wsync" },
#ifdef XFS_MOUNT_INO64
		{ XFS_MOUNT_INO64,		"ino64" },
#endif
#ifdef XFS_MOUNT_ROOTQCHECK
		{ XFS_MOUNT_ROOTQCHECK,		"rootqcheck" },
#endif
		{ XFS_MOUNT_FS_SHUTDOWN,	"fs_shutdown" },
		{ XFS_MOUNT_NOATIME,		"noatime" },
		{ XFS_MOUNT_RETERR,		"reterr" },
		{ XFS_MOUNT_NOALIGN,		"noalign" },
#ifdef XFS_MOUNT_REGISTERED
		{ XFS_MOUNT_REGISTERED,		"registered" },
#endif
		{ XFS_MOUNT_NORECOVERY,		"norecovery" },
		{ XFS_MOUNT_SHARED,		"shared" },
		{ XFS_MOUNT_DFLT_IOSIZE,	"dflt_iosize" },
#ifdef XFS_MOUNT_OSYNCISOSYNC
		{ XFS_MOUNT_OSYNCISOSYNC,	"osyncisosync" },
#endif
#ifdef XFS_MOUNT_OSYNCISDSYNC
		{ XFS_MOUNT_OSYNCISDSYNC,	"osyncisdsync" },
#endif
		{ XFS_MOUNT_NOUUID,		"nouuid" },
#ifdef XFS_MOUNT_32BITINODES
		{ XFS_MOUNT_32BITINODES,	"32bitinodes" },
#endif
#ifdef XFS_MOUNT_IRIXSGID
		{ XFS_MOUNT_IRIXSGID,		"irixsgid" },
#endif
#ifdef XFS_MOUNT_NOLOGFLUSH
		{ XFS_MOUNT_NOLOGFLUSH,		"nologflush" },
#endif
		{ 0,				NULL }
	};
#endif

	mprintf("addr     " FPTR "\n", addr);
	memread(addr, sizeof(m), &m, "xfs_mount_t");

	mprintf("ail.forw " FPTR "\n", m.m_ail.ail_forw);
	mprintf("ail.back " FPTR "\n", m.m_ail.ail_back);
	mprintf("sb_bp    " FPTR "\n", m.m_sb_bp);
	mprintf("fsname   " FPTR "  \"", m.m_fsname);
	memread((addr_t)m.m_fsname, sizeof(name), name, "xfs_mount.m_fsname");
	mprint_str(name, sizeof(name));
	mprintf("\"\n");
	mprintf("bsize         %x\n", m.m_bsize);
	mprintf("ihsize         %x\n", m.m_ihsize);
	mprintf("ihash    " FPTR "\n", m.m_ihash);
	mprintf("inodes   " FPTR "\n", m.m_inodes);
	mprintf("ireclaims      %x\n", m.m_ireclaims);
	mprintf("readio_log     %x\n", m.m_readio_log);
	mprintf("readio_blocks  %x\n", m.m_readio_blocks);
	mprintf("writeio_log    %x\n", m.m_writeio_log);
	mprintf("writeio_blocks %x\n", m.m_writeio_blocks);
	mprintf("logbufs        %x\n", m.m_logbufs);
	mprintf("logbsize       %x\n", m.m_logbsize);
	mprintf("log      " FPTR "\n", m.m_log);
	mprintf("rbmip    " FPTR "\n", m.m_rbmip);
	mprintf("rsumip   " FPTR "\n", m.m_rsumip);
	mprintf("rootip   " FPTR "\n", m.m_rootip);
#ifdef _xfs_mount_has_m_logdev_targp
	/* new style */
	mprintf("m_ddev_targp   " FPTR "\n", m.m_ddev_targp);
	mprintf("m_logdev_targp " FPTR "\n", m.m_logdev_targp);
#else
	/* old fashion */
	mprintf("m_ddev_targ   " FPTR " " FPTR " %04x\n",
		m.m_ddev_targ.pb_targ, m.m_ddev_targ.bd_targ, m.m_ddev_targ.dev);
	mprintf("m_logdev_targ " FPTR " " FPTR " %04x\n",
		m.m_logdev_targ.pb_targ, m.m_logdev_targ.bd_targ, m.m_logdev_targ.dev);
#endif
	mprintf("flags    ");
	mprintbit(mflags, m.m_flags);
	mprintf("\n");

	if (flag & HFLAG) {
		int n;
		mprintf("XFS_INODE HASH\n");
		prhead_xfs_inode();
		for (n = 0; n < m.m_ihsize; n++) {
			struct xfs_ihash hash;
			addr_t tmp;
			memread((addr_t)m.m_ihash + sizeof(hash) * n, sizeof(hash), &hash, "xfs_ihash");
			tmp = (addr_t)hash.ih_next;
			while (tmp) {
				tmp = print_xfs_inode(tmp, 0, 1);
			}
		}
		prhead_xfs_inode();
	}

	if (flag & IFLAG) {
		addr_t top, tmp;

		tmp = top = (addr_t)m.m_inodes;
		mprintf("XFS_INODE\n");
		prhead_xfs_inode();
		while (tmp) {
			tmp = print_xfs_inode(tmp, 0, 0);
			if (tmp == top)
				break;
		}
		prhead_xfs_inode();
	}

	if (flag & LFLAG) {
		addr_t tmp = (addr_t)m.m_ail.ail_forw;
		mprintf("AIL\n");
		prhead_xfs_log_item();
		while (tmp && tmp != addr + OFFSET(xfs_mount_t, m_ail)) {
			tmp = print_xfs_log_item(tmp);
		}
	}

	return 0;
}
