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

#include "def.h"

#define __KERNEL__
#include <asm/param.h>
#include <linux/wait.h>
#include <linux/socket.h>
#include <linux/sunrpc/svc.h>
#include <linux/nfsd/nfsd.h>

#include "printdev.h"
#include "flags_nfsd_export.h"

void
prhead_svc_export()
{
	mprintf(SPTR" " SPTR " " SPTR " " SPTR " " SPTR "   DEV     INO NAME\n", "ADDR",
		"PARENT", "CLIENT", "MNT", "DENTRY");
}

addr_t
print_svc_export(addr, full)
	addr_t addr;
	int full;
{
	struct svc_export exp;

	memread(addr, sizeof(exp), &exp, "svc_export");
	mprintf(FPTR " ", addr);
#ifdef _svc_export_has_ex_parent
	mprintf(FPTR " ", exp.ex_parent);
#endif /*_svc_export_has_ex_parent*/
	mprintf(FPTR " " FPTR " " FPTR " ",
		exp.ex_client, exp.ex_mnt, exp.ex_dentry);
	mprint_kdev_t(exp.ex_dev);
	mprintf("%6ld ", exp.ex_ino);
	mprintstr(exp.ex_path, sizeof(exp.ex_path));
	mprintbit(expflags, exp.ex_flags);
	mprintf("\n");
#ifdef _svc_export_has_ex_list
	return (addr_t)exp.ex_list.next;
#else
#ifdef _svc_export_has_ex_next
	return (addr_t)exp.ex_next;
#else
	return 0;
#endif /*_svc_export_has_ex_next*/
#endif /*_svc_export_has_ex_list*/
}

void
prhead_svc_client()
{
	mprintf(SPTR" NADDR  ADDR[0]  ADDR[1] "SPTR" IDENT\n", "ADDR",
		"UMAP");
}

addr_t
print_svc_client(addr, full)
	addr_t addr;
	int full;
{
	struct svc_client client;

	memread(addr, sizeof(client), &client, "svc_client");
	mprintf(FPTR " ", addr);
	mprintf("%5x ", client.cl_naddr);
	mprintf("%8x ", htonl(client.cl_addr[0].s_addr));
	if (client.cl_naddr >= 2)
		mprintf("%8x ", htonl(client.cl_addr[1].s_addr));
	else
		mprintf("       - ");
	mprintf(FPTR " ", client.cl_umap);
	mprintstr(client.cl_ident, sizeof(client.cl_ident));
	mprintf("\n");
	if (full) {
#ifdef _svc_client_has_cl_list
		addr_t tmp = (addr_t)client.cl_list.next;
		prhead_svc_export();
		while (tmp && tmp != addr + OFFSET(struct svc_client, cl_list)) {
			tmp = print_svc_export(tmp - OFFSET(struct svc_export, ex_list), 0);
		}
#else
#ifdef _svc_client_has_cl_export
		int i;
		prhead_svc_export();
		for (i = 0; i < NFSCLNT_EXPMAX; i++) {
			addr_t tmp = (addr_t)client.cl_export[i];
			while (tmp) {
				tmp = print_svc_export(tmp, 0);
			}
		}
#endif /*_svc_client_has_cl_export*/
#endif /*_svc_client_has_cl_list*/
		mprintf("\n");
	}
	return (addr_t)client.cl_next;
}
