Index: sys/fs/nfs/nfs_commonkrpc.c
===================================================================
--- sys/fs/nfs/nfs_commonkrpc.c
+++ sys/fs/nfs/nfs_commonkrpc.c
@@ -89,7 +89,7 @@
 NFSSTATESPINLOCK;
 NFSREQSPINLOCK;
 NFSDLOCKMUTEX;
-extern struct nfsstats newnfsstats;
+extern struct nfsstatsv1 nfsstatsv1;
 extern struct nfsreqhead nfsd_reqq;
 extern int nfscl_ticks;
 extern void (*ncl_call_invalcaches)(struct vnode *);
@@ -642,7 +642,7 @@
 		procnum = NFSV4PROC_COMPOUND;
 
 	if (nmp != NULL) {
-		NFSINCRGLOBAL(newnfsstats.rpcrequests);
+		NFSINCRGLOBAL(nfsstatsv1.rpcrequests);
 
 		/* Map the procnum to the old NFSv2 one, as required. */
 		if ((nd->nd_flag & ND_NFSV2) != 0) {
@@ -762,18 +762,18 @@
 	if (stat == RPC_SUCCESS) {
 		error = 0;
 	} else if (stat == RPC_TIMEDOUT) {
-		NFSINCRGLOBAL(newnfsstats.rpctimeouts);
+		NFSINCRGLOBAL(nfsstatsv1.rpctimeouts);
 		error = ETIMEDOUT;
 	} else if (stat == RPC_VERSMISMATCH) {
-		NFSINCRGLOBAL(newnfsstats.rpcinvalid);
+		NFSINCRGLOBAL(nfsstatsv1.rpcinvalid);
 		error = EOPNOTSUPP;
 	} else if (stat == RPC_PROGVERSMISMATCH) {
-		NFSINCRGLOBAL(newnfsstats.rpcinvalid);
+		NFSINCRGLOBAL(nfsstatsv1.rpcinvalid);
 		error = EPROTONOSUPPORT;
 	} else if (stat == RPC_INTR) {
 		error = EINTR;
 	} else {
-		NFSINCRGLOBAL(newnfsstats.rpcinvalid);
+		NFSINCRGLOBAL(nfsstatsv1.rpcinvalid);
 		error = EACCES;
 	}
 	if (error) {
Index: sys/fs/nfs/nfs_commonport.c
===================================================================
--- sys/fs/nfs/nfs_commonport.c
+++ sys/fs/nfs/nfs_commonport.c
@@ -58,7 +58,7 @@
 extern int nfsrv_useacl;
 struct mount nfsv4root_mnt;
 int newnfs_numnfsd = 0;
-struct nfsstats newnfsstats;
+struct nfsstatsv1 nfsstatsv1;
 int nfs_numnfscbd = 0;
 int nfscl_debuglevel = 0;
 char nfsv4_callbackaddr[INET6_ADDRSTRLEN];
@@ -69,6 +69,7 @@
 
 static int nfs_realign_test;
 static int nfs_realign_count;
+static struct ext_nfsstats oldnfsstats;
 
 SYSCTL_NODE(_vfs, OID_AUTO, nfs, CTLFLAG_RW, 0, "NFS filesystem");
 SYSCTL_INT(_vfs_nfs, OID_AUTO, realign_test, CTLFLAG_RW, &nfs_realign_test,
@@ -446,9 +447,12 @@
 static int
 nfssvc_call(struct thread *p, struct nfssvc_args *uap, struct ucred *cred)
 {
-	int error = EINVAL;
+	int error = EINVAL, i, j;
 	struct nfsd_idargs nid;
 	struct nfsd_oidargs onid;
+	struct {
+		int vers;	/* Just the first field of nfsstats. */
+	} nfsstatver;
 
 	if (uap->flag & NFSSVC_IDNAME) {
 		if ((uap->flag & NFSSVC_NEWSTRUCT) != 0)
@@ -472,63 +476,157 @@
 		error = nfssvc_idname(&nid);
 		goto out;
 	} else if (uap->flag & NFSSVC_GETSTATS) {
-		error = copyout(&newnfsstats,
-		    CAST_USER_ADDR_T(uap->argp), sizeof (newnfsstats));
+		if ((uap->flag & NFSSVC_NEWSTRUCT) == 0) {
+			/* Copy fields to the old ext_nfsstat structure. */
+			oldnfsstats.attrcache_hits =
+			    nfsstatsv1.attrcache_hits;
+			oldnfsstats.attrcache_misses =
+			    nfsstatsv1.attrcache_misses;
+			oldnfsstats.lookupcache_hits =
+			    nfsstatsv1.lookupcache_hits;
+			oldnfsstats.lookupcache_misses =
+			    nfsstatsv1.lookupcache_misses;
+			oldnfsstats.direofcache_hits =
+			    nfsstatsv1.direofcache_hits;
+			oldnfsstats.direofcache_misses =
+			    nfsstatsv1.direofcache_misses;
+			oldnfsstats.accesscache_hits =
+			    nfsstatsv1.accesscache_hits;
+			oldnfsstats.accesscache_misses =
+			    nfsstatsv1.accesscache_misses;
+			oldnfsstats.biocache_reads =
+			    nfsstatsv1.biocache_reads;
+			oldnfsstats.read_bios =
+			    nfsstatsv1.read_bios;
+			oldnfsstats.read_physios =
+			    nfsstatsv1.read_physios;
+			oldnfsstats.biocache_writes =
+			    nfsstatsv1.biocache_writes;
+			oldnfsstats.write_bios =
+			    nfsstatsv1.write_bios;
+			oldnfsstats.write_physios =
+			    nfsstatsv1.write_physios;
+			oldnfsstats.biocache_readlinks =
+			    nfsstatsv1.biocache_readlinks;
+			oldnfsstats.readlink_bios =
+			    nfsstatsv1.readlink_bios;
+			oldnfsstats.biocache_readdirs =
+			    nfsstatsv1.biocache_readdirs;
+			oldnfsstats.readdir_bios =
+			    nfsstatsv1.readdir_bios;
+			for (i = 0; i < NFSV4_NPROCS; i++)
+				oldnfsstats.rpccnt[i] = nfsstatsv1.rpccnt[i];
+			oldnfsstats.rpcretries = nfsstatsv1.rpcretries;
+			for (i = 0; i < NFSV4OP_NOPS; i++)
+				oldnfsstats.srvrpccnt[i] =
+				    nfsstatsv1.srvrpccnt[i];
+			for (i = NFSV41_NOPS, j = NFSV4OP_NOPS;
+			    i < NFSV41_NOPS + NFSV4OP_FAKENOPS; i++, j++)
+				oldnfsstats.srvrpccnt[j] =
+				    nfsstatsv1.srvrpccnt[i];
+			oldnfsstats.srvrpc_errs = nfsstatsv1.srvrpc_errs;
+			oldnfsstats.srv_errs = nfsstatsv1.srv_errs;
+			oldnfsstats.rpcrequests = nfsstatsv1.rpcrequests;
+			oldnfsstats.rpctimeouts = nfsstatsv1.rpctimeouts;
+			oldnfsstats.rpcunexpected = nfsstatsv1.rpcunexpected;
+			oldnfsstats.rpcinvalid = nfsstatsv1.rpcinvalid;
+			oldnfsstats.srvcache_inproghits =
+			    nfsstatsv1.srvcache_inproghits;
+			oldnfsstats.srvcache_idemdonehits =
+			    nfsstatsv1.srvcache_idemdonehits;
+			oldnfsstats.srvcache_nonidemdonehits =
+			    nfsstatsv1.srvcache_nonidemdonehits;
+			oldnfsstats.srvcache_misses =
+			    nfsstatsv1.srvcache_misses;
+			oldnfsstats.srvcache_tcppeak =
+			    nfsstatsv1.srvcache_tcppeak;
+			oldnfsstats.srvcache_size = nfsstatsv1.srvcache_size;
+			oldnfsstats.srvclients = nfsstatsv1.srvclients;
+			oldnfsstats.srvopenowners = nfsstatsv1.srvopenowners;
+			oldnfsstats.srvopens = nfsstatsv1.srvopens;
+			oldnfsstats.srvlockowners = nfsstatsv1.srvlockowners;
+			oldnfsstats.srvlocks = nfsstatsv1.srvlocks;
+			oldnfsstats.srvdelegates = nfsstatsv1.srvdelegates;
+			for (i = 0; i < NFSV4OP_CBNOPS; i++)
+				oldnfsstats.cbrpccnt[i] =
+				    nfsstatsv1.cbrpccnt[i];
+			oldnfsstats.clopenowners = nfsstatsv1.clopenowners;
+			oldnfsstats.clopens = nfsstatsv1.clopens;
+			oldnfsstats.cllockowners = nfsstatsv1.cllockowners;
+			oldnfsstats.cllocks = nfsstatsv1.cllocks;
+			oldnfsstats.cldelegates = nfsstatsv1.cldelegates;
+			oldnfsstats.cllocalopenowners =
+			    nfsstatsv1.cllocalopenowners;
+			oldnfsstats.cllocalopens = nfsstatsv1.cllocalopens;
+			oldnfsstats.cllocallockowners =
+			    nfsstatsv1.cllocallockowners;
+			oldnfsstats.cllocallocks = nfsstatsv1.cllocallocks;
+			error = copyout(&oldnfsstats, uap->argp,
+			    sizeof (oldnfsstats));
+		} else {
+			error = copyin(uap->argp, &nfsstatver,
+			    sizeof(nfsstatver));
+			if (error == 0 && nfsstatver.vers != NFSSTATS_V1)
+				error = EPERM;
+			if (error == 0)
+				error = copyout(&nfsstatsv1, uap->argp,
+				    sizeof (nfsstatsv1));
+		}
 		if (error == 0) {
 			if ((uap->flag & NFSSVC_ZEROCLTSTATS) != 0) {
-				newnfsstats.attrcache_hits = 0;
-				newnfsstats.attrcache_misses = 0;
-				newnfsstats.lookupcache_hits = 0;
-				newnfsstats.lookupcache_misses = 0;
-				newnfsstats.direofcache_hits = 0;
-				newnfsstats.direofcache_misses = 0;
-				newnfsstats.accesscache_hits = 0;
-				newnfsstats.accesscache_misses = 0;
-				newnfsstats.biocache_reads = 0;
-				newnfsstats.read_bios = 0;
-				newnfsstats.read_physios = 0;
-				newnfsstats.biocache_writes = 0;
-				newnfsstats.write_bios = 0;
-				newnfsstats.write_physios = 0;
-				newnfsstats.biocache_readlinks = 0;
-				newnfsstats.readlink_bios = 0;
-				newnfsstats.biocache_readdirs = 0;
-				newnfsstats.readdir_bios = 0;
-				newnfsstats.rpcretries = 0;
-				newnfsstats.rpcrequests = 0;
-				newnfsstats.rpctimeouts = 0;
-				newnfsstats.rpcunexpected = 0;
-				newnfsstats.rpcinvalid = 0;
-				bzero(newnfsstats.rpccnt,
-				    sizeof(newnfsstats.rpccnt));
+				nfsstatsv1.attrcache_hits = 0;
+				nfsstatsv1.attrcache_misses = 0;
+				nfsstatsv1.lookupcache_hits = 0;
+				nfsstatsv1.lookupcache_misses = 0;
+				nfsstatsv1.direofcache_hits = 0;
+				nfsstatsv1.direofcache_misses = 0;
+				nfsstatsv1.accesscache_hits = 0;
+				nfsstatsv1.accesscache_misses = 0;
+				nfsstatsv1.biocache_reads = 0;
+				nfsstatsv1.read_bios = 0;
+				nfsstatsv1.read_physios = 0;
+				nfsstatsv1.biocache_writes = 0;
+				nfsstatsv1.write_bios = 0;
+				nfsstatsv1.write_physios = 0;
+				nfsstatsv1.biocache_readlinks = 0;
+				nfsstatsv1.readlink_bios = 0;
+				nfsstatsv1.biocache_readdirs = 0;
+				nfsstatsv1.readdir_bios = 0;
+				nfsstatsv1.rpcretries = 0;
+				nfsstatsv1.rpcrequests = 0;
+				nfsstatsv1.rpctimeouts = 0;
+				nfsstatsv1.rpcunexpected = 0;
+				nfsstatsv1.rpcinvalid = 0;
+				bzero(nfsstatsv1.rpccnt,
+				    sizeof(nfsstatsv1.rpccnt));
 			}
 			if ((uap->flag & NFSSVC_ZEROSRVSTATS) != 0) {
-				newnfsstats.srvrpc_errs = 0;
-				newnfsstats.srv_errs = 0;
-				newnfsstats.srvcache_inproghits = 0;
-				newnfsstats.srvcache_idemdonehits = 0;
-				newnfsstats.srvcache_nonidemdonehits = 0;
-				newnfsstats.srvcache_misses = 0;
-				newnfsstats.srvcache_tcppeak = 0;
-				newnfsstats.srvclients = 0;
-				newnfsstats.srvopenowners = 0;
-				newnfsstats.srvopens = 0;
-				newnfsstats.srvlockowners = 0;
-				newnfsstats.srvlocks = 0;
-				newnfsstats.srvdelegates = 0;
-				newnfsstats.clopenowners = 0;
-				newnfsstats.clopens = 0;
-				newnfsstats.cllockowners = 0;
-				newnfsstats.cllocks = 0;
-				newnfsstats.cldelegates = 0;
-				newnfsstats.cllocalopenowners = 0;
-				newnfsstats.cllocalopens = 0;
-				newnfsstats.cllocallockowners = 0;
-				newnfsstats.cllocallocks = 0;
-				bzero(newnfsstats.srvrpccnt,
-				    sizeof(newnfsstats.srvrpccnt));
-				bzero(newnfsstats.cbrpccnt,
-				    sizeof(newnfsstats.cbrpccnt));
+				nfsstatsv1.srvrpc_errs = 0;
+				nfsstatsv1.srv_errs = 0;
+				nfsstatsv1.srvcache_inproghits = 0;
+				nfsstatsv1.srvcache_idemdonehits = 0;
+				nfsstatsv1.srvcache_nonidemdonehits = 0;
+				nfsstatsv1.srvcache_misses = 0;
+				nfsstatsv1.srvcache_tcppeak = 0;
+				nfsstatsv1.srvclients = 0;
+				nfsstatsv1.srvopenowners = 0;
+				nfsstatsv1.srvopens = 0;
+				nfsstatsv1.srvlockowners = 0;
+				nfsstatsv1.srvlocks = 0;
+				nfsstatsv1.srvdelegates = 0;
+				nfsstatsv1.clopenowners = 0;
+				nfsstatsv1.clopens = 0;
+				nfsstatsv1.cllockowners = 0;
+				nfsstatsv1.cllocks = 0;
+				nfsstatsv1.cldelegates = 0;
+				nfsstatsv1.cllocalopenowners = 0;
+				nfsstatsv1.cllocalopens = 0;
+				nfsstatsv1.cllocallockowners = 0;
+				nfsstatsv1.cllocallocks = 0;
+				bzero(nfsstatsv1.srvrpccnt,
+				    sizeof(nfsstatsv1.srvrpccnt));
+				bzero(nfsstatsv1.cbrpccnt,
+				    sizeof(nfsstatsv1.cbrpccnt));
 			}
 		}
 		goto out;
Index: sys/fs/nfs/nfsport.h
===================================================================
--- sys/fs/nfs/nfsport.h
+++ sys/fs/nfs/nfsport.h
@@ -55,6 +55,7 @@
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
 #include <sys/mount.h>
+#include <sys/mutex.h>
 #include <sys/namei.h>
 #include <sys/proc.h>
 #include <sys/protosw.h>
@@ -261,17 +262,17 @@
 #define	NFSV4OP_OPILLEGAL	10044
 
 /*
- * Fake NFSV4OP_xxx used for nfsstat. Start at NFSV4OP_NOPS.
+ * Fake NFSV4OP_xxx used for nfsstat. Start at NFSV41_NOPS.
  */
-#define	NFSV4OP_SYMLINK		(NFSV4OP_NOPS)
-#define	NFSV4OP_MKDIR		(NFSV4OP_NOPS + 1)
-#define	NFSV4OP_RMDIR		(NFSV4OP_NOPS + 2)
-#define	NFSV4OP_READDIRPLUS	(NFSV4OP_NOPS + 3)
-#define	NFSV4OP_MKNOD		(NFSV4OP_NOPS + 4)
-#define	NFSV4OP_FSSTAT		(NFSV4OP_NOPS + 5)
-#define	NFSV4OP_FSINFO		(NFSV4OP_NOPS + 6)
-#define	NFSV4OP_PATHCONF	(NFSV4OP_NOPS + 7)
-#define	NFSV4OP_V3CREATE	(NFSV4OP_NOPS + 8)
+#define	NFSV4OP_SYMLINK		(NFSV41_NOPS)
+#define	NFSV4OP_MKDIR		(NFSV41_NOPS + 1)
+#define	NFSV4OP_RMDIR		(NFSV41_NOPS + 2)
+#define	NFSV4OP_READDIRPLUS	(NFSV41_NOPS + 3)
+#define	NFSV4OP_MKNOD		(NFSV41_NOPS + 4)
+#define	NFSV4OP_FSSTAT		(NFSV41_NOPS + 5)
+#define	NFSV4OP_FSINFO		(NFSV41_NOPS + 6)
+#define	NFSV4OP_PATHCONF	(NFSV41_NOPS + 7)
+#define	NFSV4OP_V3CREATE	(NFSV41_NOPS + 8)
 
 /*
  * This is the count of the fake operations listed above.
@@ -285,12 +286,12 @@
 #define	NFSV4OP_CBRECALL	4
 
 /*
- * Must be one greater than the last Callback Operation#.
+ * Must be one greater than the last Callback Operation# for NFSv4.0.
  */
 #define	NFSV4OP_CBNOPS		5
 
 /*
- * Additional Callback Ops for NFSv4.1 only. Not yet in nfsstats.
+ * Additional Callback Ops for NFSv4.1 only.
  */
 #define	NFSV4OP_CBLAYOUTRECALL	5
 #define	NFSV4OP_CBNOTIFY	6
@@ -303,6 +304,8 @@
 #define	NFSV4OP_CBNOTIFYLOCK	13
 #define	NFSV4OP_CBNOTIFYDEVID	14
 
+#define	NFSV41_CBNOPS		15
+
 /*
  * The lower numbers -> 21 are used by NFSv2 and v3. These define higher
  * numbers used by NFSv4.
@@ -360,7 +363,72 @@
 #endif	/* NFS_V3NPROCS */
 
 /*
- * Stats structure
+ * New stats structure.
+ * The vers field will be set to NFSSTATS_V1 by the caller.
+ */
+#define	NFSSTATS_V1	1
+struct nfsstatsv1 {
+	int		vers;	/* Set to version requested by caller. */
+	uint64_t	attrcache_hits;
+	uint64_t	attrcache_misses;
+	uint64_t	lookupcache_hits;
+	uint64_t	lookupcache_misses;
+	uint64_t	direofcache_hits;
+	uint64_t	direofcache_misses;
+	uint64_t	accesscache_hits;
+	uint64_t	accesscache_misses;
+	uint64_t	biocache_reads;
+	uint64_t	read_bios;
+	uint64_t	read_physios;
+	uint64_t	biocache_writes;
+	uint64_t	write_bios;
+	uint64_t	write_physios;
+	uint64_t	biocache_readlinks;
+	uint64_t	readlink_bios;
+	uint64_t	biocache_readdirs;
+	uint64_t	readdir_bios;
+	uint64_t	rpccnt[NFSV41_NPROCS + 10];
+	uint64_t	rpcretries;
+	uint64_t	srvrpccnt[NFSV41_NOPS + NFSV4OP_FAKENOPS + 10];
+	uint64_t	srvrpc_errs;
+	uint64_t	srv_errs;
+	uint64_t	rpcrequests;
+	uint64_t	rpctimeouts;
+	uint64_t	rpcunexpected;
+	uint64_t	rpcinvalid;
+	uint64_t	srvcache_inproghits;
+	uint64_t	srvcache_idemdonehits;
+	uint64_t	srvcache_nonidemdonehits;
+	uint64_t	srvcache_misses;
+	uint64_t	srvcache_tcppeak;
+	int		srvcache_size;	/* Updated by atomic_xx_int(). */
+	uint64_t	srvclients;
+	uint64_t	srvopenowners;
+	uint64_t	srvopens;
+	uint64_t	srvlockowners;
+	uint64_t	srvlocks;
+	uint64_t	srvdelegates;
+	uint64_t	cbrpccnt[NFSV41_CBNOPS + 10];
+	uint64_t	clopenowners;
+	uint64_t	clopens;
+	uint64_t	cllockowners;
+	uint64_t	cllocks;
+	uint64_t	cldelegates;
+	uint64_t	cllocalopenowners;
+	uint64_t	cllocalopens;
+	uint64_t	cllocallockowners;
+	uint64_t	cllocallocks;
+	uint64_t	srvstartcnt;
+	uint64_t	srvdonecnt;
+	uint64_t	srvbytes[NFSV41_NOPS + NFSV4OP_FAKENOPS + 10];
+	uint64_t	srvops[NFSV41_NOPS + NFSV4OP_FAKENOPS + 10];
+	struct bintime	srvduration[NFSV41_NOPS + NFSV4OP_FAKENOPS + 10];
+	struct bintime	busyfrom;
+	struct bintime	busytime;
+};
+
+/*
+ * Old stats structure.
  */
 struct ext_nfsstats {
 	int	attrcache_hits;
@@ -416,11 +484,6 @@
 
 #ifdef _KERNEL
 /*
- * Define the ext_nfsstats as nfsstats for the kernel code.
- */
-#define nfsstats	ext_nfsstats
-
-/*
  * Define NFS_NPROCS as NFSV4_NPROCS for the experimental kernel code.
  */
 #ifndef	NFS_NPROCS
Index: sys/fs/nfsclient/nfs_clbio.c
===================================================================
--- sys/fs/nfsclient/nfs_clbio.c
+++ sys/fs/nfsclient/nfs_clbio.c
@@ -60,7 +60,7 @@
 #include <fs/nfsclient/nfs_kdtrace.h>
 
 extern int newnfs_directio_allow_mmap;
-extern struct nfsstats newnfsstats;
+extern struct nfsstatsv1 nfsstatsv1;
 extern struct mtx ncl_iod_mutex;
 extern int ncl_numasync;
 extern enum nfsiod_state ncl_iodwant[NFS_MAXASYNCDAEMON];
@@ -466,7 +466,7 @@
 
 	    switch (vp->v_type) {
 	    case VREG:
-		NFSINCRGLOBAL(newnfsstats.biocache_reads);
+		NFSINCRGLOBAL(nfsstatsv1.biocache_reads);
 		lbn = uio->uio_offset / biosize;
 		on = uio->uio_offset - (lbn * biosize);
 
@@ -543,7 +543,7 @@
 			n = MIN((unsigned)(bcount - on), uio->uio_resid);
 		break;
 	    case VLNK:
-		NFSINCRGLOBAL(newnfsstats.biocache_readlinks);
+		NFSINCRGLOBAL(nfsstatsv1.biocache_readlinks);
 		bp = nfs_getcacheblk(vp, (daddr_t)0, NFS_MAXPATHLEN, td);
 		if (!bp) {
 			error = newnfs_sigintr(nmp, td);
@@ -563,7 +563,7 @@
 		on = 0;
 		break;
 	    case VDIR:
-		NFSINCRGLOBAL(newnfsstats.biocache_readdirs);
+		NFSINCRGLOBAL(nfsstatsv1.biocache_readdirs);
 		if (np->n_direofoffset
 		    && uio->uio_offset >= np->n_direofoffset) {
 		    return (0);
@@ -992,7 +992,7 @@
 			}
 		}
 
-		NFSINCRGLOBAL(newnfsstats.biocache_writes);
+		NFSINCRGLOBAL(nfsstatsv1.biocache_writes);
 		lbn = uio->uio_offset / biosize;
 		on = uio->uio_offset - (lbn * biosize);
 		n = MIN((unsigned)(biosize - on), uio->uio_resid);
@@ -1606,7 +1606,7 @@
 	    switch (vp->v_type) {
 	    case VREG:
 		uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE;
-		NFSINCRGLOBAL(newnfsstats.read_bios);
+		NFSINCRGLOBAL(nfsstatsv1.read_bios);
 		error = ncl_readrpc(vp, uiop, cr);
 
 		if (!error) {
@@ -1641,11 +1641,11 @@
 		break;
 	    case VLNK:
 		uiop->uio_offset = (off_t)0;
-		NFSINCRGLOBAL(newnfsstats.readlink_bios);
+		NFSINCRGLOBAL(nfsstatsv1.readlink_bios);
 		error = ncl_readlinkrpc(vp, uiop, cr);
 		break;
 	    case VDIR:
-		NFSINCRGLOBAL(newnfsstats.readdir_bios);
+		NFSINCRGLOBAL(nfsstatsv1.readdir_bios);
 		uiop->uio_offset = ((u_quad_t)bp->b_lblkno) * NFS_DIRBLKSIZ;
 		if ((nmp->nm_flag & NFSMNT_RDIRPLUS) != 0) {
 			error = ncl_readdirplusrpc(vp, uiop, cr, td);
@@ -1707,7 +1707,7 @@
 		    + bp->b_dirtyoff;
 		io.iov_base = (char *)bp->b_data + bp->b_dirtyoff;
 		uiop->uio_rw = UIO_WRITE;
-		NFSINCRGLOBAL(newnfsstats.write_bios);
+		NFSINCRGLOBAL(nfsstatsv1.write_bios);
 
 		if ((bp->b_flags & (B_ASYNC | B_NEEDCOMMIT | B_NOCACHE | B_CLUSTER)) == B_ASYNC)
 		    iomode = NFSWRITE_UNSTABLE;
Index: sys/fs/nfsclient/nfs_clcomsubs.c
===================================================================
--- sys/fs/nfsclient/nfs_clcomsubs.c
+++ sys/fs/nfsclient/nfs_clcomsubs.c
@@ -42,7 +42,7 @@
 #ifndef APPLEKEXT
 #include <fs/nfs/nfsport.h>
 
-extern struct nfsstats newnfsstats;
+extern struct nfsstatsv1 nfsstatsv1;
 extern struct nfsv4_opflag nfsv4_opflag[NFSV41_NOPS];
 extern int ncl_mbuf_mlen;
 extern enum vtype newnv2tov_type[8];
@@ -241,8 +241,8 @@
 	} else {
 		(void) nfsm_fhtom(nd, nfhp, fhlen, 0);
 	}
-	if (procnum < NFSV4_NPROCS)
-		NFSINCRGLOBAL(newnfsstats.rpccnt[procnum]);
+	if (procnum < NFSV41_NPROCS)
+		NFSINCRGLOBAL(nfsstatsv1.rpccnt[procnum]);
 }
 
 #ifndef APPLE
Index: sys/fs/nfsclient/nfs_clstate.c
===================================================================
--- sys/fs/nfsclient/nfs_clstate.c
+++ sys/fs/nfsclient/nfs_clstate.c
@@ -84,7 +84,7 @@
 /*
  * Global variables
  */
-extern struct nfsstats newnfsstats;
+extern struct nfsstatsv1 nfsstatsv1;
 extern struct nfsreqhead nfsd_reqq;
 extern u_int32_t newnfs_false, newnfs_true;
 extern int nfscl_debuglevel;
@@ -343,10 +343,10 @@
 		nowp->nfsow_defunct = 0;
 		nfscl_lockinit(&nowp->nfsow_rwlock);
 		if (dp != NULL) {
-			newnfsstats.cllocalopenowners++;
+			nfsstatsv1.cllocalopenowners++;
 			LIST_INSERT_HEAD(&dp->nfsdl_owner, nowp, nfsow_list);
 		} else {
-			newnfsstats.clopenowners++;
+			nfsstatsv1.clopenowners++;
 			LIST_INSERT_HEAD(&clp->nfsc_owner, nowp, nfsow_list);
 		}
 		owp = *owpp = nowp;
@@ -380,9 +380,9 @@
 				TAILQ_INSERT_HEAD(&clp->nfsc_deleg, dp,
 				    nfsdl_list);
 				dp->nfsdl_timestamp = NFSD_MONOSEC + 120;
-				newnfsstats.cllocalopens++;
+				nfsstatsv1.cllocalopens++;
 			} else {
-				newnfsstats.clopens++;
+				nfsstatsv1.clopens++;
 			}
 			LIST_INSERT_HEAD(&owp->nfsow_open, nop, nfso_list);
 			*opp = nop;
@@ -430,7 +430,7 @@
 		LIST_INSERT_HEAD(NFSCLDELEGHASH(clp, nfhp, fhlen), dp,
 		    nfsdl_hash);
 		dp->nfsdl_timestamp = NFSD_MONOSEC + 120;
-		newnfsstats.cldelegates++;
+		nfsstatsv1.cldelegates++;
 		nfscl_delegcnt++;
 	} else {
 		/*
@@ -1071,10 +1071,10 @@
 		LIST_INIT(&nlp->nfsl_lock);
 		if (donelocally) {
 			nlp->nfsl_open = NULL;
-			newnfsstats.cllocallockowners++;
+			nfsstatsv1.cllocallockowners++;
 		} else {
 			nlp->nfsl_open = op;
-			newnfsstats.cllockowners++;
+			nfsstatsv1.cllockowners++;
 		}
 		LIST_INSERT_HEAD(lhp, nlp, nfsl_list);
 		lp = nlp;
@@ -1402,9 +1402,9 @@
 	nfscl_freealllocks(&op->nfso_lock, local);
 	FREE((caddr_t)op, M_NFSCLOPEN);
 	if (local)
-		newnfsstats.cllocalopens--;
+		nfsstatsv1.cllocalopens--;
 	else
-		newnfsstats.clopens--;
+		nfsstatsv1.clopens--;
 }
 
 /*
@@ -1483,9 +1483,9 @@
 	LIST_REMOVE(owp, nfsow_list);
 	FREE((caddr_t)owp, M_NFSCLOWNER);
 	if (local)
-		newnfsstats.cllocalopenowners--;
+		nfsstatsv1.cllocalopenowners--;
 	else
-		newnfsstats.clopenowners--;
+		nfsstatsv1.clopenowners--;
 }
 
 /*
@@ -1502,9 +1502,9 @@
 	}
 	FREE((caddr_t)lp, M_NFSCLLOCKOWNER);
 	if (local)
-		newnfsstats.cllocallockowners--;
+		nfsstatsv1.cllocallockowners--;
 	else
-		newnfsstats.cllockowners--;
+		nfsstatsv1.cllockowners--;
 }
 
 /*
@@ -1517,9 +1517,9 @@
 	LIST_REMOVE(lop, nfslo_list);
 	FREE((caddr_t)lop, M_NFSCLLOCK);
 	if (local)
-		newnfsstats.cllocallocks--;
+		nfsstatsv1.cllocallocks--;
 	else
-		newnfsstats.cllocks--;
+		nfsstatsv1.cllocks--;
 }
 
 /*
@@ -1553,7 +1553,7 @@
 	TAILQ_REMOVE(hdp, dp, nfsdl_list);
 	LIST_REMOVE(dp, nfsdl_hash);
 	FREE((caddr_t)dp, M_NFSCLDELEG);
-	newnfsstats.cldelegates--;
+	nfsstatsv1.cldelegates--;
 	nfscl_delegcnt--;
 }
 
@@ -1621,18 +1621,18 @@
 			    LIST_REMOVE(op, nfso_list);
 			    op->nfso_own = towp;
 			    LIST_INSERT_HEAD(&towp->nfsow_open, op, nfso_list);
-			    newnfsstats.cllocalopens--;
-			    newnfsstats.clopens++;
+			    nfsstatsv1.cllocalopens--;
+			    nfsstatsv1.clopens++;
 			}
 		    } else {
 			/* Just add the openowner to the client list */
 			LIST_REMOVE(owp, nfsow_list);
 			owp->nfsow_clp = clp;
 			LIST_INSERT_HEAD(&clp->nfsc_owner, owp, nfsow_list);
-			newnfsstats.cllocalopenowners--;
-			newnfsstats.clopenowners++;
-			newnfsstats.cllocalopens--;
-			newnfsstats.clopens++;
+			nfsstatsv1.cllocalopenowners--;
+			nfsstatsv1.clopenowners++;
+			nfsstatsv1.cllocalopens--;
+			nfsstatsv1.clopens++;
 		    }
 		}
 		owp = nowp;
@@ -2282,9 +2282,9 @@
 	else
 		LIST_INSERT_AFTER(insert_lop, new_lop, nfslo_list);
 	if (local)
-		newnfsstats.cllocallocks++;
+		nfsstatsv1.cllocallocks++;
 	else
-		newnfsstats.cllocks++;
+		nfsstatsv1.cllocks++;
 }
 
 /*
@@ -2571,7 +2571,7 @@
 				    LIST_REMOVE(dp, nfsdl_hash);
 				    TAILQ_INSERT_HEAD(&dh, dp, nfsdl_list);
 				    nfscl_delegcnt--;
-				    newnfsstats.cldelegates--;
+				    nfsstatsv1.cldelegates--;
 				}
 				NFSLOCKCLSTATE();
 			}
@@ -2612,7 +2612,7 @@
 			    LIST_REMOVE(dp, nfsdl_hash);
 			    TAILQ_INSERT_HEAD(&dh, dp, nfsdl_list);
 			    nfscl_delegcnt--;
-			    newnfsstats.cldelegates--;
+			    nfsstatsv1.cldelegates--;
 			}
 		    }
 		    dp = ndp;
@@ -3215,8 +3215,8 @@
 		    break;
 		}
 		nd->nd_procnum = op;
-		if (op < NFSV4OP_CBNOPS)
-			newnfsstats.cbrpccnt[nd->nd_procnum]++;
+		if (op < NFSV41_CBNOPS)
+			nfsstatsv1.cbrpccnt[nd->nd_procnum]++;
 		switch (op) {
 		case NFSV4OP_CBGETATTR:
 			NFSCL_DEBUG(4, "cbgetattr\n");
Index: sys/fs/nfsclient/nfs_clsubs.c
===================================================================
--- sys/fs/nfsclient/nfs_clsubs.c
+++ sys/fs/nfsclient/nfs_clsubs.c
@@ -83,7 +83,7 @@
 extern struct nfsmount *ncl_iodmount[NFS_MAXASYNCDAEMON];
 extern int ncl_numasync;
 extern unsigned int ncl_iodmax;
-extern struct nfsstats newnfsstats;
+extern struct nfsstatsv1 nfsstatsv1;
 
 struct task	ncl_nfsiodnew_task;
 
@@ -234,7 +234,7 @@
 
 	if ((time_second - np->n_attrstamp) >= timeo &&
 	    (mustflush != 0 || np->n_attrstamp == 0)) {
-		newnfsstats.attrcache_misses++;
+		nfsstatsv1.attrcache_misses++;
 		mtx_unlock(&np->n_mtx);
 #ifdef NFS_ACDEBUG
 		mtx_unlock(&Giant);	/* ncl_printf() */
@@ -242,7 +242,7 @@
 		KDTRACE_NFS_ATTRCACHE_GET_MISS(vp);
 		return( ENOENT);
 	}
-	newnfsstats.attrcache_hits++;
+	nfsstatsv1.attrcache_hits++;
 	if (vap->va_size != np->n_size) {
 		if (vap->va_type == VREG) {
 			if (np->n_flag & NMODIFIED) {
Index: sys/fs/nfsclient/nfs_clvfsops.c
===================================================================
--- sys/fs/nfsclient/nfs_clvfsops.c
+++ sys/fs/nfsclient/nfs_clvfsops.c
@@ -78,7 +78,6 @@
 
 extern int nfscl_ticks;
 extern struct timeval nfsboottime;
-extern struct nfsstats	newnfsstats;
 extern int nfsrv_useacl;
 extern int nfscl_debuglevel;
 extern enum nfsiod_state ncl_iodwant[NFS_MAXASYNCDAEMON];
Index: sys/fs/nfsclient/nfs_clvnops.c
===================================================================
--- sys/fs/nfsclient/nfs_clvnops.c
+++ sys/fs/nfsclient/nfs_clvnops.c
@@ -100,7 +100,7 @@
 #define	TRUE	1
 #define	FALSE	0
 
-extern struct nfsstats newnfsstats;
+extern struct nfsstatsv1 nfsstatsv1;
 extern int nfsrv_useacl;
 extern int nfscl_debuglevel;
 MALLOC_DECLARE(M_NEWNFSREQ);
@@ -260,14 +260,6 @@
 SYSCTL_INT(_vfs_nfs, OID_AUTO, nfs_directio_allow_mmap, CTLFLAG_RW,
 	   &newnfs_directio_allow_mmap, 0, "Enable mmaped IO on file with O_DIRECT opens");
 
-#if 0
-SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_hits, CTLFLAG_RD,
-	   &newnfsstats.accesscache_hits, 0, "NFS ACCESS cache hit count");
-
-SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_misses, CTLFLAG_RD,
-	   &newnfsstats.accesscache_misses, 0, "NFS ACCESS cache miss count");
-#endif
-
 #define	NFSACCESS_ALL (NFSACCESS_READ | NFSACCESS_MODIFY		\
 			 | NFSACCESS_EXTEND | NFSACCESS_EXECUTE	\
 			 | NFSACCESS_DELETE | NFSACCESS_LOOKUP)
@@ -420,7 +412,7 @@
 			    if (time_second < (np->n_accesscache[i].stamp
 				+ nfsaccess_cache_timeout) &&
 				(np->n_accesscache[i].mode & mode) == mode) {
-				NFSINCRGLOBAL(newnfsstats.accesscache_hits);
+				NFSINCRGLOBAL(nfsstatsv1.accesscache_hits);
 				gotahit = 1;
 			    }
 			    break;
@@ -439,7 +431,7 @@
 			/*
 			 * Either a no, or a don't know.  Go to the wire.
 			 */
-			NFSINCRGLOBAL(newnfsstats.accesscache_misses);
+			NFSINCRGLOBAL(nfsstatsv1.accesscache_misses);
 		        error = nfs34_access_otw(vp, wmode, ap->a_td,
 			    ap->a_cred, &rmode);
 			if (!error &&
@@ -859,7 +851,7 @@
 
 	if (NFS_ISV34(vp) && nfs_prime_access_cache &&
 	    nfsaccess_cache_timeout > 0) {
-		NFSINCRGLOBAL(newnfsstats.accesscache_misses);
+		NFSINCRGLOBAL(nfsstatsv1.accesscache_misses);
 		nfs34_access_otw(vp, NFSACCESS_ALL, td, ap->a_cred, NULL);
 		if (ncl_getattrcache(vp, ap->a_vap) == 0) {
 			nfscl_deleggetmodtime(vp, &ap->a_vap->va_mtime);
@@ -1116,7 +1108,7 @@
 		    ((u_int)(ticks - ncticks) < (nmp->nm_nametimeo * hz) &&
 		    VOP_GETATTR(newvp, &vattr, cnp->cn_cred) == 0 &&
 		    timespeccmp(&vattr.va_ctime, &nctime, ==))) {
-			NFSINCRGLOBAL(newnfsstats.lookupcache_hits);
+			NFSINCRGLOBAL(nfsstatsv1.lookupcache_hits);
 			if (cnp->cn_nameiop != LOOKUP &&
 			    (flags & ISLASTCN))
 				cnp->cn_flags |= SAVENAME;
@@ -1143,7 +1135,7 @@
 		if ((u_int)(ticks - ncticks) < (nmp->nm_negnametimeo * hz) &&
 		    VOP_GETATTR(dvp, &vattr, cnp->cn_cred) == 0 &&
 		    timespeccmp(&vattr.va_mtime, &nctime, ==)) {
-			NFSINCRGLOBAL(newnfsstats.lookupcache_hits);
+			NFSINCRGLOBAL(nfsstatsv1.lookupcache_hits);
 			return (ENOENT);
 		}
 		cache_purge_negative(dvp);
@@ -1151,7 +1143,7 @@
 
 	error = 0;
 	newvp = NULLVP;
-	NFSINCRGLOBAL(newnfsstats.lookupcache_misses);
+	NFSINCRGLOBAL(nfsstatsv1.lookupcache_misses);
 	error = nfsrpc_lookup(dvp, cnp->cn_nameptr, cnp->cn_namelen,
 	    cnp->cn_cred, td, &dnfsva, &nfsva, &nfhp, &attrflag, &dattrflag,
 	    NULL);
@@ -2229,7 +2221,7 @@
 			if ((NFS_ISV4(vp) && np->n_change == vattr.va_filerev) ||
 			    !NFS_TIMESPEC_COMPARE(&np->n_mtime, &vattr.va_mtime)) {
 				mtx_unlock(&np->n_mtx);
-				NFSINCRGLOBAL(newnfsstats.direofcache_hits);
+				NFSINCRGLOBAL(nfsstatsv1.direofcache_hits);
 				if (ap->a_eofflag != NULL)
 					*ap->a_eofflag = 1;
 				return (0);
@@ -2256,7 +2248,7 @@
 	error = ncl_bioread(vp, uio, 0, ap->a_cred);
 
 	if (!error && uio->uio_resid == tresid) {
-		NFSINCRGLOBAL(newnfsstats.direofcache_misses);
+		NFSINCRGLOBAL(nfsstatsv1.direofcache_misses);
 		if (ap->a_eofflag != NULL)
 			*ap->a_eofflag = 1;
 	}
Index: sys/fs/nfsserver/nfs_nfsdcache.c
===================================================================
--- sys/fs/nfsserver/nfs_nfsdcache.c
+++ sys/fs/nfsserver/nfs_nfsdcache.c
@@ -159,7 +159,7 @@
 #ifndef APPLEKEXT
 #include <fs/nfs/nfsport.h>
 
-extern struct nfsstats newnfsstats;
+extern struct nfsstatsv1 nfsstatsv1;
 extern struct mtx nfsrc_udpmtx;
 extern struct nfsrchash_bucket nfsrchash_table[NFSRVCACHE_HASHSIZE];
 extern struct nfsrchash_bucket nfsrcahash_table[NFSRVCACHE_HASHSIZE];
@@ -318,8 +318,8 @@
 	TAILQ_INIT(&nfsrvudplru);
 	nfsrc_tcpsavedreplies = 0;
 	nfsrc_udpcachesize = 0;
-	newnfsstats.srvcache_tcppeak = 0;
-	newnfsstats.srvcache_size = 0;
+	nfsstatsv1.srvcache_tcppeak = 0;
+	nfsstatsv1.srvcache_size = 0;
 }
 
 /*
@@ -395,14 +395,14 @@
 			TAILQ_REMOVE(&nfsrvudplru, rp, rc_lru);
 			TAILQ_INSERT_TAIL(&nfsrvudplru, rp, rc_lru);
 			if (rp->rc_flag & RC_INPROG) {
-				newnfsstats.srvcache_inproghits++;
+				nfsstatsv1.srvcache_inproghits++;
 				mtx_unlock(mutex);
 				ret = RC_DROPIT;
 			} else if (rp->rc_flag & RC_REPSTATUS) {
 				/*
 				 * V2 only.
 				 */
-				newnfsstats.srvcache_nonidemdonehits++;
+				nfsstatsv1.srvcache_nonidemdonehits++;
 				mtx_unlock(mutex);
 				nfsrvd_rephead(nd);
 				*(nd->nd_errp) = rp->rc_status;
@@ -410,7 +410,7 @@
 				rp->rc_timestamp = NFSD_MONOSEC +
 					NFSRVCACHE_UDPTIMEOUT;
 			} else if (rp->rc_flag & RC_REPMBUF) {
-				newnfsstats.srvcache_nonidemdonehits++;
+				nfsstatsv1.srvcache_nonidemdonehits++;
 				mtx_unlock(mutex);
 				nd->nd_mreq = m_copym(rp->rc_reply, 0,
 					M_COPYALL, M_WAITOK);
@@ -425,8 +425,8 @@
 			goto out;
 		}
 	}
-	newnfsstats.srvcache_misses++;
-	atomic_add_int(&newnfsstats.srvcache_size, 1);
+	nfsstatsv1.srvcache_misses++;
+	atomic_add_int(&nfsstatsv1.srvcache_size, 1);
 	nfsrc_udpcachesize++;
 
 	newrp->rc_flag |= RC_INPROG;
@@ -480,7 +480,7 @@
 	 * Reply from cache is a special case returned by nfsrv_checkseqid().
 	 */
 	if (nd->nd_repstat == NFSERR_REPLYFROMCACHE) {
-		newnfsstats.srvcache_nonidemdonehits++;
+		nfsstatsv1.srvcache_nonidemdonehits++;
 		mtx_unlock(mutex);
 		nd->nd_repstat = 0;
 		if (nd->nd_mreq)
@@ -519,8 +519,8 @@
 			if (!(rp->rc_flag & RC_UDP)) {
 			    atomic_add_int(&nfsrc_tcpsavedreplies, 1);
 			    if (nfsrc_tcpsavedreplies >
-				newnfsstats.srvcache_tcppeak)
-				newnfsstats.srvcache_tcppeak =
+				nfsstatsv1.srvcache_tcppeak)
+				nfsstatsv1.srvcache_tcppeak =
 				    nfsrc_tcpsavedreplies;
 			}
 			mtx_unlock(mutex);
@@ -678,7 +678,7 @@
 			panic("nfs tcp cache0");
 		rp->rc_flag |= RC_LOCKED;
 		if (rp->rc_flag & RC_INPROG) {
-			newnfsstats.srvcache_inproghits++;
+			nfsstatsv1.srvcache_inproghits++;
 			mtx_unlock(mutex);
 			if (newrp->rc_sockref == rp->rc_sockref)
 				nfsrc_marksametcpconn(rp->rc_sockref);
@@ -687,7 +687,7 @@
 			/*
 			 * V2 only.
 			 */
-			newnfsstats.srvcache_nonidemdonehits++;
+			nfsstatsv1.srvcache_nonidemdonehits++;
 			mtx_unlock(mutex);
 			if (newrp->rc_sockref == rp->rc_sockref)
 				nfsrc_marksametcpconn(rp->rc_sockref);
@@ -696,7 +696,7 @@
 			*(nd->nd_errp) = rp->rc_status;
 			rp->rc_timestamp = NFSD_MONOSEC + nfsrc_tcptimeout;
 		} else if (rp->rc_flag & RC_REPMBUF) {
-			newnfsstats.srvcache_nonidemdonehits++;
+			nfsstatsv1.srvcache_nonidemdonehits++;
 			mtx_unlock(mutex);
 			if (newrp->rc_sockref == rp->rc_sockref)
 				nfsrc_marksametcpconn(rp->rc_sockref);
@@ -711,8 +711,8 @@
 		free((caddr_t)newrp, M_NFSRVCACHE);
 		goto out;
 	}
-	newnfsstats.srvcache_misses++;
-	atomic_add_int(&newnfsstats.srvcache_size, 1);
+	nfsstatsv1.srvcache_misses++;
+	atomic_add_int(&nfsstatsv1.srvcache_size, 1);
 
 	/*
 	 * For TCP, multiple entries for a key are allowed, so don't
@@ -801,7 +801,7 @@
 			atomic_add_int(&nfsrc_tcpsavedreplies, -1);
 	}
 	FREE((caddr_t)rp, M_NFSRVCACHE);
-	atomic_add_int(&newnfsstats.srvcache_size, -1);
+	atomic_add_int(&nfsstatsv1.srvcache_size, -1);
 }
 
 /*
@@ -825,7 +825,7 @@
 			nfsrc_freecache(rp);
 		}
 	}
-	newnfsstats.srvcache_size = 0;
+	nfsstatsv1.srvcache_size = 0;
 	mtx_unlock(&nfsrc_udpmtx);
 	nfsrc_tcpsavedreplies = 0;
 }
Index: sys/fs/nfsserver/nfs_nfsdsocket.c
===================================================================
--- sys/fs/nfsserver/nfs_nfsdsocket.c
+++ sys/fs/nfsserver/nfs_nfsdsocket.c
@@ -41,7 +41,7 @@
 #ifndef APPLEKEXT
 #include <fs/nfs/nfsport.h>
 
-extern struct nfsstats newnfsstats;
+extern struct nfsstatsv1 nfsstatsv1;
 extern struct nfsrvfh nfs_pubfh, nfs_rootfh;
 extern int nfs_pubfhset, nfs_rootfhset;
 extern struct nfsv4lock nfsv4rootfs_lock;
@@ -400,6 +400,68 @@
 	NFSV4OP_COMMIT,
 };
 
+static struct mtx nfsrvd_statmtx;
+MTX_SYSINIT(nfsst, &nfsrvd_statmtx, "NFSstat", MTX_DEF);
+
+static void
+nfsrvd_statstart(int op, struct bintime *now)
+{
+	if (op > (NFSV41_NOPS + NFSV4OP_FAKENOPS)) {
+		printf("%s: op %d invalid\n", __func__, op);
+		return;
+	}
+
+	mtx_lock(&nfsrvd_statmtx);
+	if (nfsstatsv1.srvstartcnt == nfsstatsv1.srvdonecnt) {
+		if (now != NULL)
+			nfsstatsv1.busyfrom = *now;
+		else
+			binuptime(&nfsstatsv1.busyfrom);
+		
+	}
+	nfsstatsv1.srvrpccnt[op]++;
+	nfsstatsv1.srvstartcnt++;
+	mtx_unlock(&nfsrvd_statmtx);
+
+}
+
+static void
+nfsrvd_statend(int op, uint64_t bytes, struct bintime *now,
+    struct bintime *then)
+{
+	struct bintime dt, lnow;
+
+	if (op > (NFSV41_NOPS + NFSV4OP_FAKENOPS)) {
+		printf("%s: op %d invalid\n", __func__, op);
+		return;
+	}
+
+	if (now == NULL) {
+		now = &lnow;
+		binuptime(now);
+	}
+
+	mtx_lock(&nfsrvd_statmtx);
+
+	nfsstatsv1.srvbytes[op] += bytes;
+	nfsstatsv1.srvops[op]++;
+
+	if (then != NULL) {
+		dt = *now;
+		bintime_sub(&dt, then);
+		bintime_add(&nfsstatsv1.srvduration[op], &dt);
+	}
+
+	dt = *now;
+	bintime_sub(&dt, &nfsstatsv1.busyfrom);
+	bintime_add(&nfsstatsv1.busytime, &dt);
+	nfsstatsv1.busyfrom = *now;
+
+	nfsstatsv1.srvdonecnt++;
+
+	mtx_unlock(&nfsrvd_statmtx);
+}
+
 /*
  * Do an RPC. Basically, get the file handles translated to vnode pointers
  * and then call the appropriate server routine. The server routines are
@@ -476,7 +538,9 @@
 	 */
 	if (nd->nd_repstat && (nd->nd_flag & ND_NFSV2)) {
 		*nd->nd_errp = nfsd_errmap(nd);
-		NFSINCRGLOBAL(newnfsstats.srvrpccnt[nfsv3to4op[nd->nd_procnum]]);
+		nfsrvd_statstart(nfsv3to4op[nd->nd_procnum], /*now*/ NULL);
+		nfsrvd_statend(nfsv3to4op[nd->nd_procnum], /*bytes*/ 0,
+		   /*now*/ NULL, /*then*/ NULL);
 		if (mp != NULL && nfs_writerpc[nd->nd_procnum] != 0)
 			vn_finished_write(mp);
 		goto out;
@@ -491,6 +555,11 @@
 	if (nd->nd_flag & ND_NFSV4) {
 		nfsrvd_compound(nd, isdgram, tag, taglen, minorvers, p);
 	} else {
+		struct bintime start_time;
+
+		binuptime(&start_time);
+		nfsrvd_statstart(nfsv3to4op[nd->nd_procnum], &start_time);
+
 		if (nfs_retfh[nd->nd_procnum] == 1) {
 			if (vp)
 				NFSVOPUNLOCK(vp, 0);
@@ -505,7 +574,9 @@
 		}
 		if (mp != NULL && nfs_writerpc[nd->nd_procnum] != 0)
 			vn_finished_write(mp);
-		NFSINCRGLOBAL(newnfsstats.srvrpccnt[nfsv3to4op[nd->nd_procnum]]);
+
+		nfsrvd_statend(nfsv3to4op[nd->nd_procnum], /*bytes*/ 0,
+		    /*now*/ NULL, /*then*/ &start_time);
 	}
 	if (error) {
 		if (error != EBADRPC)
@@ -547,7 +618,7 @@
 nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, u_char *tag,
     int taglen, u_int32_t minorvers, NFSPROC_T *p)
 {
-	int i, lktype, op, op0 = 0;
+	int i, lktype, op, op0 = 0, statsinprog = 0;
 	u_int32_t *tl;
 	struct nfsclient *clp, *nclp;
 	int numops, error = 0, igotlock;
@@ -559,6 +630,7 @@
 	struct nfsexstuff nes, vpnes, savevpnes;
 	fsid_t cur_fsid, save_fsid;
 	static u_int64_t compref = 0;
+	struct bintime start_time;
 
 	NFSVNO_EXINIT(&vpnes);
 	NFSVNO_EXINIT(&savevpnes);
@@ -686,6 +758,11 @@
 		*repp = *tl;
 		op = fxdr_unsigned(int, *tl);
 		NFSD_DEBUG(4, "op=%d\n", op);
+
+		binuptime(&start_time);
+		nfsrvd_statstart(op, &start_time);
+		statsinprog = 1;
+
 		if (op < NFSV4OP_ACCESS ||
 		    (op >= NFSV4OP_NOPS && (nd->nd_flag & ND_NFSV41) == 0) ||
 		    (op >= NFSV41_NOPS && (nd->nd_flag & ND_NFSV41) != 0)) {
@@ -771,7 +848,6 @@
 		}
 		if (nfsv4_opflag[op].savereply)
 			nd->nd_flag |= ND_SAVEREPLY;
-		NFSINCRGLOBAL(newnfsstats.srvrpccnt[nd->nd_procnum]);
 		switch (op) {
 		case NFSV4OP_PUTFH:
 			error = nfsrv_mtofh(nd, &fh);
@@ -1002,6 +1078,13 @@
 			}
 			error = 0;
 		}
+
+		if (statsinprog != 0) {
+			nfsrvd_statend(op, /*bytes*/ 0, /*now*/ NULL,
+			    /*then*/ &start_time);
+			statsinprog = 0;
+		}
+
 		retops++;
 		if (nd->nd_repstat) {
 			*repp = nfsd_errmap(nd);
@@ -1011,6 +1094,11 @@
 		}
 	}
 nfsmout:
+	if (statsinprog != 0) {
+		nfsrvd_statend(op, /*bytes*/ 0, /*now*/ NULL,
+		    /*then*/ &start_time);
+		statsinprog = 0;
+	}
 	if (error) {
 		if (error == EBADRPC || error == NFSERR_BADXDR)
 			nd->nd_repstat = NFSERR_BADXDR;
Index: sys/fs/nfsserver/nfs_nfsdstate.c
===================================================================
--- sys/fs/nfsserver/nfs_nfsdstate.c
+++ sys/fs/nfsserver/nfs_nfsdstate.c
@@ -37,7 +37,7 @@
 struct nfsv4lock nfsv4rootfs_lock;
 
 extern int newnfs_numnfsd;
-extern struct nfsstats newnfsstats;
+extern struct nfsstatsv1 nfsstatsv1;
 extern int nfsrv_lease;
 extern struct timeval nfsboottime;
 extern u_int32_t newnfs_true, newnfs_false;
@@ -273,7 +273,7 @@
 			LIST_INIT(&new_clp->lc_stateid[i]);
 		LIST_INSERT_HEAD(NFSCLIENTHASH(new_clp->lc_clientid), new_clp,
 		    lc_hash);
-		newnfsstats.srvclients++;
+		nfsstatsv1.srvclients++;
 		nfsrv_openpluslock++;
 		nfsrv_clients++;
 		NFSLOCKV4ROOTMUTEX();
@@ -377,7 +377,7 @@
 		}
 		LIST_INSERT_HEAD(NFSCLIENTHASH(new_clp->lc_clientid), new_clp,
 		    lc_hash);
-		newnfsstats.srvclients++;
+		nfsstatsv1.srvclients++;
 		nfsrv_openpluslock++;
 		nfsrv_clients++;
 		NFSLOCKV4ROOTMUTEX();
@@ -441,7 +441,7 @@
 		}
 		LIST_INSERT_HEAD(NFSCLIENTHASH(new_clp->lc_clientid), new_clp,
 		    lc_hash);
-		newnfsstats.srvclients++;
+		nfsstatsv1.srvclients++;
 		nfsrv_openpluslock++;
 		nfsrv_clients++;
 	}
@@ -815,7 +815,7 @@
 
 /*
  * Dump out stats for all clients. Called from nfssvc(2), that is used
- * newnfsstats.
+ * nfsstatsv1.
  */
 APPLESTATIC void
 nfsrv_dumpclients(struct nfsd_dumpclients *dumpp, int maxcnt)
@@ -1219,7 +1219,7 @@
 	free(clp->lc_stateid, M_NFSDCLIENT);
 	free(clp, M_NFSDCLIENT);
 	NFSLOCKSTATE();
-	newnfsstats.srvclients--;
+	nfsstatsv1.srvclients--;
 	nfsrv_openpluslock--;
 	nfsrv_clients--;
 	NFSUNLOCKSTATE();
@@ -1260,7 +1260,7 @@
 	    nfsv4_testlock(&lfp->lf_locallock_lck) == 0)
 		nfsrv_freenfslockfile(lfp);
 	FREE((caddr_t)stp, M_NFSDSTATE);
-	newnfsstats.srvdelegates--;
+	nfsstatsv1.srvdelegates--;
 	nfsrv_openpluslock--;
 	nfsrv_delegatecnt--;
 }
@@ -1286,7 +1286,7 @@
 	if (stp->ls_op)
 		nfsrvd_derefcache(stp->ls_op);
 	FREE((caddr_t)stp, M_NFSDSTATE);
-	newnfsstats.srvopenowners--;
+	nfsstatsv1.srvopenowners--;
 	nfsrv_openpluslock--;
 }
 
@@ -1336,7 +1336,7 @@
 	if (cansleep != 0)
 		NFSUNLOCKSTATE();
 	FREE((caddr_t)stp, M_NFSDSTATE);
-	newnfsstats.srvopens--;
+	nfsstatsv1.srvopens--;
 	nfsrv_openpluslock--;
 	return (ret);
 }
@@ -1355,7 +1355,7 @@
 	if (stp->ls_op)
 		nfsrvd_derefcache(stp->ls_op);
 	FREE((caddr_t)stp, M_NFSDSTATE);
-	newnfsstats.srvlockowners--;
+	nfsstatsv1.srvlockowners--;
 	nfsrv_openpluslock--;
 }
 
@@ -1430,7 +1430,7 @@
 
 	if (lop->lo_lckfile.le_prev != NULL) {
 		LIST_REMOVE(lop, lo_lckfile);
-		newnfsstats.srvlocks--;
+		nfsstatsv1.srvlocks--;
 		nfsrv_openpluslock--;
 	}
 	LIST_REMOVE(lop, lo_lckowner);
@@ -2200,7 +2200,7 @@
 		LIST_INSERT_HEAD(&stp->ls_open, new_stp, ls_list);
 		*new_lopp = NULL;
 		*new_stpp = NULL;
-		newnfsstats.srvlockowners++;
+		nfsstatsv1.srvlockowners++;
 		nfsrv_openpluslock++;
 	}
 	if (filestruct_locked != 0) {
@@ -2849,12 +2849,12 @@
 			LIST_INSERT_HEAD(&new_stp->ls_open, new_open, ls_list);
 			LIST_INSERT_HEAD(&clp->lc_open, new_stp, ls_list);
 			*new_stpp = NULL;
-			newnfsstats.srvopenowners++;
+			nfsstatsv1.srvopenowners++;
 			nfsrv_openpluslock++;
 		    }
 		    openstp = new_open;
 		    new_open = NULL;
-		    newnfsstats.srvopens++;
+		    nfsstatsv1.srvopens++;
 		    nfsrv_openpluslock++;
 		    break;
 		}
@@ -2913,7 +2913,7 @@
 		    NFSRV_V4DELEGLIMIT(nfsrv_delegatecnt) ||
 		    !NFSVNO_DELEGOK(vp))
 		    *rflagsp |= NFSV4OPEN_RECALL;
-		newnfsstats.srvdelegates++;
+		nfsstatsv1.srvdelegates++;
 		nfsrv_openpluslock++;
 		nfsrv_delegatecnt++;
 
@@ -2953,12 +2953,12 @@
 		    LIST_INSERT_HEAD(&new_stp->ls_open, new_open, ls_list);
 		    LIST_INSERT_HEAD(&clp->lc_open, new_stp, ls_list);
 		    *new_stpp = NULL;
-		    newnfsstats.srvopenowners++;
+		    nfsstatsv1.srvopenowners++;
 		    nfsrv_openpluslock++;
 		}
 		openstp = new_open;
 		new_open = NULL;
-		newnfsstats.srvopens++;
+		nfsstatsv1.srvopens++;
 		nfsrv_openpluslock++;
 	    } else {
 		error = NFSERR_RECLAIMCONFLICT;
@@ -3027,7 +3027,7 @@
 			    new_deleg->ls_stateid), new_deleg, ls_hash);
 			LIST_INSERT_HEAD(&clp->lc_deleg, new_deleg, ls_list);
 			new_deleg = NULL;
-			newnfsstats.srvdelegates++;
+			nfsstatsv1.srvdelegates++;
 			nfsrv_openpluslock++;
 			nfsrv_delegatecnt++;
 		    }
@@ -3049,7 +3049,7 @@
 			new_open, ls_hash);
 		    openstp = new_open;
 		    new_open = NULL;
-		    newnfsstats.srvopens++;
+		    nfsstatsv1.srvopens++;
 		    nfsrv_openpluslock++;
 
 		    /*
@@ -3094,7 +3094,7 @@
 			    new_deleg->ls_stateid), new_deleg, ls_hash);
 			LIST_INSERT_HEAD(&clp->lc_deleg, new_deleg, ls_list);
 			new_deleg = NULL;
-			newnfsstats.srvdelegates++;
+			nfsstatsv1.srvdelegates++;
 			nfsrv_openpluslock++;
 			nfsrv_delegatecnt++;
 		    }
@@ -3173,7 +3173,7 @@
 				LIST_INSERT_HEAD(&clp->lc_deleg, new_deleg,
 				    ls_list);
 				new_deleg = NULL;
-				newnfsstats.srvdelegates++;
+				nfsstatsv1.srvdelegates++;
 				nfsrv_openpluslock++;
 				nfsrv_delegatecnt++;
 			}
@@ -3191,9 +3191,9 @@
 		openstp = new_open;
 		new_open = NULL;
 		*new_stpp = NULL;
-		newnfsstats.srvopens++;
+		nfsstatsv1.srvopens++;
 		nfsrv_openpluslock++;
-		newnfsstats.srvopenowners++;
+		nfsstatsv1.srvopenowners++;
 		nfsrv_openpluslock++;
 	}
 	if (!error) {
@@ -3645,7 +3645,7 @@
 	else
 		LIST_INSERT_AFTER(insert_lop, new_lop, lo_lckowner);
 	if (stp != NULL) {
-		newnfsstats.srvlocks++;
+		nfsstatsv1.srvlocks++;
 		nfsrv_openpluslock++;
 	}
 }
@@ -3843,7 +3843,7 @@
  * just set lc_program to 0 to indicate no callbacks are possible.
  * (For cases where the address can't be parsed or is 0.0.0.0.0.0, set
  *  the address to the client's transport address. This won't be used
- *  for callbacks, but can be printed out by newnfsstats for info.)
+ *  for callbacks, but can be printed out by nfsstats for info.)
  * Return error if the xdr can't be parsed, 0 otherwise.
  */
 APPLESTATIC int
Index: usr.bin/nfsstat/Makefile
===================================================================
--- usr.bin/nfsstat/Makefile
+++ usr.bin/nfsstat/Makefile
@@ -4,4 +4,6 @@
 PROG=	nfsstat
 CFLAGS+=-DNFS
 
+LIBADD=	devstat
+
 .include <bsd.prog.mk>
Index: usr.bin/nfsstat/nfsstat.1
===================================================================
--- usr.bin/nfsstat/nfsstat.1
+++ usr.bin/nfsstat/nfsstat.1
@@ -28,7 +28,7 @@
 .\"     From: @(#)nfsstat.1	8.1 (Berkeley) 6/6/93
 .\" $FreeBSD: head/usr.bin/nfsstat/nfsstat.1 281888 2015-04-23 14:36:01Z trasz $
 .\"
-.Dd April 23, 2015
+.Dd May 26, 2016
 .Dt NFSSTAT 1
 .Os
 .Sh NAME
@@ -38,7 +38,7 @@
 statistics
 .Sh SYNOPSIS
 .Nm
-.Op Fl cemszW
+.Op Fl cdemszW
 .Op Fl M Ar core
 .Op Fl N Ar system
 .Op Fl w Ar wait
@@ -57,6 +57,21 @@
 .Bl -tag -width indent
 .It Fl c
 Only display client side statistics.
+.It Fl d
+Display statistics for the new NFS server that are similar to those
+displayed by
+.Xr iostat 8 .
+This includes kilobytes per transfer, transfers per second, and megabytes per
+second for read, write and all operations.
+It also includes the current queue depth, the busy percentage, and latency
+for all operations.
+If the
+.Fl W
+flag is added, commits per second, commit latency, read latency and write
+latency are also added to the display.
+The busy percentage may exceed 100 at times.
+That is not a bug, but is rather caused when a long running operation
+completes.
 .It Fl e
 Report the extra statistics collected by the NFS client and
 server for NFSv4.
@@ -79,7 +94,8 @@
 Use wide format with interval short summary.
 This option is especially
 useful when combined with
-.Fl c
+.Fl c ,
+.Fl d ,
 or
 .Fl s
 and a time delay.
Index: usr.bin/nfsstat/nfsstat.c
===================================================================
--- usr.bin/nfsstat/nfsstat.c
+++ usr.bin/nfsstat/nfsstat.c
@@ -29,6 +29,36 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+/*-
+ * Copyright (c) 2004, 2008, 2009 Silicon Graphics International Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
 
 #ifndef lint
 static const char copyright[] =
@@ -67,30 +97,53 @@
 #include <stdlib.h>
 #include <string.h>
 #include <paths.h>
+#include <devstat.h>
 #include <err.h>
 
 static int widemode = 0;
 static int zflag = 0;
 static int printtitle = 1;
-static struct ext_nfsstats ext_nfsstats;
+static struct nfsstatsv1 ext_nfsstats;
 static int extra_output = 0;
 
 static void intpr(int, int);
-static void printhdr(int, int);
+static void printhdr(int, int, int);
 static void usage(void);
 static char *sperc1(int, int);
 static char *sperc2(int, int);
 static void exp_intpr(int, int);
-static void exp_sidewaysintpr(u_int, int, int);
+static void exp_sidewaysintpr(u_int, int, int, int);
+static void compute_new_stats(struct nfsstatsv1 *cur_stats,
+    struct nfsstatsv1 *prev_stats, int curop, long double etime,
+    long double *mbsec, long double *kb_per_transfer,
+    long double *transfers_per_second, long double *ms_per_transfer,
+    uint64_t *queue_len, long double *busy_pct);
 
 #define DELTA(field)	(nfsstats.field - lastst.field)
 
+#define	STAT_TYPE_READ		0
+#define	STAT_TYPE_WRITE		1
+#define	STAT_TYPE_COMMIT	2
+#define	NUM_STAT_TYPES		3
+
+struct stattypes {
+	int stat_type;
+	int nfs_type;
+} statstruct[] = {
+	{STAT_TYPE_READ, NFSV4OP_READ},
+	{STAT_TYPE_WRITE, NFSV4OP_WRITE},
+	{STAT_TYPE_COMMIT, NFSV4OP_COMMIT}
+};
+
+#define	STAT_TYPE_TO_NFS(stat_type)	statstruct[stat_type].nfs_type
+
 int
 main(int argc, char **argv)
 {
 	u_int interval;
 	int clientOnly = -1;
 	int serverOnly = -1;
+	int newStats = 0;
 	int ch;
 	char *memf, *nlistf;
 	int mntlen, i;
@@ -100,7 +153,7 @@
 
 	interval = 0;
 	memf = nlistf = NULL;
-	while ((ch = getopt(argc, argv, "cesWM:mN:w:z")) != -1)
+	while ((ch = getopt(argc, argv, "cdesWM:mN:w:z")) != -1)
 		switch(ch) {
 		case 'M':
 			memf = optarg;
@@ -140,6 +193,11 @@
 			if (serverOnly < 0)
 				serverOnly = 0;
 			break;
+		case 'd':
+			newStats = 1;
+			if (interval == 0)
+				interval = 1;
+			break;
 		case 's':
 			serverOnly = 1;
 			if (clientOnly < 0)
@@ -173,7 +231,8 @@
 		errx(1, "NFS client/server not loaded");
 
 	if (interval) {
-		exp_sidewaysintpr(interval, clientOnly, serverOnly);
+		exp_sidewaysintpr(interval, clientOnly, serverOnly,
+		    newStats);
 	} else {
 		if (extra_output != 0)
 			exp_intpr(clientOnly, serverOnly);
@@ -191,13 +250,14 @@
 {
 	int nfssvc_flag;
 
-	nfssvc_flag = NFSSVC_GETSTATS;
+	nfssvc_flag = NFSSVC_GETSTATS | NFSSVC_NEWSTRUCT;
 	if (zflag != 0) {
 		if (clientOnly != 0)
 			nfssvc_flag |= NFSSVC_ZEROCLTSTATS;
 		if (serverOnly != 0)
 			nfssvc_flag |= NFSSVC_ZEROSRVSTATS;
 	}
+	ext_nfsstats.vers = NFSSTATS_V1;
 	if (nfssvc(nfssvc_flag, &ext_nfsstats) < 0)
 		err(1, "Can't get stats");
 	if (clientOnly) {
@@ -206,124 +266,124 @@
 		printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
 			"Getattr", "Setattr", "Lookup", "Readlink", "Read",
 			"Write", "Create", "Remove");
-		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
-			ext_nfsstats.rpccnt[NFSPROC_GETATTR],
-			ext_nfsstats.rpccnt[NFSPROC_SETATTR],
-			ext_nfsstats.rpccnt[NFSPROC_LOOKUP],
-			ext_nfsstats.rpccnt[NFSPROC_READLINK],
-			ext_nfsstats.rpccnt[NFSPROC_READ],
-			ext_nfsstats.rpccnt[NFSPROC_WRITE],
-			ext_nfsstats.rpccnt[NFSPROC_CREATE],
-			ext_nfsstats.rpccnt[NFSPROC_REMOVE]);
+		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
+			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_GETATTR],
+			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_SETATTR],
+			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LOOKUP],
+			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READLINK],
+			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READ],
+			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_WRITE],
+			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_CREATE],
+			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_REMOVE]);
 		printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
 			"Rename", "Link", "Symlink", "Mkdir", "Rmdir",
 			"Readdir", "RdirPlus", "Access");
-		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
-			ext_nfsstats.rpccnt[NFSPROC_RENAME],
-			ext_nfsstats.rpccnt[NFSPROC_LINK],
-			ext_nfsstats.rpccnt[NFSPROC_SYMLINK],
-			ext_nfsstats.rpccnt[NFSPROC_MKDIR],
-			ext_nfsstats.rpccnt[NFSPROC_RMDIR],
-			ext_nfsstats.rpccnt[NFSPROC_READDIR],
-			ext_nfsstats.rpccnt[NFSPROC_READDIRPLUS],
-			ext_nfsstats.rpccnt[NFSPROC_ACCESS]);
+		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
+			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_RENAME],
+			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LINK],
+			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_SYMLINK],
+			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_MKDIR],
+			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_RMDIR],
+			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READDIR],
+			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READDIRPLUS],
+			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_ACCESS]);
 		printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
 			"Mknod", "Fsstat", "Fsinfo", "PathConf", "Commit");
-		printf("%9d %9d %9d %9d %9d\n",
-			ext_nfsstats.rpccnt[NFSPROC_MKNOD],
-			ext_nfsstats.rpccnt[NFSPROC_FSSTAT],
-			ext_nfsstats.rpccnt[NFSPROC_FSINFO],
-			ext_nfsstats.rpccnt[NFSPROC_PATHCONF],
-			ext_nfsstats.rpccnt[NFSPROC_COMMIT]);
+		printf("%9ju %9ju %9ju %9ju %9ju\n",
+			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_MKNOD],
+			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_FSSTAT],
+			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_FSINFO],
+			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_PATHCONF],
+			(uintmax_t)ext_nfsstats.rpccnt[NFSPROC_COMMIT]);
 		printf("Rpc Info:\n");
 		printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
 			"TimedOut", "Invalid", "X Replies", "Retries", 
 			"Requests");
-		printf("%9d %9d %9d %9d %9d\n",
-			ext_nfsstats.rpctimeouts,
-			ext_nfsstats.rpcinvalid,
-			ext_nfsstats.rpcunexpected,
-			ext_nfsstats.rpcretries,
-			ext_nfsstats.rpcrequests);
+		printf("%9ju %9ju %9ju %9ju %9ju\n",
+			(uintmax_t)ext_nfsstats.rpctimeouts,
+			(uintmax_t)ext_nfsstats.rpcinvalid,
+			(uintmax_t)ext_nfsstats.rpcunexpected,
+			(uintmax_t)ext_nfsstats.rpcretries,
+			(uintmax_t)ext_nfsstats.rpcrequests);
 		printf("Cache Info:\n");
 		printf("%9.9s %9.9s %9.9s %9.9s",
 			"Attr Hits", "Misses", "Lkup Hits", "Misses");
 		printf(" %9.9s %9.9s %9.9s %9.9s\n",
 			"BioR Hits", "Misses", "BioW Hits", "Misses");
-		printf("%9d %9d %9d %9d",
-			ext_nfsstats.attrcache_hits,
-			ext_nfsstats.attrcache_misses,
-			ext_nfsstats.lookupcache_hits,
-			ext_nfsstats.lookupcache_misses);
-		printf(" %9d %9d %9d %9d\n",
-			ext_nfsstats.biocache_reads -
-			ext_nfsstats.read_bios,
-			ext_nfsstats.read_bios,
-			ext_nfsstats.biocache_writes -
-			ext_nfsstats.write_bios,
-			ext_nfsstats.write_bios);
+		printf("%9ju %9ju %9ju %9ju",
+			(uintmax_t)ext_nfsstats.attrcache_hits,
+			(uintmax_t)ext_nfsstats.attrcache_misses,
+			(uintmax_t)ext_nfsstats.lookupcache_hits,
+			(uintmax_t)ext_nfsstats.lookupcache_misses);
+		printf(" %9ju %9ju %9ju %9ju\n",
+			(uintmax_t)(ext_nfsstats.biocache_reads -
+			ext_nfsstats.read_bios),
+			(uintmax_t)ext_nfsstats.read_bios,
+			(uintmax_t)(ext_nfsstats.biocache_writes -
+			ext_nfsstats.write_bios),
+			(uintmax_t)ext_nfsstats.write_bios);
 		printf("%9.9s %9.9s %9.9s %9.9s",
 			"BioRLHits", "Misses", "BioD Hits", "Misses");
 		printf(" %9.9s %9.9s %9.9s %9.9s\n", "DirE Hits", "Misses", "Accs Hits", "Misses");
-		printf("%9d %9d %9d %9d",
-			ext_nfsstats.biocache_readlinks -
-			ext_nfsstats.readlink_bios,
-			ext_nfsstats.readlink_bios,
-			ext_nfsstats.biocache_readdirs -
-			ext_nfsstats.readdir_bios,
-			ext_nfsstats.readdir_bios);
-		printf(" %9d %9d %9d %9d\n",
-			ext_nfsstats.direofcache_hits,
-			ext_nfsstats.direofcache_misses,
-			ext_nfsstats.accesscache_hits,
-			ext_nfsstats.accesscache_misses);
+		printf("%9ju %9ju %9ju %9ju",
+			(uintmax_t)(ext_nfsstats.biocache_readlinks -
+			ext_nfsstats.readlink_bios),
+			(uintmax_t)ext_nfsstats.readlink_bios,
+			(uintmax_t)(ext_nfsstats.biocache_readdirs -
+			ext_nfsstats.readdir_bios),
+			(uintmax_t)ext_nfsstats.readdir_bios);
+		printf(" %9ju %9ju %9ju %9ju\n",
+			(uintmax_t)ext_nfsstats.direofcache_hits,
+			(uintmax_t)ext_nfsstats.direofcache_misses,
+			(uintmax_t)ext_nfsstats.accesscache_hits,
+			(uintmax_t)ext_nfsstats.accesscache_misses);
 	}
 	if (serverOnly) {
 		printf("\nServer Info:\n");
 		printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
 			"Getattr", "Setattr", "Lookup", "Readlink", "Read",
 			"Write", "Create", "Remove");
-		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
-			ext_nfsstats.srvrpccnt[NFSV4OP_GETATTR],
-			ext_nfsstats.srvrpccnt[NFSV4OP_SETATTR],
-			ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUP],
-			ext_nfsstats.srvrpccnt[NFSV4OP_READLINK],
-			ext_nfsstats.srvrpccnt[NFSV4OP_READ],
-			ext_nfsstats.srvrpccnt[NFSV4OP_WRITE],
-			ext_nfsstats.srvrpccnt[NFSV4OP_CREATE],
-			ext_nfsstats.srvrpccnt[NFSV4OP_REMOVE]);
+		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
+			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_GETATTR],
+			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SETATTR],
+			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUP],
+			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READLINK],
+			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READ],
+			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_WRITE],
+			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_CREATE],
+			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_REMOVE]);
 		printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
 			"Rename", "Link", "Symlink", "Mkdir", "Rmdir",
 			"Readdir", "RdirPlus", "Access");
-		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
-			ext_nfsstats.srvrpccnt[NFSV4OP_RENAME],
-			ext_nfsstats.srvrpccnt[NFSV4OP_LINK],
-			ext_nfsstats.srvrpccnt[NFSV4OP_SYMLINK],
-			ext_nfsstats.srvrpccnt[NFSV4OP_MKDIR],
-			ext_nfsstats.srvrpccnt[NFSV4OP_RMDIR],
-			ext_nfsstats.srvrpccnt[NFSV4OP_READDIR],
-			ext_nfsstats.srvrpccnt[NFSV4OP_READDIRPLUS],
-			ext_nfsstats.srvrpccnt[NFSV4OP_ACCESS]);
+		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
+			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RENAME],
+			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LINK],
+			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SYMLINK],
+			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_MKDIR],
+			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RMDIR],
+			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READDIR],
+			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READDIRPLUS],
+			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_ACCESS]);
 		printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
 			"Mknod", "Fsstat", "Fsinfo", "PathConf", "Commit");
-		printf("%9d %9d %9d %9d %9d\n",
-			ext_nfsstats.srvrpccnt[NFSV4OP_MKNOD],
-			ext_nfsstats.srvrpccnt[NFSV4OP_FSSTAT],
-			ext_nfsstats.srvrpccnt[NFSV4OP_FSINFO],
-			ext_nfsstats.srvrpccnt[NFSV4OP_PATHCONF],
-			ext_nfsstats.srvrpccnt[NFSV4OP_COMMIT]);
+		printf("%9ju %9ju %9ju %9ju %9ju\n",
+			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_MKNOD],
+			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_FSSTAT],
+			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_FSINFO],
+			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_PATHCONF],
+			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_COMMIT]);
 		printf("Server Ret-Failed\n");
-		printf("%17d\n", ext_nfsstats.srvrpc_errs);
+		printf("%17ju\n", (uintmax_t)ext_nfsstats.srvrpc_errs);
 		printf("Server Faults\n");
-		printf("%13d\n", ext_nfsstats.srv_errs);
+		printf("%13ju\n", (uintmax_t)ext_nfsstats.srv_errs);
 		printf("Server Cache Stats:\n");
 		printf("%9.9s %9.9s %9.9s %9.9s\n",
 			"Inprog", "Idem", "Non-idem", "Misses");
-		printf("%9d %9d %9d %9d\n",
-			ext_nfsstats.srvcache_inproghits,
-			ext_nfsstats.srvcache_idemdonehits,
-			ext_nfsstats.srvcache_nonidemdonehits,
-			ext_nfsstats.srvcache_misses);
+		printf("%9ju %9ju %9ju %9ju\n",
+			(uintmax_t)ext_nfsstats.srvcache_inproghits,
+			(uintmax_t)ext_nfsstats.srvcache_idemdonehits,
+			(uintmax_t)ext_nfsstats.srvcache_nonidemdonehits,
+			(uintmax_t)ext_nfsstats.srvcache_misses);
 		printf("Server Write Gathering:\n");
 		printf("%9.9s %9.9s %9.9s\n",
 			"WriteOps", "WriteRPC", "Opsaved");
@@ -331,21 +391,37 @@
 		 * The new client doesn't do write gathering. It was
 		 * only useful for NFSv2.
 		 */
-		printf("%9d %9d %9d\n",
-			ext_nfsstats.srvrpccnt[NFSV4OP_WRITE],
-			ext_nfsstats.srvrpccnt[NFSV4OP_WRITE], 0);
+		printf("%9ju %9ju %9d\n",
+			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_WRITE],
+			(uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_WRITE], 0);
 	}
 }
 
 static void
-printhdr(int clientOnly, int serverOnly)
+printhdr(int clientOnly, int serverOnly, int newStats)
 {
-	printf("%s%6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s",
-	    ((serverOnly && clientOnly) ? "        " : " "),
-	    "GtAttr", "Lookup", "Rdlink", "Read", "Write", "Rename",
-	    "Access", "Rddir");
-	if (widemode && clientOnly) {
-		printf(" Attr Lkup BioR BioW Accs BioD");
+
+	if (newStats) {
+		printf(" [%s Read %s]  [%s Write %s]  "
+		    "%s[=========== Total ============]\n"
+		    " KB/t   tps    MB/s%s  KB/t   tps    MB/s%s  "
+		    "%sKB/t   tps    MB/s    ms  ql  %%b",
+		    widemode ? "========" : "=====",
+		    widemode ? "========" : "=====",
+		    widemode ? "========" : "=====",
+		    widemode ? "======="  : "====",
+		    widemode ? "[Commit ]  " : "",
+		    widemode ? "    ms" : "",
+		    widemode ? "    ms" : "",
+		    widemode ? "tps    ms  " : "");
+	} else {
+		printf("%s%6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s",
+		    ((serverOnly && clientOnly) ? "        " : " "),
+		    "GtAttr", "Lookup", "Rdlink", "Read", "Write", "Rename",
+		    "Access", "Rddir");
+		if (widemode && clientOnly) {
+			printf(" Attr Lkup BioR BioW Accs BioD");
+		}
 	}
 	printf("\n");
 	fflush(stdout);
@@ -355,7 +431,7 @@
 usage(void)
 {
 	(void)fprintf(stderr,
-	    "usage: nfsstat [-cemszW] [-M core] [-N system] [-w wait]\n");
+	    "usage: nfsstat [-cdemszW] [-M core] [-N system] [-w wait]\n");
 	exit(1);
 }
 
@@ -392,6 +468,75 @@
 	return(p);
 }
 
+#define DELTA_T(field)					\
+	devstat_compute_etime(&cur_stats->field,	\
+	(prev_stats ? &prev_stats->field : NULL))
+
+/*
+ * XXX KDM mostly copied from ctlstat.  We should commonize the code (and
+ * the devstat code) somehow.
+ */
+static void
+compute_new_stats(struct nfsstatsv1 *cur_stats,
+		  struct nfsstatsv1 *prev_stats, int curop,
+		  long double etime, long double *mbsec,
+		  long double *kb_per_transfer,
+		  long double *transfers_per_second,
+		  long double *ms_per_transfer, uint64_t *queue_len,
+		  long double *busy_pct)
+{
+	uint64_t total_bytes = 0, total_operations = 0;
+	struct bintime total_time_bt;
+	struct timespec total_time_ts;
+
+	bzero(&total_time_bt, sizeof(total_time_bt));
+	bzero(&total_time_ts, sizeof(total_time_ts));
+
+	total_bytes = cur_stats->srvbytes[curop];
+	total_operations = cur_stats->srvops[curop];
+	if (prev_stats != NULL) {
+		total_bytes -= prev_stats->srvbytes[curop];
+		total_operations -= prev_stats->srvops[curop];
+	}
+
+	*mbsec = total_bytes;
+	*mbsec /= 1024 * 1024;
+	if (etime > 0.0) {
+		*busy_pct = DELTA_T(busytime);
+		if (*busy_pct < 0)
+			*busy_pct = 0;
+		*busy_pct /= etime;
+		*busy_pct *= 100;
+		if (*busy_pct < 0)
+			*busy_pct = 0;
+		*mbsec /= etime;
+	} else {
+		*busy_pct = 0;
+		*mbsec = 0;
+	}
+	*kb_per_transfer = total_bytes;
+	*kb_per_transfer /= 1024;
+	if (total_operations > 0)
+		*kb_per_transfer /= total_operations;
+	else
+		*kb_per_transfer = 0;
+	if (etime > 0.0) {
+		*transfers_per_second = total_operations;
+		*transfers_per_second /= etime;
+	} else {
+		*transfers_per_second = 0.0;
+	}
+                        
+	if (total_operations > 0) {
+		*ms_per_transfer = DELTA_T(srvduration[curop]);
+		*ms_per_transfer /= total_operations;
+		*ms_per_transfer *= 1000;
+	} else
+		*ms_per_transfer = 0.0;
+
+	*queue_len = cur_stats->srvstartcnt - cur_stats->srvdonecnt;
+}
+
 /*
  * Print a description of the nfs stats for the experimental client/server.
  */
@@ -400,13 +545,14 @@
 {
 	int nfssvc_flag;
 
-	nfssvc_flag = NFSSVC_GETSTATS;
+	nfssvc_flag = NFSSVC_GETSTATS | NFSSVC_NEWSTRUCT;
 	if (zflag != 0) {
 		if (clientOnly != 0)
 			nfssvc_flag |= NFSSVC_ZEROCLTSTATS;
 		if (serverOnly != 0)
 			nfssvc_flag |= NFSSVC_ZEROSRVSTATS;
 	}
+	ext_nfsstats.vers = NFSSTATS_V1;
 	if (nfssvc(nfssvc_flag, &ext_nfsstats) < 0)
 		err(1, "Can't get stats");
 	if (clientOnly != 0) {
@@ -418,81 +564,81 @@
 			    , "Getattr", "Setattr", "Lookup", "Readlink",
 			    "Read", "Write", "Create", "Remove");
 		}
-		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
-		    ext_nfsstats.rpccnt[NFSPROC_GETATTR],
-		    ext_nfsstats.rpccnt[NFSPROC_SETATTR],
-		    ext_nfsstats.rpccnt[NFSPROC_LOOKUP],
-		    ext_nfsstats.rpccnt[NFSPROC_READLINK],
-		    ext_nfsstats.rpccnt[NFSPROC_READ],
-		    ext_nfsstats.rpccnt[NFSPROC_WRITE],
-		    ext_nfsstats.rpccnt[NFSPROC_CREATE],
-		    ext_nfsstats.rpccnt[NFSPROC_REMOVE]);
+		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_GETATTR],
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_SETATTR],
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LOOKUP],
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READLINK],
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READ],
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_WRITE],
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_CREATE],
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_REMOVE]);
 		if (printtitle)
 			printf(
 			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
 			    , "Rename", "Link", "Symlink", "Mkdir", "Rmdir",
 			    "Readdir", "RdirPlus", "Access");
-		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
-		    ext_nfsstats.rpccnt[NFSPROC_RENAME],
-		    ext_nfsstats.rpccnt[NFSPROC_LINK],
-		    ext_nfsstats.rpccnt[NFSPROC_SYMLINK],
-		    ext_nfsstats.rpccnt[NFSPROC_MKDIR],
-		    ext_nfsstats.rpccnt[NFSPROC_RMDIR],
-		    ext_nfsstats.rpccnt[NFSPROC_READDIR],
-		    ext_nfsstats.rpccnt[NFSPROC_READDIRPLUS],
-		    ext_nfsstats.rpccnt[NFSPROC_ACCESS]);
+		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_RENAME],
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LINK],
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_SYMLINK],
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_MKDIR],
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_RMDIR],
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READDIR],
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_READDIRPLUS],
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_ACCESS]);
 		if (printtitle)
 			printf(
 			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
 			    , "Mknod", "Fsstat", "Fsinfo", "PathConf",
 			    "Commit", "SetClId", "SetClIdCf", "Lock");
-		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
-		    ext_nfsstats.rpccnt[NFSPROC_MKNOD],
-		    ext_nfsstats.rpccnt[NFSPROC_FSSTAT],
-		    ext_nfsstats.rpccnt[NFSPROC_FSINFO],
-		    ext_nfsstats.rpccnt[NFSPROC_PATHCONF],
-		    ext_nfsstats.rpccnt[NFSPROC_COMMIT],
-		    ext_nfsstats.rpccnt[NFSPROC_SETCLIENTID],
-		    ext_nfsstats.rpccnt[NFSPROC_SETCLIENTIDCFRM],
-		    ext_nfsstats.rpccnt[NFSPROC_LOCK]);
+		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_MKNOD],
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_FSSTAT],
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_FSINFO],
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_PATHCONF],
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_COMMIT],
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_SETCLIENTID],
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_SETCLIENTIDCFRM],
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LOCK]);
 		if (printtitle)
 			printf("%9.9s %9.9s %9.9s %9.9s\n",
 			    "LockT", "LockU", "Open", "OpenCfr");
-		printf("%9d %9d %9d %9d\n",
-		    ext_nfsstats.rpccnt[NFSPROC_LOCKT],
-		    ext_nfsstats.rpccnt[NFSPROC_LOCKU],
-		    ext_nfsstats.rpccnt[NFSPROC_OPEN],
-		    ext_nfsstats.rpccnt[NFSPROC_OPENCONFIRM]);
+		printf("%9ju %9ju %9ju %9ju\n",
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LOCKT],
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_LOCKU],
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_OPEN],
+		    (uintmax_t)ext_nfsstats.rpccnt[NFSPROC_OPENCONFIRM]);
 		if (printtitle)
 			printf(
 			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
 			    , "OpenOwner", "Opens", "LockOwner",
 			    "Locks", "Delegs", "LocalOwn",
 			    "LocalOpen", "LocalLOwn");
-		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
-		    ext_nfsstats.clopenowners,
-		    ext_nfsstats.clopens,
-		    ext_nfsstats.cllockowners,
-		    ext_nfsstats.cllocks,
-		    ext_nfsstats.cldelegates,
-		    ext_nfsstats.cllocalopenowners,
-		    ext_nfsstats.cllocalopens,
-		    ext_nfsstats.cllocallockowners);
+		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
+		    (uintmax_t)ext_nfsstats.clopenowners,
+		    (uintmax_t)ext_nfsstats.clopens,
+		    (uintmax_t)ext_nfsstats.cllockowners,
+		    (uintmax_t)ext_nfsstats.cllocks,
+		    (uintmax_t)ext_nfsstats.cldelegates,
+		    (uintmax_t)ext_nfsstats.cllocalopenowners,
+		    (uintmax_t)ext_nfsstats.cllocalopens,
+		    (uintmax_t)ext_nfsstats.cllocallockowners);
 		if (printtitle)
 			printf("%9.9s\n", "LocalLock");
-		printf("%9d\n", ext_nfsstats.cllocallocks);
+		printf("%9ju\n", (uintmax_t)ext_nfsstats.cllocallocks);
 		if (printtitle) {
 			printf("Rpc Info:\n");
 			printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
 			    "TimedOut", "Invalid", "X Replies", "Retries",
 			    "Requests");
 		}
-		printf("%9d %9d %9d %9d %9d\n",
-		    ext_nfsstats.rpctimeouts,
-		    ext_nfsstats.rpcinvalid,
-		    ext_nfsstats.rpcunexpected,
-		    ext_nfsstats.rpcretries,
-		    ext_nfsstats.rpcrequests);
+		printf("%9ju %9ju %9ju %9ju %9ju\n",
+		    (uintmax_t)ext_nfsstats.rpctimeouts,
+		    (uintmax_t)ext_nfsstats.rpcinvalid,
+		    (uintmax_t)ext_nfsstats.rpcunexpected,
+		    (uintmax_t)ext_nfsstats.rpcretries,
+		    (uintmax_t)ext_nfsstats.rpcrequests);
 		if (printtitle) {
 			printf("Cache Info:\n");
 			printf("%9.9s %9.9s %9.9s %9.9s",
@@ -500,31 +646,33 @@
 			printf(" %9.9s %9.9s %9.9s %9.9s\n",
 			    "BioR Hits", "Misses", "BioW Hits", "Misses");
 		}
-		printf("%9d %9d %9d %9d",
-		    ext_nfsstats.attrcache_hits,
-		    ext_nfsstats.attrcache_misses,
-		    ext_nfsstats.lookupcache_hits,
-		    ext_nfsstats.lookupcache_misses);
-		printf(" %9d %9d %9d %9d\n",
-		    ext_nfsstats.biocache_reads - ext_nfsstats.read_bios,
-		    ext_nfsstats.read_bios,
-		    ext_nfsstats.biocache_writes - ext_nfsstats.write_bios,
-		    ext_nfsstats.write_bios);
+		printf("%9ju %9ju %9ju %9ju",
+		    (uintmax_t)ext_nfsstats.attrcache_hits,
+		    (uintmax_t)ext_nfsstats.attrcache_misses,
+		    (uintmax_t)ext_nfsstats.lookupcache_hits,
+		    (uintmax_t)ext_nfsstats.lookupcache_misses);
+		printf(" %9ju %9ju %9ju %9ju\n",
+		    (uintmax_t)(ext_nfsstats.biocache_reads -
+		    ext_nfsstats.read_bios),
+		    (uintmax_t)ext_nfsstats.read_bios,
+		    (uintmax_t)(ext_nfsstats.biocache_writes -
+		    ext_nfsstats.write_bios),
+		    (uintmax_t)ext_nfsstats.write_bios);
 		if (printtitle) {
 			printf("%9.9s %9.9s %9.9s %9.9s",
 			    "BioRLHits", "Misses", "BioD Hits", "Misses");
 			printf(" %9.9s %9.9s\n", "DirE Hits", "Misses");
 		}
-		printf("%9d %9d %9d %9d",
-		    ext_nfsstats.biocache_readlinks -
-		    ext_nfsstats.readlink_bios,
-		    ext_nfsstats.readlink_bios,
-		    ext_nfsstats.biocache_readdirs -
-		    ext_nfsstats.readdir_bios,
-		    ext_nfsstats.readdir_bios);
-		printf(" %9d %9d\n",
-		    ext_nfsstats.direofcache_hits,
-		    ext_nfsstats.direofcache_misses);
+		printf("%9ju %9ju %9ju %9ju",
+		    (uintmax_t)(ext_nfsstats.biocache_readlinks -
+		    ext_nfsstats.readlink_bios),
+		    (uintmax_t)ext_nfsstats.readlink_bios,
+		    (uintmax_t)(ext_nfsstats.biocache_readdirs -
+		    ext_nfsstats.readdir_bios),
+		    (uintmax_t)ext_nfsstats.readdir_bios);
+		printf(" %9ju %9ju\n",
+		    (uintmax_t)ext_nfsstats.direofcache_hits,
+		    (uintmax_t)ext_nfsstats.direofcache_misses);
 	}
 	if (serverOnly != 0) {
 		if (printtitle) {
@@ -534,116 +682,136 @@
 			    , "Getattr", "Setattr", "Lookup", "Readlink",
 			    "Read", "Write", "Create", "Remove");
 		}
-		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
-		    ext_nfsstats.srvrpccnt[NFSV4OP_GETATTR],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_SETATTR],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUP],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_READLINK],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_READ],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_WRITE],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_V3CREATE],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_REMOVE]);
+		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_GETATTR],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SETATTR],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUP],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READLINK],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READ],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_WRITE],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_V3CREATE],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_REMOVE]);
 		if (printtitle)
 			printf(
 			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
 			    , "Rename", "Link", "Symlink", "Mkdir", "Rmdir",
 			    "Readdir", "RdirPlus", "Access");
-		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
-		    ext_nfsstats.srvrpccnt[NFSV4OP_RENAME],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_LINK],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_SYMLINK],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_MKDIR],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_RMDIR],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_READDIR],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_READDIRPLUS],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_ACCESS]);
+		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RENAME],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LINK],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SYMLINK],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_MKDIR],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RMDIR],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READDIR],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_READDIRPLUS],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_ACCESS]);
 		if (printtitle)
 			printf(
 			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
 			    , "Mknod", "Fsstat", "Fsinfo", "PathConf",
 			    "Commit", "LookupP", "SetClId", "SetClIdCf");
-		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
-		    ext_nfsstats.srvrpccnt[NFSV4OP_MKNOD],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_FSSTAT],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_FSINFO],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_PATHCONF],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_COMMIT],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUPP],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_SETCLIENTID],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_SETCLIENTIDCFRM]);
+		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_MKNOD],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_FSSTAT],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_FSINFO],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_PATHCONF],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_COMMIT],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUPP],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SETCLIENTID],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SETCLIENTIDCFRM]);
 		if (printtitle)
 			printf(
 			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
 			    , "Open", "OpenAttr", "OpenDwnGr", "OpenCfrm",
 			    "DelePurge", "DeleRet", "GetFH", "Lock");
-		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
-		    ext_nfsstats.srvrpccnt[NFSV4OP_OPEN],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_OPENATTR],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_OPENDOWNGRADE],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_OPENCONFIRM],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_DELEGPURGE],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_DELEGRETURN],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_GETFH],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_LOCK]);
+		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_OPEN],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_OPENATTR],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_OPENDOWNGRADE],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_OPENCONFIRM],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_DELEGPURGE],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_DELEGRETURN],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_GETFH],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LOCK]);
 		if (printtitle)
 			printf(
 			    "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n"
 			    , "LockT", "LockU", "Close", "Verify", "NVerify",
 			    "PutFH", "PutPubFH", "PutRootFH");
-		printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
-		    ext_nfsstats.srvrpccnt[NFSV4OP_LOCKT],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_LOCKU],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_CLOSE],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_VERIFY],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_NVERIFY],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_PUTFH],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_PUTPUBFH],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_PUTROOTFH]);
+		printf("%9ju %9ju %9ju %9ju %9ju %9ju %9ju %9ju\n",
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LOCKT],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_LOCKU],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_CLOSE],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_VERIFY],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_NVERIFY],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_PUTFH],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_PUTPUBFH],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_PUTROOTFH]);
 		if (printtitle)
 			printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
 			    "Renew", "RestoreFH", "SaveFH", "Secinfo",
 			    "RelLckOwn", "V4Create");
-		printf("%9d %9d %9d %9d %9d %9d\n",
-		    ext_nfsstats.srvrpccnt[NFSV4OP_RENEW],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_RESTOREFH],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_SAVEFH],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_SECINFO],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_RELEASELCKOWN],
-		    ext_nfsstats.srvrpccnt[NFSV4OP_CREATE]);
+		printf("%9ju %9ju %9ju %9ju %9ju %9ju\n",
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RENEW],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RESTOREFH],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SAVEFH],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_SECINFO],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_RELEASELCKOWN],
+		    (uintmax_t)ext_nfsstats.srvrpccnt[NFSV4OP_CREATE]);
 		if (printtitle) {
 			printf("Server:\n");
 			printf("%9.9s %9.9s %9.9s\n",
 			    "Retfailed", "Faults", "Clients");
 		}
-		printf("%9d %9d %9d\n",
-		    ext_nfsstats.srv_errs, ext_nfsstats.srvrpc_errs,
-		    ext_nfsstats.srvclients);
+		printf("%9ju %9ju %9ju\n",
+		    (uintmax_t)ext_nfsstats.srv_errs,
+		    (uintmax_t)ext_nfsstats.srvrpc_errs,
+		    (uintmax_t)ext_nfsstats.srvclients);
 		if (printtitle)
 			printf("%9.9s %9.9s %9.9s %9.9s %9.9s \n",
 			    "OpenOwner", "Opens", "LockOwner",
 			    "Locks", "Delegs");
-		printf("%9d %9d %9d %9d %9d \n",
-		    ext_nfsstats.srvopenowners,
-		    ext_nfsstats.srvopens,
-		    ext_nfsstats.srvlockowners,
-		    ext_nfsstats.srvlocks,
-		    ext_nfsstats.srvdelegates);
+		printf("%9ju %9ju %9ju %9ju %9ju \n",
+		    (uintmax_t)ext_nfsstats.srvopenowners,
+		    (uintmax_t)ext_nfsstats.srvopens,
+		    (uintmax_t)ext_nfsstats.srvlockowners,
+		    (uintmax_t)ext_nfsstats.srvlocks,
+		    (uintmax_t)ext_nfsstats.srvdelegates);
 		if (printtitle) {
 			printf("Server Cache Stats:\n");
 			printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
 			    "Inprog", "Idem", "Non-idem", "Misses", 
 			    "CacheSize", "TCPPeak");
 		}
-		printf("%9d %9d %9d %9d %9d %9d\n",
-		    ext_nfsstats.srvcache_inproghits,
-		    ext_nfsstats.srvcache_idemdonehits,
-		    ext_nfsstats.srvcache_nonidemdonehits,
-		    ext_nfsstats.srvcache_misses,
-		    ext_nfsstats.srvcache_size,
-		    ext_nfsstats.srvcache_tcppeak);
+		printf("%9ju %9ju %9ju %9ju %9ju %9ju\n",
+		    (uintmax_t)ext_nfsstats.srvcache_inproghits,
+		    (uintmax_t)ext_nfsstats.srvcache_idemdonehits,
+		    (uintmax_t)ext_nfsstats.srvcache_nonidemdonehits,
+		    (uintmax_t)ext_nfsstats.srvcache_misses,
+		    (uintmax_t)ext_nfsstats.srvcache_size,
+		    (uintmax_t)ext_nfsstats.srvcache_tcppeak);
 	}
 }
 
+static void
+compute_totals(struct nfsstatsv1 *total_stats, struct nfsstatsv1 *cur_stats)
+{
+	int i;
+
+	bzero(total_stats, sizeof(*total_stats));
+	for (i = 0; i < (NFSV4OP_NOPS + NFSV4OP_FAKENOPS); i++) {
+		total_stats->srvbytes[0] += cur_stats->srvbytes[i];
+		total_stats->srvops[0] += cur_stats->srvops[i];
+		bintime_add(&total_stats->srvduration[0],
+			    &cur_stats->srvduration[i]);
+		total_stats->srvrpccnt[i] = cur_stats->srvrpccnt[i];
+	}
+	total_stats->srvstartcnt = cur_stats->srvstartcnt;
+	total_stats->srvdonecnt = cur_stats->srvdonecnt;
+	total_stats->busytime = cur_stats->busytime;
+
+}
+
 /*
  * Print a running summary of nfs statistics for the experimental client and/or
  * server.
@@ -652,40 +820,51 @@
  * First line printed at top of screen is always cumulative.
  */
 static void
-exp_sidewaysintpr(u_int interval, int clientOnly, int serverOnly)
+exp_sidewaysintpr(u_int interval, int clientOnly, int serverOnly,
+    int newStats)
 {
-	struct ext_nfsstats nfsstats, lastst, *ext_nfsstatsp;
+	struct nfsstatsv1 nfsstats, lastst, *ext_nfsstatsp;
+	struct nfsstatsv1 curtotal, lasttotal;
+	struct timespec ts, lastts;
 	int hdrcnt = 1;
 
 	ext_nfsstatsp = &lastst;
-	if (nfssvc(NFSSVC_GETSTATS, ext_nfsstatsp) < 0)
+	ext_nfsstatsp->vers = NFSSTATS_V1;
+	if (nfssvc(NFSSVC_GETSTATS | NFSSVC_NEWSTRUCT, ext_nfsstatsp) < 0)
 		err(1, "Can't get stats");
+	clock_gettime(CLOCK_MONOTONIC, &lastts);
+	compute_totals(&lasttotal, ext_nfsstatsp);
 	sleep(interval);
 
 	for (;;) {
 		ext_nfsstatsp = &nfsstats;
-		if (nfssvc(NFSSVC_GETSTATS, ext_nfsstatsp) < 0)
+		ext_nfsstatsp->vers = NFSSTATS_V1;
+		if (nfssvc(NFSSVC_GETSTATS | NFSSVC_NEWSTRUCT, ext_nfsstatsp)
+		    < 0)
 			err(1, "Can't get stats");
+		clock_gettime(CLOCK_MONOTONIC, &ts);
 
 		if (--hdrcnt == 0) {
-			printhdr(clientOnly, serverOnly);
-			if (clientOnly && serverOnly)
+			printhdr(clientOnly, serverOnly, newStats);
+			if (newStats)
+				hdrcnt = 20;
+			else if (clientOnly && serverOnly)
 				hdrcnt = 10;
 			else
 				hdrcnt = 20;
 		}
-		if (clientOnly) {
-		    printf("%s %6d %6d %6d %6d %6d %6d %6d %6d",
+		if (clientOnly && newStats == 0) {
+		    printf("%s %6ju %6ju %6ju %6ju %6ju %6ju %6ju %6ju",
 			((clientOnly && serverOnly) ? "Client:" : ""),
-			DELTA(rpccnt[NFSPROC_GETATTR]),
-			DELTA(rpccnt[NFSPROC_LOOKUP]),
-			DELTA(rpccnt[NFSPROC_READLINK]),
-			DELTA(rpccnt[NFSPROC_READ]),
-			DELTA(rpccnt[NFSPROC_WRITE]),
-			DELTA(rpccnt[NFSPROC_RENAME]),
-			DELTA(rpccnt[NFSPROC_ACCESS]),
-			DELTA(rpccnt[NFSPROC_READDIR]) +
-			DELTA(rpccnt[NFSPROC_READDIRPLUS])
+			(uintmax_t)DELTA(rpccnt[NFSPROC_GETATTR]),
+			(uintmax_t)DELTA(rpccnt[NFSPROC_LOOKUP]),
+			(uintmax_t)DELTA(rpccnt[NFSPROC_READLINK]),
+			(uintmax_t)DELTA(rpccnt[NFSPROC_READ]),
+			(uintmax_t)DELTA(rpccnt[NFSPROC_WRITE]),
+			(uintmax_t)DELTA(rpccnt[NFSPROC_RENAME]),
+			(uintmax_t)DELTA(rpccnt[NFSPROC_ACCESS]),
+			(uintmax_t)(DELTA(rpccnt[NFSPROC_READDIR]) +
+			DELTA(rpccnt[NFSPROC_READDIRPLUS]))
 		    );
 		    if (widemode) {
 			    printf(" %s %s %s %s %s %s",
@@ -705,21 +884,74 @@
 		    }
 		    printf("\n");
 		}
-		if (serverOnly) {
-		    printf("%s %6d %6d %6d %6d %6d %6d %6d %6d",
+
+		if (serverOnly && newStats) {
+			long double cur_secs, last_secs, etime;
+			long double mbsec;
+			long double kb_per_transfer;
+			long double transfers_per_second;
+			long double ms_per_transfer;
+			uint64_t queue_len;
+			long double busy_pct;
+			int i;
+
+			cur_secs = ts.tv_sec +
+			    ((long double)ts.tv_nsec / 1000000000);
+			last_secs = lastts.tv_sec +
+			    ((long double)lastts.tv_nsec / 1000000000);
+			etime = cur_secs - last_secs;
+
+			compute_totals(&curtotal, &nfsstats);
+
+			for (i = 0; i < NUM_STAT_TYPES; i++) {
+				compute_new_stats(&nfsstats, &lastst,
+				    STAT_TYPE_TO_NFS(i), etime, &mbsec,
+				    &kb_per_transfer,
+				    &transfers_per_second,
+				    &ms_per_transfer, &queue_len,
+				    &busy_pct);
+
+				if (i == STAT_TYPE_COMMIT) {
+					if (widemode == 0)
+						continue;
+
+					printf("%2.0Lf %7.2Lf ",
+					    transfers_per_second,
+					    ms_per_transfer);
+				} else {
+					printf("%5.2Lf %5.0Lf %7.2Lf ",
+					    kb_per_transfer,
+					    transfers_per_second, mbsec);
+					if (widemode)
+						printf("%5.2Lf ",
+						    ms_per_transfer);
+				}
+			}
+
+			compute_new_stats(&curtotal, &lasttotal, 0, etime,
+			    &mbsec, &kb_per_transfer, &transfers_per_second,
+			    &ms_per_transfer, &queue_len, &busy_pct);
+
+			printf("%5.2Lf %5.0Lf %7.2Lf %5.2Lf %3ju %3.0Lf\n",
+			    kb_per_transfer, transfers_per_second, mbsec,
+			    ms_per_transfer, queue_len, busy_pct);
+		} else if (serverOnly) {
+		    printf("%s %6ju %6ju %6ju %6ju %6ju %6ju %6ju %6ju",
 			((clientOnly && serverOnly) ? "Server:" : ""),
-			DELTA(srvrpccnt[NFSV4OP_GETATTR]),
-			DELTA(srvrpccnt[NFSV4OP_LOOKUP]),
-			DELTA(srvrpccnt[NFSV4OP_READLINK]),
-			DELTA(srvrpccnt[NFSV4OP_READ]),
-			DELTA(srvrpccnt[NFSV4OP_WRITE]),
-			DELTA(srvrpccnt[NFSV4OP_RENAME]),
-			DELTA(srvrpccnt[NFSV4OP_ACCESS]),
-			DELTA(srvrpccnt[NFSV4OP_READDIR]) +
-			DELTA(srvrpccnt[NFSV4OP_READDIRPLUS]));
+			(uintmax_t)DELTA(srvrpccnt[NFSV4OP_GETATTR]),
+			(uintmax_t)DELTA(srvrpccnt[NFSV4OP_LOOKUP]),
+			(uintmax_t)DELTA(srvrpccnt[NFSV4OP_READLINK]),
+			(uintmax_t)DELTA(srvrpccnt[NFSV4OP_READ]),
+			(uintmax_t)DELTA(srvrpccnt[NFSV4OP_WRITE]),
+			(uintmax_t)DELTA(srvrpccnt[NFSV4OP_RENAME]),
+			(uintmax_t)DELTA(srvrpccnt[NFSV4OP_ACCESS]),
+			(uintmax_t)(DELTA(srvrpccnt[NFSV4OP_READDIR]) +
+			DELTA(srvrpccnt[NFSV4OP_READDIRPLUS])));
 		    printf("\n");
 		}
-		lastst = nfsstats;
+		bcopy(&nfsstats, &lastst, sizeof(lastst));
+		bcopy(&curtotal, &lasttotal, sizeof(lasttotal));
+		lastts = ts;
 		fflush(stdout);
 		sleep(interval);
 	}