Index: sbin/idmapd/idmapd.8
===================================================================
RCS file: /home/ncvs/src/sbin/idmapd/idmapd.8,v
retrieving revision 1.1
diff -u -r1.1 idmapd.8
--- sbin/idmapd/idmapd.8	14 Nov 2003 21:04:33 -0000	1.1
+++ sbin/idmapd/idmapd.8	21 Nov 2003 21:31:13 -0000
@@ -1,2 +1,64 @@
+.\" copyright (c) 2003
+.\" the regents of the university of michigan
+.\" all rights reserved
+.\" 
+.\" permission is granted to use, copy, create derivative works and redistribute
+.\" this software and such derivative works for any purpose, so long as the name
+.\" of the university of michigan is not used in any advertising or publicity
+.\" pertaining to the use or distribution of this software without specific,
+.\" written prior authorization.  if the above copyright notice or any other
+.\" identification of the university of michigan is included in any copy of any
+.\" portion of this software, then the disclaimer below must also be included.
+.\" 
+.\" this software is provided as is, without representation from the university
+.\" of michigan as to its fitness for any purpose, and without warranty by the
+.\" university of michigan of any kind, either express or implied, including
+.\" without limitation the implied warranties of merchantability and fitness for
+.\" a particular purpose. the regents of the university of michigan shall not be
+.\" liable for any damages, including special, indirect, incidental, or
+.\" consequential damages, with respect to any claim arising out of or in
+.\" connection with the use of the software, even if it has been or is hereafter
+.\" advised of the possibility of such damages.
+.\"
 .\" $FreeBSD: src/sbin/idmapd/idmapd.8,v 1.1 2003/11/14 21:04:33 alfred Exp $
 man
+.\"
+.Dd November 14, 2003
+.Dt IDMAPD 8
+.Os
+.Sh NAME
+.Nm idmapd
+.Nd name/uid mapper for NFSv4
+.Sh SYNOPSIS
+.Nm
+.Op Fl v
+.Op Fl d Ar domainname
+.Sh DESCRIPTION
+The
+.Nm
+daemon normally runs in the background and services uid/gid-to-name and
+name-to-uid/gid mapping
+requests from the NFSv4 client.
+.Pp
+The options are:
+.Bl -tag -width indent
+.It Fl v
+Be verbose, and do not run in the background.
+.It Fl d
+Set the domain part of the name string to the specified string.
+.El
+.Sh FILES
+.Bl -tag -width /etc/master.passwd -compact
+.It Pa /etc/pwd.db
+The insecure password database file
+.It Pa /etc/spwd.db
+The secure password database file
+.It Pa /etc/master.passwd
+The current password file
+.It Pa /etc/passwd
+A Version 7 format password file
+.El
+.Sh SEE ALSO
+.Xr getpwnam 2 ,
+.Xr getpwuid 2 ,
+.Xr mount_nfs 8
Index: sbin/idmapd/idmapd.c
===================================================================
RCS file: /home/ncvs/src/sbin/idmapd/idmapd.c,v
retrieving revision 1.1
diff -u -r1.1 idmapd.c
--- sbin/idmapd/idmapd.c	14 Nov 2003 21:04:33 -0000	1.1
+++ sbin/idmapd/idmapd.c	21 Nov 2003 21:31:14 -0000
@@ -25,7 +25,7 @@
  * advised of the possibility of such damages.
  */
 
-/* XXX ignores the domain of recieved names. */
+/* XXX ignores the domain of received names. */
 
 #include <sys/types.h>
 #include <sys/ioctl.h>
@@ -52,7 +52,7 @@
 
 #define DEV_PATH "/dev/nfs4"
 
-#define DOMAIN "@citi.umich.edu"
+#define DOMAIN "@FreeBSD.org"
 #define BADUSER "nobody"
 #define BADGROUP "nogroup"
 #define BADUID (-2)
Index: sbin/mount_nfs4/mount_nfs4.8
===================================================================
RCS file: /home/ncvs/src/sbin/mount_nfs4/mount_nfs4.8,v
retrieving revision 1.1
diff -u -r1.1 mount_nfs4.8
--- sbin/mount_nfs4/mount_nfs4.8	14 Nov 2003 21:04:33 -0000	1.1
+++ sbin/mount_nfs4/mount_nfs4.8	21 Nov 2003 21:31:14 -0000
@@ -32,15 +32,15 @@
 .\"	@(#)mount_nfs.8	8.3 (Berkeley) 3/29/95
 .\" $FreeBSD: src/sbin/mount_nfs4/mount_nfs4.8,v 1.1 2003/11/14 21:04:33 alfred Exp $
 .\"
-.Dd May 11, 2003
-.Dt MOUNT_NFS 8
+.Dd November 14, 2003
+.Dt MOUNT_NFS4 8
 .Os
 .Sh NAME
-.Nm mount_nfs
-.Nd mount NFS file systems
+.Nm mount_nfs4
+.Nd mount NFSv4 file systems
 .Sh SYNOPSIS
 .Nm
-.Op Fl 23NPTUbcdiLls
+.Op Fl NPTUbcdiLls
 .Op Fl D Ar deadthresh
 .Op Fl I Ar readdirsize
 .Op Fl R Ar retrycnt
@@ -57,30 +57,16 @@
 .Nm
 utility calls the
 .Xr mount 2
-system call to prepare and graft a remote NFS file system
+system call to prepare and graft a remote NFSv4 file system
 .Pq Ar rhost : Ns Ar path
 on to the file system tree at the point
 .Ar node .
 This command is normally executed by
 .Xr mount 8 .
-It implements the mount protocol as described in RFC 1094, Appendix A and
-.%T "NFS: Network File System Version 3 Protocol Specification" ,
-Appendix I.
+It implements the NFSv4 protocol as described in RFC 3530,
+.%T "NFS version 4 Protocol."
 .Pp
-By default,
-.Nm
-keeps retrying until the mount succeeds.
-This behaviour is intended for file systems listed in
-.Xr fstab 5
-that are critical to the boot process.
-For non-critical file systems, the
-.Fl b
-and
-.Fl R
-flags provide mechanisms to prevent the boot process from hanging
-if the server is unavailable.
-.Pp
-If the server becomes unresponsive while an NFS file system is
+If the server becomes unresponsive while an NFSv4 file system is
 mounted, any new or outstanding file operations on that file system
 will hang uninterruptibly until the server comes back.
 To modify this default behaviour, see the
@@ -91,12 +77,6 @@
 .Pp
 The options are:
 .Bl -tag -width indent
-.It Fl 2
-Use the NFS Version 2 protocol (the default is to try version 3 first
-then version 2).
-Note that NFS version 2 has a file size limit of 2 gigabytes.
-.It Fl 3
-Use the NFS Version 3 protocol.
 .It Fl D
 Set the
 .Dq "dead server threshold"
@@ -109,24 +89,6 @@
 be a multiple of
 .Dv DIRBLKSIZ
 that is <= the read size for the mount.
-.It Fl L
-Do
-.Em not
-forward
-.Xr fcntl 2
-locks over the wire.
-All locks will be local and not seen by the server
-and likewise not seen by other NFS clients.
-This removes the need to run the
-.Xr rpcbind 8
-service and the
-.Xr rpc.statd 8
-and
-.Xr rpc.lockd 8
-servers on the client.
-Note that this option will only be honored when performing the
-initial mount, it will be silently ignored if used while updating
-the mount options.
 .It Fl N
 Do
 .Em not
@@ -144,17 +106,11 @@
 forever.
 There is a 60 second delay between each attempt.
 .It Fl T
-Use TCP transport instead of UDP.
-This is recommended for servers that are not on the same LAN cable as
-the client.
-(NB: This is NOT supported by most
-.No non- Ns Bx
-servers.)
+Use TCP transport. This is the default.
 .It Fl U
-Force the mount protocol to use UDP transport, even for TCP NFS mounts.
-(Necessary for some old
-.Bx
-servers.)
+Force the mount protocol to use UDP transport.
+This is not supported by the version 4 protocol and is provided only for
+debugging purposes.
 .It Fl a
 Set the read-ahead count to the specified value.
 This may be in the range of 0 - 4, and determines how many blocks
@@ -167,41 +123,10 @@
 Useful for
 .Xr fstab 5 ,
 where the file system mount is not critical to multiuser operation.
-.It Fl c
-For UDP mount points, do not do a
-.Xr connect 2 .
-This must be used if the server does not reply to requests from the standard
-NFS port number 2049 or replies to requests using a different IP address
-(which can occur if the server is multi-homed).
-Setting the
-.Va vfs.nfs.nfs_ip_paranoia
-sysctl to 0 will make this option the default.
-.It Fl d
-Turn off the dynamic retransmit timeout estimator.
-This may be useful for UDP mounts that exhibit high retry rates,
-since it is possible that the dynamically estimated timeout interval is too
-short.
-.It Fl g
-Set the maximum size of the group list for the credentials to the
-specified value.
-This should be used for mounts on old servers that cannot handle a
-group list size of 16, as specified in RFC 1057.
-Try 8, if users in a lot of groups cannot get response from the mount
-point.
 .It Fl i
 Make the mount interruptible, which implies that file system calls that
 are delayed due to an unresponsive server will fail with EINTR when a
 termination signal is posted for the process.
-.It Fl l
-Used with NQNFS and NFSV3 to specify that the \fBReaddirPlus\fR RPC should
-be used.
-This option reduces RPC traffic for cases such as
-.Dq "ls -l" ,
-but tends to flood the attribute and name caches with prefetched entries.
-Try this option and see whether performance improves or degrades.
-Probably
-most useful for client to server network interconnects with a large bandwidth
-times delay product.
 .It Fl o
 Options are specified with a
 .Fl o
@@ -212,8 +137,9 @@
 The following NFS specific options are also available:
 .Bl -tag -width indent
 .It Cm port Ns = Ns Aq Ar port_number
-Use specified port number for NFS requests.
-The default is to query the portmapper for the NFS port.
+Use specified port number for NFSv4 requests.
+The default is to use port 2049.
+Set this to 0 to query the portmapper for the NFSv4 port.
 .It Cm acregmin Ns = Ns Aq Ar seconds
 .It Cm acregmax Ns = Ns Aq Ar seconds
 .It Cm acdirmin Ns = Ns Aq Ar seconds
@@ -239,64 +165,6 @@
 Useful for hosts that have
 both an A record and an AAAA record for the same name.
 .El
-.Bl -tag -width ".Cm dumbtimer"
-.Ss Historic Fl o Ss Options
-Use of these options is deprecated, they are only mentioned here for
-compatibility with historic versions of
-.Nm .
-.It Cm bg
-Same as
-.Fl b .
-.It Cm conn
-Same as not specifying
-.Fl c .
-.It Cm dumbtimer
-Same as
-.Fl d .
-.It Cm intr
-Same as
-.Fl i .
-.It Cm lockd
-Same as not specifying
-.Fl L .
-.It Cm nfsv2
-Same as
-.Fl 2 .
-.It Cm nfsv3
-Same as
-.Fl 3 .
-.It Cm rdirplus
-Same as
-.Fl l .
-.It Cm mntudp
-Same as
-.Fl U .
-.It Cm resvport
-Same as
-.Fl P .
-.It Cm soft
-Same as
-.Fl s .
-.It Cm tcp
-Same as
-.Fl T .
-.El
-.It Fl r
-Set the read data size to the specified value.
-It should normally be a power of 2 greater than or equal to 1024.
-This should be used for UDP mounts when the
-.Dq "fragments dropped due to timeout"
-value is getting large while actively using a mount point.
-(Use
-.Xr netstat 1
-with the
-.Fl s
-option to see what the
-.Dq "fragments dropped due to timeout"
-value is.)
-See the
-.Fl w
-option as well.
 .It Fl s
 A soft mount, which implies that file system calls will fail
 after
@@ -315,19 +183,6 @@
 option should be specified when using this option to manually
 tune the timeout
 interval.)
-.It Fl w
-Set the write data size to the specified value.
-Ditto the comments w.r.t. the
-.Fl r
-option, but using the
-.Dq "fragments dropped due to timeout"
-value on the server instead of the client.
-Note that both the
-.Fl r
-and
-.Fl w
-options should only be used as a last ditch effort at improving performance
-when mounting servers that do not support TCP mounts.
 .It Fl x
 Set the retransmit timeout count for soft mounts to the specified value.
 .El
@@ -335,17 +190,12 @@
 .Xr mount 2 ,
 .Xr unmount 2 ,
 .Xr fstab 5 ,
+.Xr idmapd 8 ,
 .Xr mount 8 ,
+.Xr mount_nfs 8 ,
 .Xr nfsd 8 ,
-.Xr nfsiod 8 ,
-.Xr showmount 8
+.Xr nfsiod 8
 .Sh BUGS
-Due to the way that Sun RPC is implemented on top of UDP (unreliable datagram)
-transport, tuning such mounts is really a black art that can only be expected
-to have limited success.
-For clients mounting servers that are not on the same
-LAN cable or that tend to be overloaded,
-TCP transport is strongly recommended,
-but unfortunately this is restricted to mostly
-.Bx 4.4
-servers.
+This version of the NFSv4 client, while functional, is a long way
+from compliance with RFC 3530. It lacks lock state, reboot recovery,
+delegation, gss, and many other mandatory items from the RFC.
Index: sbin/mount_nfs4/mount_nfs4.c
===================================================================
RCS file: /home/ncvs/src/sbin/mount_nfs4/mount_nfs4.c,v
retrieving revision 1.1
diff -u -r1.1 mount_nfs4.c
--- sbin/mount_nfs4/mount_nfs4.c	14 Nov 2003 21:04:33 -0000	1.1
+++ sbin/mount_nfs4/mount_nfs4.c	21 Nov 2003 21:31:14 -0000
@@ -290,14 +290,8 @@
 	nfsargs = nfsdefargs;
 	nfsargsp = &nfsargs;
 	while ((c = getopt(argc, argv,
-	    "23a:bcdD:g:I:iLl:No:PR:r:sTt:w:x:U")) != -1)
+	    "a:bcdD:I:iNo:PR:sTt:x:U")) != -1)
 		switch (c) {
-		case '2':
-			mountmode = V2;
-			break;
-		case '3':
-			mountmode = V3;
-			break;
 		case 'a':
 			num = strtol(optarg, &p, 10);
 			if (*p || num < 0)
@@ -308,9 +302,6 @@
 		case 'b':
 			opflags |= BGRND;
 			break;
-		case 'c':
-			nfsargsp->flags |= NFSMNT_NOCONN;
-			break;
 		case 'D':
 			num = strtol(optarg, &p, 10);
 			if (*p || num <= 0)
@@ -318,19 +309,6 @@
 			nfsargsp->deadthresh = num;
 			nfsargsp->flags |= NFSMNT_DEADTHRESH;
 			break;
-		case 'd':
-			nfsargsp->flags |= NFSMNT_DUMBTIMR;
-			break;
-#if 0 /* XXXX */
-		case 'g':
-			num = strtol(optarg, &p, 10);
-			if (*p || num <= 0)
-				errx(1, "illegal -g value -- %s", optarg);
-			set_rpc_maxgrouplist(num);
-			nfsargsp->maxgrouplist = num;
-			nfsargsp->flags |= NFSMNT_MAXGRPS;
-			break;
-#endif
 		case 'I':
 			num = strtol(optarg, &p, 10);
 			if (*p || num <= 0)
@@ -341,12 +319,6 @@
 		case 'i':
 			nfsargsp->flags |= NFSMNT_INT;
 			break;
-		case 'L':
-			nfsargsp->flags |= NFSMNT_NOLOCKD;
-			break;
-		case 'l':
-			nfsargsp->flags |= NFSMNT_RDIRPLUS;
-			break;
 		case 'N':
 			nfsargsp->flags &= ~NFSMNT_RESVPORT;
 			break;
@@ -422,13 +394,6 @@
 				errx(1, "illegal -R value -- %s", optarg);
 			retrycnt = num;
 			break;
-		case 'r':
-			num = strtol(optarg, &p, 10);
-			if (*p || num <= 0)
-				errx(1, "illegal -r value -- %s", optarg);
-			nfsargsp->rsize = num;
-			nfsargsp->flags |= NFSMNT_RSIZE;
-			break;
 		case 's':
 			nfsargsp->flags |= NFSMNT_SOFT;
 			break;
@@ -443,13 +408,6 @@
 			nfsargsp->timeo = num;
 			nfsargsp->flags |= NFSMNT_TIMEO;
 			break;
-		case 'w':
-			num = strtol(optarg, &p, 10);
-			if (*p || num <= 0)
-				errx(1, "illegal -w value -- %s", optarg);
-			nfsargsp->wsize = num;
-			nfsargsp->flags |= NFSMNT_WSIZE;
-			break;
 		case 'x':
 			num = strtol(optarg, &p, 10);
 			if (*p || num <= 0)
@@ -667,47 +625,6 @@
 		}
 	}
 
-#if 0
-	/* Check that the server (nfsd) responds on the port we have chosen. */
-	clp = clnt_tli_create(RPC_ANYFD, nconf, &nfs_nb, RPCPROG_NFS, nfsvers,
-	    0, 0);
-	if (clp == NULL) {
-		snprintf(errbuf, sizeof errbuf, "[%s] %s:%s: %s", netid,
-		    hostp, spec, clnt_spcreateerror("nfsd: RPCPROG_NFS"));
-		return (returncode(rpc_createerr.cf_stat,
-		    &rpc_createerr.cf_error));
-	}
-	if (nfsargsp->sotype == SOCK_DGRAM &&
-	    !(nfsargsp->flags & NFSMNT_NOCONN)) {
-		/*
-		 * Use connect(), to match what the kernel does. This
-		 * catches cases where the server responds from the
-		 * wrong source address.
-		 */
-		doconnect = 1;
-		if (!clnt_control(clp, CLSET_CONNECT, (char *)&doconnect)) {
-			clnt_destroy(clp);
-			snprintf(errbuf, sizeof errbuf,
-			    "[%s] %s:%s: CLSET_CONNECT failed", netid, hostp,
-			    spec);
-			return (TRYRET_LOCALERR);
-		}
-	}
-
-	try.tv_sec = 10;
-	try.tv_usec = 0;
-	stat = clnt_call(clp, NFSPROC_NULL, (xdrproc_t)xdr_void, NULL,
-	    (xdrproc_t)xdr_void, NULL, try);
-	if (stat != RPC_SUCCESS) {
-		clnt_geterr(clp, &rpcerr);
-		snprintf(errbuf, sizeof errbuf, "[%s] %s:%s: %s", netid,
-		    hostp, spec, clnt_sperror(clp, "NFSPROC_NULL"));
-		clnt_destroy(clp);
-		return (returncode(stat, &rpcerr));
-	}
-	clnt_destroy(clp);
-#endif
-
 	/*
 	 * Store the filehandle and server address in nfsargsp, making
 	 * sure to copy any locally allocated structures.
@@ -865,9 +782,9 @@
 usage()
 {
 	(void)fprintf(stderr, "%s\n%s\n%s\n%s\n",
-"usage: mount_nfs [-23KNPTUbcdilqs] [-D deadthresh] [-I readdirsize]",
+"usage: mount_nfs [-KNPTUbiqs] [-D deadthresh] [-I readdirsize]",
 "                 [-R retrycnt] [-a maxreadahead]",
-"                 [-g maxgroups] [-m realm] [-o options] [-r readsize]",
-"                 [-t timeout] [-w writesize] [-x retrans] rhost:path node");
+"                 [-m realm] [-o options]",
+"                 [-t timeout] [-x retrans] rhost:path node");
 	exit(1);
 }
Index: sys/nfsclient/nfs.h
===================================================================
RCS file: /home/ncvs/src/sys/nfsclient/nfs.h,v
retrieving revision 1.75
diff -u -r1.75 nfs.h
--- sys/nfsclient/nfs.h	15 Nov 2003 05:03:15 -0000	1.75
+++ sys/nfsclient/nfs.h	21 Nov 2003 21:31:14 -0000
@@ -215,6 +215,20 @@
 #define	R_GETONEREP	0x80		/* Probe for one reply only */
 
 /*
+ * Pointers to ops that differ from v3 to v4
+ */
+struct nfs_rpcops {
+	int	(*nr_readrpc)(struct vnode *vp, struct uio *uiop, struct ucred *cred);
+	int	(*nr_writerpc)(struct vnode *vp, struct uio *uiop, struct ucred *cred,
+			       int *iomode, int *must_commit);
+	int	(*nr_writebp)(struct buf *bp, int force, struct thread *td);
+	int	(*nr_readlinkrpc)(struct vnode *vp, struct uio *uiop, struct ucred *cred);
+	void	(*nr_invaldir)(struct vnode *vp);
+	int	(*nr_commit)(struct vnode *vp, u_quad_t offset, int cnt,
+			     struct ucred *cred, struct thread *td);
+};
+
+/*
  * Defines for WebNFS
  */
 
Index: sys/nfsclient/nfs_bio.c
===================================================================
RCS file: /home/ncvs/src/sys/nfsclient/nfs_bio.c,v
retrieving revision 1.125
diff -u -r1.125 nfs_bio.c
--- sys/nfsclient/nfs_bio.c	14 Nov 2003 20:54:08 -0000	1.125
+++ sys/nfsclient/nfs_bio.c	21 Nov 2003 21:31:14 -0000
@@ -187,10 +187,7 @@
 	uio.uio_rw = UIO_READ;
 	uio.uio_td = td;
 
-	if ((nmp->nm_flag & NFSMNT_NFSV4) != 0)
-		error = nfs4_readrpc(vp, &uio, cred);
-	else
-		error = nfs_readrpc(vp, &uio, cred);
+	error = (nmp->nm_rpcops->nr_readrpc)(vp, &uio, cred);
 	pmap_qremove(kva, npages);
 
 	relpbuf(bp, &nfs_pbuf_freecnt);
@@ -352,10 +349,7 @@
 	else
 	    iomode = NFSV3WRITE_FILESYNC;
 
-	if ((nmp->nm_flag & NFSMNT_NFSV4) != 0)
-		error = nfs4_writerpc(vp, &uio, cred, &iomode, &must_commit);
-	else
-		error = nfs_writerpc(vp, &uio, cred, &iomode, &must_commit);
+	error = (nmp->nm_rpcops->nr_writerpc)(vp, &uio, cred, &iomode, &must_commit);
 
 	pmap_qremove(kva, npages);
 	relpbuf(bp, &nfs_pbuf_freecnt);
@@ -428,7 +422,7 @@
 		if (vp->v_type != VREG) {
 			if (vp->v_type != VDIR)
 				panic("nfs: bioread, not dir");
-			nfs_invaldir(vp);
+			(nmp->nm_rpcops->nr_invaldir)(vp);
 			error = nfs_vinvalbuf(vp, V_SAVE, cred, td, 1);
 			if (error)
 				return (error);
@@ -444,7 +438,7 @@
 			return (error);
 		if (np->n_mtime != vattr.va_mtime.tv_sec) {
 			if (vp->v_type == VDIR)
-				nfs_invaldir(vp);
+				(nmp->nm_rpcops->nr_invaldir)(vp);
 			error = nfs_vinvalbuf(vp, V_SAVE, cred, td, 1);
 			if (error)
 				return (error);
@@ -592,7 +586,7 @@
 		    }
 		    while (error == NFSERR_BAD_COOKIE) {
 			printf("got bad cookie vp %p bp %p\n", vp, bp);
-			nfs_invaldir(vp);
+			(nmp->nm_rpcops->nr_invaldir)(vp);
 			error = nfs_vinvalbuf(vp, 0, cred, td, 1);
 			/*
 			 * Yuck! The directory has been modified on the
@@ -1022,10 +1016,7 @@
 				break;
 		} else if ((n + on) == biosize) {
 			bp->b_flags |= B_ASYNC;
-			if ((nmp->nm_flag & NFSMNT_NFSV4) != 0)
-				(void)nfs4_writebp(bp, 0, 0);
-			else
-				(void)nfs_writebp(bp, 0, 0);
+			(void) (nmp->nm_rpcops->nr_writebp)(bp, 0, 0);
 		} else {
 			bdwrite(bp);
 		}
@@ -1330,7 +1321,7 @@
 	    case VREG:
 		uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE;
 		nfsstats.read_bios++;
-		error = nfs_readrpc(vp, uiop, cr);
+		error = (nmp->nm_rpcops->nr_readrpc)(vp, uiop, cr);
 
 		if (!error) {
 		    if (uiop->uio_resid) {
@@ -1363,7 +1354,7 @@
 	    case VLNK:
 		uiop->uio_offset = (off_t)0;
 		nfsstats.readlink_bios++;
-		error = nfs_readlinkrpc(vp, uiop, cr);
+		error = (nmp->nm_rpcops->nr_readlinkrpc)(vp, uiop, cr);
 		break;
 	    case VDIR:
 		nfsstats.readdir_bios++;
@@ -1404,7 +1395,7 @@
 
 		    off = ((u_quad_t)bp->b_blkno) * DEV_BSIZE + bp->b_dirtyoff;
 		    bp->b_flags |= B_WRITEINPROG;
-		    retv = nfs_commit(
+		    retv = (nmp->nm_rpcops->nr_commit)(
 				bp->b_vp, off, bp->b_dirtyend-bp->b_dirtyoff,
 				bp->b_wcred, td);
 		    bp->b_flags &= ~B_WRITEINPROG;
@@ -1442,7 +1433,7 @@
 		    iomode = NFSV3WRITE_FILESYNC;
 
 		bp->b_flags |= B_WRITEINPROG;
-		error = nfs_writerpc(vp, uiop, cr, &iomode, &must_commit);
+		error = (nmp->nm_rpcops->nr_writerpc)(vp, uiop, cr, &iomode, &must_commit);
 
 		/*
 		 * When setting B_NEEDCOMMIT also set B_CLUSTEROK to try
Index: sys/nfsclient/nfs_subs.c
===================================================================
RCS file: /home/ncvs/src/sys/nfsclient/nfs_subs.c,v
retrieving revision 1.121
diff -u -r1.121 nfs_subs.c
--- sys/nfsclient/nfs_subs.c	14 Nov 2003 20:54:09 -0000	1.121
+++ sys/nfsclient/nfs_subs.c	21 Nov 2003 21:31:15 -0000
@@ -763,10 +763,6 @@
 	if (vp->v_type != VDIR)
 		panic("nfs: invaldir not dir");
 #endif
-	if ((VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NFSV4) != 0) {
-		nfs4_invaldir(vp);
-		return;
-	}
 	np->n_direofoffset = 0;
 	np->n_cookieverf.nfsuquad[0] = 0;
 	np->n_cookieverf.nfsuquad[1] = 0;
Index: sys/nfsclient/nfs_vfsops.c
===================================================================
RCS file: /home/ncvs/src/sys/nfsclient/nfs_vfsops.c,v
retrieving revision 1.144
diff -u -r1.144 nfs_vfsops.c
--- sys/nfsclient/nfs_vfsops.c	14 Nov 2003 20:54:09 -0000	1.144
+++ sys/nfsclient/nfs_vfsops.c	21 Nov 2003 21:31:15 -0000
@@ -124,6 +124,15 @@
 /* So that loader and kldload(2) can find us, wherever we are.. */
 MODULE_VERSION(nfs, 1);
 
+static struct nfs_rpcops nfs_rpcops = {
+	nfs_readrpc,
+	nfs_writerpc,
+	nfs_writebp,
+	nfs_readlinkrpc,
+	nfs_invaldir,
+	nfs_commit,
+};
+
 /*
  * This structure must be filled in by a primary bootstrap or bootstrap
  * server for a diskless/dataless machine. It is initialized below just
@@ -790,6 +799,7 @@
 	/* Set up the sockets and per-host congestion */
 	nmp->nm_sotype = argp->sotype;
 	nmp->nm_soproto = argp->proto;
+	nmp->nm_rpcops = &nfs_rpcops;
 
 	nfs_decode_args(nmp, argp);
 
Index: sys/nfsclient/nfsmount.h
===================================================================
RCS file: /home/ncvs/src/sys/nfsclient/nfsmount.h,v
retrieving revision 1.24
diff -u -r1.24 nfsmount.h
--- sys/nfsclient/nfsmount.h	14 Nov 2003 20:54:09 -0000	1.24
+++ sys/nfsclient/nfsmount.h	21 Nov 2003 21:31:15 -0000
@@ -80,6 +80,7 @@
 	short	nm_bufqwant;		/* process wants to add to the queue */
 	int	nm_bufqiods;		/* number of iods processing queue */
 	u_int64_t nm_maxfilesize;	/* maximum file size */
+	struct nfs_rpcops *nm_rpcops;
 
 	/* NFSv4 */
 	uint64_t nm_clientid;
Index: sys/nfsclient/nfsnode.h
===================================================================
RCS file: /home/ncvs/src/sys/nfsclient/nfsnode.h,v
retrieving revision 1.40
diff -u -r1.40 nfsnode.h
--- sys/nfsclient/nfsnode.h	14 Nov 2003 20:54:09 -0000	1.40
+++ sys/nfsclient/nfsnode.h	21 Nov 2003 21:31:15 -0000
@@ -128,11 +128,7 @@
 	struct lock		n_rslock;
 	struct nfs4_fctx	n_rfc;
 	struct nfs4_fctx	n_wfc;
-	/*
-	 * The last component name is needed for the NFSv4 OPEN
-	 * operation.
-	 */
-	u_char			*n_name;
+	u_char			*n_name;	/* leaf name, for v4 OPEN op */
 	uint32_t		n_namelen;
 };
 
Index: sys/nfs4client/nfs4_vfsops.c
===================================================================
RCS file: /home/ncvs/src/sys/nfs4client/nfs4_vfsops.c,v
retrieving revision 1.2
diff -u -r1.2 nfs4_vfsops.c
--- sys/nfs4client/nfs4_vfsops.c	15 Nov 2003 00:26:42 -0000	1.2
+++ sys/nfs4client/nfs4_vfsops.c	21 Nov 2003 21:31:15 -0000
@@ -144,89 +144,20 @@
 };
 VFS_SET(nfs_vfsops, nfs4, VFCF_NETWORK);
 
+static struct nfs_rpcops nfs4_rpcops = {
+	nfs4_readrpc,
+	nfs4_writerpc,
+	nfs4_writebp,
+	nfs4_readlinkrpc,
+	nfs4_invaldir,
+	nfs4_commit,
+};
+
 /* So that loader and kldload(2) can find us, wherever we are.. */
 MODULE_VERSION(nfs4, 1);
 
 void		nfsargs_ntoh(struct nfs_args *);
 
-#ifdef NFS4DISKLESS
-/*
- * This structure must be filled in by a primary bootstrap or bootstrap
- * server for a diskless/dataless machine. It is initialized below just
- * to ensure that it is allocated to initialized data (.data not .bss).
- */
-struct nfs_diskless nfs_diskless = { { { 0 } } };
-struct nfsv3_diskless nfsv3_diskless = { { { 0 } } };
-int nfs_diskless_valid = 0;
-
-SYSCTL_INT(_vfs_nfs4, OID_AUTO, diskless_valid, CTLFLAG_RD,
-	&nfs_diskless_valid, 0, "");
-
-SYSCTL_STRING(_vfs_nfs4, OID_AUTO, diskless_rootpath, CTLFLAG_RD,
-	nfsv3_diskless.root_hostnam, 0, "");
-
-SYSCTL_OPAQUE(_vfs_nfs4, OID_AUTO, diskless_rootaddr, CTLFLAG_RD,
-	&nfsv3_diskless.root_saddr, sizeof nfsv3_diskless.root_saddr,
-	"%Ssockaddr_in", "");
-
-SYSCTL_STRING(_vfs_nfs4, OID_AUTO, diskless_swappath, CTLFLAG_RD,
-	nfsv3_diskless.swap_hostnam, 0, "");
-
-SYSCTL_OPAQUE(_vfs_nfs4, OID_AUTO, diskless_swapaddr, CTLFLAG_RD,
-	&nfsv3_diskless.swap_saddr, sizeof nfsv3_diskless.swap_saddr,
-	"%Ssockaddr_in","");
-
-static int	nfs_mountdiskless(char *, char *, int,
-		    struct sockaddr_in *, struct nfs_args *,
-		    struct thread *, struct vnode **, struct mount **);
-static void	nfs_convert_diskless(void);
-static void	nfs_convert_oargs(struct nfs_args *args,
-		    struct onfs_args *oargs);
-
-static void
-nfs_convert_oargs(struct nfs_args *args, struct onfs_args *oargs)
-{
-
-	args->version = NFS_ARGSVERSION;
-	args->addr = oargs->addr;
-	args->addrlen = oargs->addrlen;
-	args->sotype = oargs->sotype;
-	args->proto = oargs->proto;
-	args->fh = oargs->fh;
-	args->fhsize = oargs->fhsize;
-	args->flags = oargs->flags;
-	args->wsize = oargs->wsize;
-	args->rsize = oargs->rsize;
-	args->readdirsize = oargs->readdirsize;
-	args->timeo = oargs->timeo;
-	args->retrans = oargs->retrans;
-	args->maxgrouplist = oargs->maxgrouplist;
-	args->readahead = oargs->readahead;
-	args->deadthresh = oargs->deadthresh;
-	args->hostname = oargs->hostname;
-}
-
-static void
-nfs_convert_diskless(void)
-{
-
-	bcopy(&nfs_diskless.myif, &nfsv3_diskless.myif,
-		sizeof(struct ifaliasreq));
-	bcopy(&nfs_diskless.mygateway, &nfsv3_diskless.mygateway,
-		sizeof(struct sockaddr_in));
-	nfs_convert_oargs(&nfsv3_diskless.root_args,&nfs_diskless.root_args);
-	nfsv3_diskless.root_fhsize = NFSX_V2FH;
-	bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V2FH);
-	bcopy(&nfs_diskless.root_saddr,&nfsv3_diskless.root_saddr,
-		sizeof(struct sockaddr_in));
-	bcopy(nfs_diskless.root_hostnam, nfsv3_diskless.root_hostnam, MNAMELEN);
-	nfsv3_diskless.root_time = nfs_diskless.root_time;
-	bcopy(nfs_diskless.my_hostnam, nfsv3_diskless.my_hostnam,
-		MAXHOSTNAMELEN);
-	nfs_diskless_valid = 3;
-}
-#endif
-
 int
 nfs4_init(struct vfsconf *vfsp)
 {
@@ -632,10 +563,10 @@
 	/* Set up the sockets and per-host congestion */
 	nmp->nm_sotype = argp->sotype;
 	nmp->nm_soproto = argp->proto;
+	nmp->nm_rpcops = &nfs4_rpcops;
 	/* XXX */
         mp->mnt_stat.f_iosize = PAGE_SIZE;
 
-	/* XXX - this is to make some other code work.  Sort of ugly. */
 	argp->flags |= (NFSMNT_NFSV3 | NFSMNT_NFSV4);
 
 	nfs_decode_args(nmp, argp);
