[Midnightbsd-cvs] src [9922] trunk/sys: sync nfs code with freebsd

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Fri May 25 09:03:43 EDT 2018


Revision: 9922
          http://svnweb.midnightbsd.org/src/?rev=9922
Author:   laffer1
Date:     2018-05-25 09:03:43 -0400 (Fri, 25 May 2018)
Log Message:
-----------
sync nfs code with freebsd

Modified Paths:
--------------
    trunk/sys/nfs/bootp_subr.c
    trunk/sys/nfs/krpc.h
    trunk/sys/nfs/krpc_subr.c
    trunk/sys/nfs/nfs_common.c
    trunk/sys/nfs/nfs_common.h
    trunk/sys/nfs/nfs_diskless.c
    trunk/sys/nfs/nfs_fha.c
    trunk/sys/nfs/nfs_fha.h
    trunk/sys/nfs/nfs_kdtrace.h
    trunk/sys/nfs/nfs_lock.c
    trunk/sys/nfs/nfs_lock.h
    trunk/sys/nfs/nfs_mountcommon.h
    trunk/sys/nfs/nfs_nfssvc.c
    trunk/sys/nfs/nfsdiskless.h
    trunk/sys/nfs/nfsproto.h
    trunk/sys/nfs/nfssvc.h
    trunk/sys/nfs/xdr_subs.h
    trunk/sys/nfsclient/nfs.h
    trunk/sys/nfsclient/nfs_bio.c
    trunk/sys/nfsclient/nfs_kdtrace.c
    trunk/sys/nfsclient/nfs_krpc.c
    trunk/sys/nfsclient/nfs_nfsiod.c
    trunk/sys/nfsclient/nfs_node.c
    trunk/sys/nfsclient/nfs_subs.c
    trunk/sys/nfsclient/nfs_vfsops.c
    trunk/sys/nfsclient/nfs_vnops.c
    trunk/sys/nfsclient/nfsargs.h
    trunk/sys/nfsclient/nfsm_subs.h
    trunk/sys/nfsclient/nfsmount.h
    trunk/sys/nfsclient/nfsnode.h
    trunk/sys/nfsclient/nfsstats.h
    trunk/sys/nfsclient/nlminfo.h

Modified: trunk/sys/nfs/bootp_subr.c
===================================================================
--- trunk/sys/nfs/bootp_subr.c	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfs/bootp_subr.c	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1995 Gordon Ross, Adam Glass
  * Copyright (c) 1992 Regents of the University of California.
@@ -41,13 +42,15 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/nfs/bootp_subr.c 301057 2016-05-31 17:15:57Z ian $");
 
 #include "opt_bootp.h"
 #include "opt_nfs.h"
+#include "opt_rootdevname.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/endian.h>
 #include <sys/jail.h>
 #include <sys/kernel.h>
 #include <sys/sockio.h>
@@ -55,6 +58,7 @@
 #include <sys/mount.h>
 #include <sys/mbuf.h>
 #include <sys/proc.h>
+#include <sys/reboot.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/sysctl.h>
@@ -64,6 +68,7 @@
 #include <net/route.h>
 
 #include <netinet/in.h>
+#include <netinet/in_var.h>
 #include <net/if_types.h>
 #include <net/if_dl.h>
 #include <net/vnet.h>
@@ -81,6 +86,14 @@
 #define BOOTP_SETTLE_DELAY 3
 #endif
 
+/* 
+ * Wait 10 seconds for interface appearance
+ * USB ethernet adapters might require some time to pop up
+ */
+#ifndef	BOOTP_IFACE_WAIT_TIMEOUT
+#define	BOOTP_IFACE_WAIT_TIMEOUT	10
+#endif
+
 /*
  * What is the longest we will wait before re-sending a request?
  * Note this is also the frequency of "RPC timeout" messages.
@@ -109,19 +122,22 @@
 };
 
 struct bootpc_ifcontext {
-	struct bootpc_ifcontext *next;
+	STAILQ_ENTRY(bootpc_ifcontext) next;
 	struct bootp_packet call;
 	struct bootp_packet reply;
 	int replylen;
 	int overload;
-	struct socket *so;
-	struct ifreq ireq;
+	union {
+		struct ifreq _ifreq;
+		struct in_aliasreq _in_alias_req;
+	} _req;
+#define	ireq	_req._ifreq
+#define	iareq	_req._in_alias_req
 	struct ifnet *ifp;
 	struct sockaddr_dl *sdl;
 	struct sockaddr_in myaddr;
 	struct sockaddr_in netmask;
 	struct sockaddr_in gw;
-	struct sockaddr_in broadcast;	/* Different for each interface */
 	int gotgw;
 	int gotnetmask;
 	int gotrootpath;
@@ -140,6 +156,7 @@
 	int dhcpquerytype;		/* dhcp type sent */
 	struct in_addr dhcpserver;
 	int gotdhcpserver;
+	uint16_t mtu;
 };
 
 #define TAG_MAXLEN 1024
@@ -153,9 +170,9 @@
 };
 
 struct bootpc_globalcontext {
-	struct bootpc_ifcontext *interfaces;
-	struct bootpc_ifcontext *lastinterface;
+	STAILQ_HEAD(, bootpc_ifcontext) interfaces;
 	u_int32_t xid;
+	int any_root_overrides;
 	int gotrootpath;
 	int gotgw;
 	int ifnum;
@@ -181,6 +198,7 @@
 #define TAG_ROUTERS	  3  /* Routers (in order of preference) */
 #define TAG_HOSTNAME	 12  /* Client host name */
 #define TAG_ROOT	 17  /* Root path */
+#define TAG_INTF_MTU	 26  /* Interface MTU Size (RFC2132) */
 
 /* DHCP specific tags */
 #define TAG_OVERLOAD	 52  /* Option Overload */
@@ -215,6 +233,7 @@
 #endif
 
 static char bootp_cookie[128];
+static struct socket *bootp_so;
 SYSCTL_STRING(_kern, OID_AUTO, bootp_cookie, CTLFLAG_RD,
 	bootp_cookie, 0, "Cookie (T134) supplied by bootp server");
 
@@ -233,7 +252,7 @@
 static void	clear_sinaddr(struct sockaddr_in *sin);
 static void	allocifctx(struct bootpc_globalcontext *gctx);
 static void	bootpc_compose_query(struct bootpc_ifcontext *ifctx,
-		    struct bootpc_globalcontext *gctx, struct thread *td);
+		    struct thread *td);
 static unsigned char *bootpc_tag(struct bootpc_tagcontext *tctx,
 		    struct bootp_packet *bp, int len, int tag);
 static void bootpc_tag_helper(struct bootpc_tagcontext *tctx,
@@ -251,10 +270,10 @@
 static int	bootpc_call(struct bootpc_globalcontext *gctx,
 		    struct thread *td);
 
-static int	bootpc_fakeup_interface(struct bootpc_ifcontext *ifctx,
-		    struct bootpc_globalcontext *gctx, struct thread *td);
+static void	bootpc_fakeup_interface(struct bootpc_ifcontext *ifctx,
+		    struct thread *td);
 
-static int	bootpc_adjust_interface(struct bootpc_ifcontext *ifctx,
+static void	bootpc_adjust_interface(struct bootpc_ifcontext *ifctx,
 		    struct bootpc_globalcontext *gctx, struct thread *td);
 
 static void	bootpc_decode_reply(struct nfsv3_diskless *nd,
@@ -270,14 +289,9 @@
 
 /*
  * In order to have multiple active interfaces with address 0.0.0.0
- * and be able to send data to a selected interface, we perform
- * some tricks:
- *
- *  - The 'broadcast' address is different for each interface.
- *
- *  - We temporarily add routing pointing 255.255.255.255 to the
- *    selected interface broadcast address, thus the packet sent
- *    goes to that interface.
+ * and be able to send data to a selected interface, we first set
+ * mask to /8 on all interfaces, and temporarily set it to /0 when
+ * doing sosend().
  */
 
 #ifdef BOOTP_DEBUG
@@ -332,7 +346,7 @@
 	bootpboot_p_sa(rt->rt_gateway, NULL);
 	printf(" ");
 	printf("flags %x", (unsigned short) rt->rt_flags);
-	printf(" %d", (int) rt->rt_rmx.rmx_expire);
+	printf(" %d", (int) rt->rt_expire);
 	printf(" %s\n", rt->rt_ifp->if_xname);
 }
 
@@ -419,11 +433,8 @@
 allocifctx(struct bootpc_globalcontext *gctx)
 {
 	struct bootpc_ifcontext *ifctx;
-	ifctx = (struct bootpc_ifcontext *) malloc(sizeof(*ifctx),
-						   M_TEMP, M_WAITOK | M_ZERO);
-	if (ifctx == NULL)
-		panic("Failed to allocate bootp interface context structure");
 
+	ifctx = malloc(sizeof(*ifctx), M_TEMP, M_WAITOK | M_ZERO);
 	ifctx->xid = gctx->xid;
 #ifdef BOOTP_NO_DHCP
 	ifctx->state = IF_BOOTP_UNRESOLVED;
@@ -431,11 +442,7 @@
 	ifctx->state = IF_DHCP_UNRESOLVED;
 #endif
 	gctx->xid += 0x100;
-	if (gctx->interfaces != NULL)
-		gctx->lastinterface->next = ifctx;
-	else
-		gctx->interfaces = ifctx;
-	gctx->lastinterface = ifctx;
+	STAILQ_INSERT_TAIL(&gctx->interfaces, ifctx, next);
 }
 
 static __inline int
@@ -570,7 +577,6 @@
 static int
 bootpc_call(struct bootpc_globalcontext *gctx, struct thread *td)
 {
-	struct socket *so;
 	struct sockaddr_in *sin, dst;
 	struct uio auio;
 	struct sockopt sopt;
@@ -585,13 +591,6 @@
 	int retry;
 	const char *s;
 
-	/*
-	 * Create socket and set its recieve timeout.
-	 */
-	error = socreate(AF_INET, &so, SOCK_DGRAM, 0, td->td_ucred, td);
-	if (error != 0)
-		goto out0;
-
 	tv.tv_sec = 1;
 	tv.tv_usec = 0;
 	bzero(&sopt, sizeof(sopt));
@@ -601,7 +600,7 @@
 	sopt.sopt_val = &tv;
 	sopt.sopt_valsize = sizeof tv;
 
-	error = sosetopt(so, &sopt);
+	error = sosetopt(bootp_so, &sopt);
 	if (error != 0)
 		goto out;
 
@@ -613,7 +612,7 @@
 	sopt.sopt_val = &on;
 	sopt.sopt_valsize = sizeof on;
 
-	error = sosetopt(so, &sopt);
+	error = sosetopt(bootp_so, &sopt);
 	if (error != 0)
 		goto out;
 
@@ -626,7 +625,7 @@
 	sopt.sopt_val = &on;
 	sopt.sopt_valsize = sizeof on;
 
-	error = sosetopt(so, &sopt);
+	error = sosetopt(bootp_so, &sopt);
 	if (error != 0)
 		goto out;
 
@@ -636,7 +635,7 @@
 	sin = &dst;
 	clear_sinaddr(sin);
 	sin->sin_port = htons(IPPORT_BOOTPC);
-	error = sobind(so, (struct sockaddr *)sin, td);
+	error = sobind(bootp_so, (struct sockaddr *)sin, td);
 	if (error != 0) {
 		printf("bind failed\n");
 		goto out;
@@ -662,9 +661,7 @@
 		outstanding = 0;
 		gotrootpath = 0;
 
-		for (ifctx = gctx->interfaces;
-		     ifctx != NULL;
-		     ifctx = ifctx->next) {
+		STAILQ_FOREACH(ifctx, &gctx->interfaces, next) {
 			if (bootpc_ifctx_isresolved(ifctx) != 0 &&
 			    bootpc_tag(&gctx->tmptag, &ifctx->reply,
 				       ifctx->replylen,
@@ -672,9 +669,10 @@
 				gotrootpath = 1;
 		}
 
-		for (ifctx = gctx->interfaces;
-		     ifctx != NULL;
-		     ifctx = ifctx->next) {
+		STAILQ_FOREACH(ifctx, &gctx->interfaces, next) {
+			struct in_aliasreq *ifra = &ifctx->iareq;
+			sin = (struct sockaddr_in *)&ifra->ifra_mask;
+
 			ifctx->outstanding = 0;
 			if (bootpc_ifctx_isresolved(ifctx)  != 0 &&
 			    gotrootpath != 0) {
@@ -694,7 +692,7 @@
 			    (ifctx->state == IF_BOOTP_UNRESOLVED &&
 			     ifctx->dhcpquerytype != DHCP_NOMSG)) {
 				ifctx->sentmsg = 0;
-				bootpc_compose_query(ifctx, gctx, td);
+				bootpc_compose_query(ifctx, td);
 			}
 
 			/* Send BOOTP request (or re-send). */
@@ -734,44 +732,32 @@
 			auio.uio_td = td;
 
 			/* Set netmask to 0.0.0.0 */
-
-			sin = (struct sockaddr_in *) &ifctx->ireq.ifr_addr;
 			clear_sinaddr(sin);
-			error = ifioctl(ifctx->so, SIOCSIFNETMASK,
-					(caddr_t) &ifctx->ireq, td);
+			error = ifioctl(bootp_so, SIOCAIFADDR, (caddr_t)ifra,
+			    td);
 			if (error != 0)
-				panic("bootpc_call:"
-				      "set if netmask, error=%d",
-				      error);
+				panic("%s: SIOCAIFADDR, error=%d", __func__,
+				    error);
 
-			error = sosend(so, (struct sockaddr *) &dst,
+			error = sosend(bootp_so, (struct sockaddr *) &dst,
 				       &auio, NULL, NULL, 0, td);
-			if (error != 0) {
-				printf("bootpc_call: sosend: %d state %08x\n",
-				       error, (int) so->so_state);
-			}
+			if (error != 0)
+				printf("%s: sosend: %d state %08x\n", __func__,
+				    error, (int )bootp_so->so_state);
 
-			/* XXX: Is this needed ? */
-			pause("bootpw", hz/10);
-
 			/* Set netmask to 255.0.0.0 */
-
-			sin = (struct sockaddr_in *) &ifctx->ireq.ifr_addr;
-			clear_sinaddr(sin);
-			sin->sin_addr.s_addr = htonl(0xff000000u);
-			error = ifioctl(ifctx->so, SIOCSIFNETMASK,
-					(caddr_t) &ifctx->ireq, td);
+			sin->sin_addr.s_addr = htonl(IN_CLASSA_NET);
+			error = ifioctl(bootp_so, SIOCAIFADDR, (caddr_t)ifra,
+			    td);
 			if (error != 0)
-				panic("bootpc_call:"
-				      "set if netmask, error=%d",
-				      error);
-
+				panic("%s: SIOCAIFADDR, error=%d", __func__,
+				    error);
 		}
 
 		if (outstanding == 0 &&
 		    (rtimo == 0 || time_second >= rtimo)) {
 			error = 0;
-			goto gotreply;
+			goto out;
 		}
 
 		/* Determine new timeout. */
@@ -801,12 +787,10 @@
 			auio.uio_td = td;
 
 			rcvflg = 0;
-			error = soreceive(so, NULL, &auio,
+			error = soreceive(bootp_so, NULL, &auio,
 					  NULL, NULL, &rcvflg);
 			gctx->secs = time_second - gctx->starttime;
-			for (ifctx = gctx->interfaces;
-			     ifctx != NULL;
-			     ifctx = ifctx->next) {
+			STAILQ_FOREACH(ifctx, &gctx->interfaces, next) {
 				if (bootpc_ifctx_isresolved(ifctx) != 0 ||
 				    bootpc_ifctx_isfailed(ifctx) != 0)
 					continue;
@@ -829,9 +813,7 @@
 				continue;
 
 			/* Is this an answer to our query */
-			for (ifctx = gctx->interfaces;
-			     ifctx != NULL;
-			     ifctx = ifctx->next) {
+			STAILQ_FOREACH(ifctx, &gctx->interfaces, next) {
 				if (gctx->reply.xid != ifctx->call.xid)
 					continue;
 
@@ -890,13 +872,14 @@
 							BOOTP_SETTLE_DELAY;
 				} else
 					printf(" (ignored)");
-				if (ifctx->gotrootpath) {
+				if (ifctx->gotrootpath || 
+				    gctx->any_root_overrides) {
 					gotrootpath = 1;
 					rtimo = time_second +
 						BOOTP_SETTLE_DELAY;
-					printf(" (got root path)");
-				} else
-					printf(" (no root path)");
+					if (ifctx->gotrootpath)
+						printf(" (got root path)");
+				}
 				printf("\n");
 			}
 		} /* while secs */
@@ -906,8 +889,7 @@
 #endif
 		/* Force a retry if halfway in DHCP negotiation */
 		retry = 0;
-		for (ifctx = gctx->interfaces; ifctx != NULL;
-		     ifctx = ifctx->next) {
+		STAILQ_FOREACH(ifctx, &gctx->interfaces, next)
 			if (ifctx->state == IF_DHCP_OFFERED) {
 				if (ifctx->dhcpquerytype == DHCP_DISCOVER)
 					retry = 1;
@@ -914,7 +896,6 @@
 				else
 					ifctx->state = IF_DHCP_UNRESOLVED;
 			}
-		}
 
 		if (retry != 0)
 			continue;
@@ -931,7 +912,7 @@
 	 * ignored
 	 */
 
-	for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next) {
+	STAILQ_FOREACH(ifctx, &gctx->interfaces, next)
 		if (bootpc_ifctx_isresolved(ifctx) == 0) {
 			printf("%s timeout for interface %s\n",
 			       ifctx->dhcpquerytype != DHCP_NOMSG ?
@@ -938,7 +919,7 @@
 			       "DHCP" : "BOOTP",
 			       ifctx->ireq.ifr_name);
 		}
-	}
+
 	if (gctx->gotrootpath != 0) {
 #if 0
 		printf("Got a root path, ignoring remaining timeout\n");
@@ -947,41 +928,29 @@
 		goto out;
 	}
 #ifndef BOOTP_NFSROOT
-	for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next) {
+	STAILQ_FOREACH(ifctx, &gctx->interfaces, next)
 		if (bootpc_ifctx_isresolved(ifctx) != 0) {
 			error = 0;
 			goto out;
 		}
-	}
 #endif
 	error = ETIMEDOUT;
-	goto out;
 
-gotreply:
 out:
-	soclose(so);
-out0:
-	return error;
+	return (error);
 }
 
-static int
-bootpc_fakeup_interface(struct bootpc_ifcontext *ifctx,
-    struct bootpc_globalcontext *gctx, struct thread *td)
+static void
+bootpc_fakeup_interface(struct bootpc_ifcontext *ifctx, struct thread *td)
 {
+	struct ifreq *ifr;
+	struct in_aliasreq *ifra;
 	struct sockaddr_in *sin;
 	int error;
-	struct ifreq *ireq;
-	struct socket *so;
-	struct ifaddr *ifa;
-	struct sockaddr_dl *sdl;
 
-	error = socreate(AF_INET, &ifctx->so, SOCK_DGRAM, 0, td->td_ucred, td);
-	if (error != 0)
-		panic("nfs_boot: socreate, error=%d", error);
+	ifr = &ifctx->ireq;
+	ifra = &ifctx->iareq;
 
-	ireq = &ifctx->ireq;
-	so = ifctx->so;
-
 	/*
 	 * Bring up the interface.
 	 *
@@ -988,163 +957,153 @@
 	 * Get the old interface flags and or IFF_UP into them; if
 	 * IFF_UP set blindly, interface selection can be clobbered.
 	 */
-	error = ifioctl(so, SIOCGIFFLAGS, (caddr_t)ireq, td);
+	error = ifioctl(bootp_so, SIOCGIFFLAGS, (caddr_t)ifr, td);
 	if (error != 0)
-		panic("bootpc_fakeup_interface: GIFFLAGS, error=%d", error);
-	ireq->ifr_flags |= IFF_UP;
-	error = ifioctl(so, SIOCSIFFLAGS, (caddr_t)ireq, td);
+		panic("%s: SIOCGIFFLAGS, error=%d", __func__, error);
+	ifr->ifr_flags |= IFF_UP;
+	error = ifioctl(bootp_so, SIOCSIFFLAGS, (caddr_t)ifr, td);
 	if (error != 0)
-		panic("bootpc_fakeup_interface: SIFFLAGS, error=%d", error);
+		panic("%s: SIOCSIFFLAGS, error=%d", __func__, error);
 
 	/*
 	 * Do enough of ifconfig(8) so that the chosen interface
-	 * can talk to the servers.  (just set the address)
+	 * can talk to the servers. Set address to 0.0.0.0/8 and
+	 * broadcast address to local broadcast.
 	 */
-
-	/* addr is 0.0.0.0 */
-
-	sin = (struct sockaddr_in *) &ireq->ifr_addr;
+	sin = (struct sockaddr_in *)&ifra->ifra_addr;
 	clear_sinaddr(sin);
-	error = ifioctl(so, SIOCSIFADDR, (caddr_t) ireq, td);
-	if (error != 0 && (error != EEXIST || ifctx == gctx->interfaces))
-		panic("bootpc_fakeup_interface: "
-		      "set if addr, error=%d", error);
-
-	/* netmask is 255.0.0.0 */
-
-	sin = (struct sockaddr_in *) &ireq->ifr_addr;
+	sin = (struct sockaddr_in *)&ifra->ifra_mask;
 	clear_sinaddr(sin);
-	sin->sin_addr.s_addr = htonl(0xff000000u);
-	error = ifioctl(so, SIOCSIFNETMASK, (caddr_t)ireq, td);
-	if (error != 0)
-		panic("bootpc_fakeup_interface: set if netmask, error=%d",
-		      error);
-
-	/* Broadcast is 255.255.255.255 */
-
-	sin = (struct sockaddr_in *)&ireq->ifr_addr;
+	sin->sin_addr.s_addr = htonl(IN_CLASSA_NET);
+	sin = (struct sockaddr_in *)&ifra->ifra_broadaddr;
 	clear_sinaddr(sin);
-	clear_sinaddr(&ifctx->broadcast);
 	sin->sin_addr.s_addr = htonl(INADDR_BROADCAST);
-	ifctx->broadcast.sin_addr.s_addr = sin->sin_addr.s_addr;
-
-	error = ifioctl(so, SIOCSIFBRDADDR, (caddr_t)ireq, td);
+	error = ifioctl(bootp_so, SIOCAIFADDR, (caddr_t)ifra, td);
 	if (error != 0)
-		panic("bootpc_fakeup_interface: "
-		      "set if broadcast addr, error=%d",
-		      error);
+		panic("%s: SIOCAIFADDR, error=%d", __func__, error);
+}
 
-	/* Get HW address */
+static void
+bootpc_shutdown_interface(struct bootpc_ifcontext *ifctx, struct thread *td)
+{
+	struct ifreq *ifr;
+	struct sockaddr_in *sin;
+	int error;
 
-	sdl = NULL;
-	TAILQ_FOREACH(ifa, &ifctx->ifp->if_addrhead, ifa_link)
-		if (ifa->ifa_addr->sa_family == AF_LINK) {
-			sdl = (struct sockaddr_dl *)ifa->ifa_addr;
-			if (sdl->sdl_type == IFT_ETHER)
-				break;
-		}
+	ifr = &ifctx->ireq;
 
-	if (sdl == NULL)
-		panic("bootpc: Unable to find HW address for %s",
-		      ifctx->ireq.ifr_name);
-	ifctx->sdl = sdl;
+	printf("Shutdown interface %s\n", ifctx->ireq.ifr_name);
+	error = ifioctl(bootp_so, SIOCGIFFLAGS, (caddr_t)ifr, td);
+	if (error != 0)
+		panic("%s: SIOCGIFFLAGS, error=%d", __func__, error);
+	ifr->ifr_flags &= ~IFF_UP;
+	error = ifioctl(bootp_so, SIOCSIFFLAGS, (caddr_t)ifr, td);
+	if (error != 0)
+		panic("%s: SIOCSIFFLAGS, error=%d", __func__, error);
 
-	return error;
+	sin = (struct sockaddr_in *) &ifr->ifr_addr;
+	clear_sinaddr(sin);
+	error = ifioctl(bootp_so, SIOCDIFADDR, (caddr_t) ifr, td);
+	if (error != 0)
+		panic("%s: SIOCDIFADDR, error=%d", __func__, error);
 }
 
-
-static int
+static void
 bootpc_adjust_interface(struct bootpc_ifcontext *ifctx,
     struct bootpc_globalcontext *gctx, struct thread *td)
 {
 	int error;
-	struct sockaddr_in defdst;
-	struct sockaddr_in defmask;
 	struct sockaddr_in *sin;
-	struct ifreq *ireq;
-	struct socket *so;
+	struct ifreq *ifr;
+	struct in_aliasreq *ifra;
 	struct sockaddr_in *myaddr;
 	struct sockaddr_in *netmask;
-	struct sockaddr_in *gw;
 
-	ireq = &ifctx->ireq;
-	so = ifctx->so;
+	ifr = &ifctx->ireq;
+	ifra = &ifctx->iareq;
 	myaddr = &ifctx->myaddr;
 	netmask = &ifctx->netmask;
-	gw = &ifctx->gw;
 
 	if (bootpc_ifctx_isresolved(ifctx) == 0) {
-
 		/* Shutdown interfaces where BOOTP failed */
+		bootpc_shutdown_interface(ifctx, td);
+		return;
+	}
 
-		printf("Shutdown interface %s\n", ifctx->ireq.ifr_name);
-		error = ifioctl(so, SIOCGIFFLAGS, (caddr_t)ireq, td);
+	printf("Adjusted interface %s", ifctx->ireq.ifr_name);
+
+	/* Do BOOTP interface options */
+	if (ifctx->mtu != 0) {
+		printf(" (MTU=%d%s)", ifctx->mtu, 
+		    (ifctx->mtu > 1514) ? "/JUMBO" : "");
+		ifr->ifr_mtu = ifctx->mtu;
+		error = ifioctl(bootp_so, SIOCSIFMTU, (caddr_t) ifr, td);
 		if (error != 0)
-			panic("bootpc_adjust_interface: "
-			      "SIOCGIFFLAGS, error=%d", error);
-		ireq->ifr_flags &= ~IFF_UP;
-		error = ifioctl(so, SIOCSIFFLAGS, (caddr_t)ireq, td);
-		if (error != 0)
-			panic("bootpc_adjust_interface: "
-			      "SIOCSIFFLAGS, error=%d", error);
-
-		sin = (struct sockaddr_in *) &ireq->ifr_addr;
-		clear_sinaddr(sin);
-		error = ifioctl(so, SIOCDIFADDR, (caddr_t) ireq, td);
-		if (error != 0 && (error != EEXIST ||
-				   ifctx == gctx->interfaces))
-			panic("bootpc_adjust_interface: "
-			      "SIOCDIFADDR, error=%d", error);
-
-		return 0;
+			panic("%s: SIOCSIFMTU, error=%d", __func__, error);
 	}
+	printf("\n");
 
-	printf("Adjusted interface %s\n", ifctx->ireq.ifr_name);
 	/*
 	 * Do enough of ifconfig(8) so that the chosen interface
 	 * can talk to the servers.  (just set the address)
 	 */
-	bcopy(netmask, &ireq->ifr_addr, sizeof(*netmask));
-	error = ifioctl(so, SIOCSIFNETMASK, (caddr_t) ireq, td);
+	sin = (struct sockaddr_in *) &ifr->ifr_addr;
+	clear_sinaddr(sin);
+	error = ifioctl(bootp_so, SIOCDIFADDR, (caddr_t) ifr, td);
 	if (error != 0)
-		panic("bootpc_adjust_interface: "
-		      "set if netmask, error=%d", error);
+		panic("%s: SIOCDIFADDR, error=%d", __func__, error);
 
-	/* Broadcast is with host part of IP address all 1's */
+	bcopy(myaddr, &ifra->ifra_addr, sizeof(*myaddr));
+	bcopy(netmask, &ifra->ifra_mask, sizeof(*netmask));
+	clear_sinaddr(&ifra->ifra_broadaddr);
+	ifra->ifra_broadaddr.sin_addr.s_addr = myaddr->sin_addr.s_addr |
+	    ~netmask->sin_addr.s_addr;
 
-	sin = (struct sockaddr_in *) &ireq->ifr_addr;
-	clear_sinaddr(sin);
-	sin->sin_addr.s_addr = myaddr->sin_addr.s_addr |
-		~ netmask->sin_addr.s_addr;
-	error = ifioctl(so, SIOCSIFBRDADDR, (caddr_t) ireq, td);
+	error = ifioctl(bootp_so, SIOCAIFADDR, (caddr_t)ifra, td);
 	if (error != 0)
-		panic("bootpc_adjust_interface: "
-		      "set if broadcast addr, error=%d", error);
+		panic("%s: SIOCAIFADDR, error=%d", __func__, error);
+}
 
-	bcopy(myaddr, &ireq->ifr_addr, sizeof(*myaddr));
-	error = ifioctl(so, SIOCSIFADDR, (caddr_t) ireq, td);
-	if (error != 0 && (error != EEXIST || ifctx == gctx->interfaces))
-		panic("bootpc_adjust_interface: "
-		      "set if addr, error=%d", error);
+static void
+bootpc_add_default_route(struct bootpc_ifcontext *ifctx)
+{
+	int error;
+	struct sockaddr_in defdst;
+	struct sockaddr_in defmask;
 
-	/* Add new default route */
+	if (ifctx->gw.sin_addr.s_addr == htonl(INADDR_ANY))
+		return;
 
-	if (ifctx->gotgw != 0 || gctx->gotgw == 0) {
-		clear_sinaddr(&defdst);
-		clear_sinaddr(&defmask);
-		/* XXX MRT just table 0 */
-		error = rtrequest_fib(RTM_ADD,
-		    (struct sockaddr *) &defdst, (struct sockaddr *) gw,
-		    (struct sockaddr *) &defmask,
-		    (RTF_UP | RTF_GATEWAY | RTF_STATIC), NULL, RT_DEFAULT_FIB);
-		if (error != 0) {
-			printf("bootpc_adjust_interface: "
-			       "add net route, error=%d\n", error);
-			return error;
-		}
+	clear_sinaddr(&defdst);
+	clear_sinaddr(&defmask);
+
+	error = rtrequest_fib(RTM_ADD, (struct sockaddr *)&defdst,
+	    (struct sockaddr *) &ifctx->gw, (struct sockaddr *)&defmask,
+	    (RTF_UP | RTF_GATEWAY | RTF_STATIC), NULL, RT_DEFAULT_FIB);
+	if (error != 0) {
+		printf("%s: RTM_ADD, error=%d\n", __func__, error);
 	}
+}
 
-	return 0;
+static void
+bootpc_remove_default_route(struct bootpc_ifcontext *ifctx)
+{
+	int error;
+	struct sockaddr_in defdst;
+	struct sockaddr_in defmask;
+
+	if (ifctx->gw.sin_addr.s_addr == htonl(INADDR_ANY))
+		return;
+
+	clear_sinaddr(&defdst);
+	clear_sinaddr(&defmask);
+
+	error = rtrequest_fib(RTM_DELETE, (struct sockaddr *)&defdst,
+	    (struct sockaddr *) &ifctx->gw, (struct sockaddr *)&defmask,
+	    (RTF_UP | RTF_GATEWAY | RTF_STATIC), NULL, RT_DEFAULT_FIB);
+	if (error != 0) {
+		printf("%s: RTM_DELETE, error=%d\n", __func__, error);
+	}
 }
 
 static int
@@ -1287,8 +1246,7 @@
 }
 
 static void
-bootpc_compose_query(struct bootpc_ifcontext *ifctx,
-    struct bootpc_globalcontext *gctx, struct thread *td)
+bootpc_compose_query(struct bootpc_ifcontext *ifctx, struct thread *td)
 {
 	unsigned char *vendp;
 	unsigned char vendor_client[64];
@@ -1453,7 +1411,7 @@
 bootpc_decode_reply(struct nfsv3_diskless *nd, struct bootpc_ifcontext *ifctx,
     struct bootpc_globalcontext *gctx)
 {
-	char *p;
+	char *p, *s;
 	unsigned int ip;
 
 	ifctx->gotgw = 0;
@@ -1520,8 +1478,32 @@
 		}
 	}
 
-	p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen,
+	/*
+	 * Choose a root filesystem.  If a value is forced in the environment
+	 * and it contains "nfs:", use it unconditionally.  Otherwise, if the
+	 * kernel is compiled with the ROOTDEVNAME option, then use it if:
+	 *  - The server doesn't provide a pathname.
+	 *  - The boothowto flags include RB_DFLTROOT (user said to override
+	 *    the server value).
+	 */
+	p = NULL;
+	if ((s = getenv("vfs.root.mountfrom")) != NULL) {
+		if ((p = strstr(s, "nfs:")) != NULL)
+			p = strdup(p + 4, M_TEMP);
+		freeenv(s);
+	}
+	if (p == NULL) {
+		p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen,
 		       TAG_ROOT);
+		if (p != NULL)
+			ifctx->gotrootpath = 1;
+	}
+#ifdef ROOTDEVNAME
+	if ((p == NULL || (boothowto & RB_DFLTROOT) != 0) && 
+	    (p = strstr(ROOTDEVNAME, "nfs:")) != NULL) {
+		p += 4;
+	}
+#endif
 	if (p != NULL) {
 		if (gctx->setrootfs != NULL) {
 			printf("rootfs %s (ignored) ", p);
@@ -1534,7 +1516,6 @@
 			}
 			printf("rootfs %s ", p);
 			gctx->gotrootpath = 1;
-			ifctx->gotrootpath = 1;
 			gctx->setrootfs = ifctx;
 
 			p = bootpc_tag(&gctx->tag, &ifctx->reply,
@@ -1574,6 +1555,11 @@
 		p[i] = '\0';
 	}
 
+	p = bootpc_tag(&gctx->tag, &ifctx->reply, ifctx->replylen,
+		       TAG_INTF_MTU);
+	if (p != NULL) {
+		ifctx->mtu = be16dec(p);
+	}
 
 	printf("\n");
 
@@ -1585,18 +1571,16 @@
 		else
 			ifctx->netmask.sin_addr.s_addr = htonl(IN_CLASSC_NET);
 	}
-	if (ifctx->gotgw == 0) {
-		/* Use proxyarp */
-		ifctx->gw.sin_addr.s_addr = ifctx->myaddr.sin_addr.s_addr;
-	}
 }
 
 void
 bootpc_init(void)
 {
-	struct bootpc_ifcontext *ifctx, *nctx;	/* Interface BOOTP contexts */
+	struct bootpc_ifcontext *ifctx;		/* Interface BOOTP contexts */
 	struct bootpc_globalcontext *gctx; 	/* Global BOOTP context */
 	struct ifnet *ifp;
+	struct sockaddr_dl *sdl;
+	struct ifaddr *ifa;
 	int error;
 #ifndef BOOTP_WIRED_TO
 	int ifcnt;
@@ -1603,7 +1587,12 @@
 #endif
 	struct nfsv3_diskless *nd;
 	struct thread *td;
+	int timeout;
+	int delay;
 
+	timeout = BOOTP_IFACE_WAIT_TIMEOUT * hz;
+	delay = hz / 10;
+
 	nd = &nfsv3_diskless;
 	td = curthread;
 
@@ -1614,18 +1603,27 @@
 		return;
 
 	gctx = malloc(sizeof(*gctx), M_TEMP, M_WAITOK | M_ZERO);
-	if (gctx == NULL)
-		panic("Failed to allocate bootp global context structure");
-
+	STAILQ_INIT(&gctx->interfaces);
 	gctx->xid = ~0xFFFF;
 	gctx->starttime = time_second;
 
 	/*
+	 * If ROOTDEVNAME is defined or vfs.root.mountfrom is set then we have
+	 * root-path overrides that can potentially let us boot even if we don't
+	 * get a root path from the server, so we can treat that as a non-error.
+	 */
+#ifdef ROOTDEVNAME
+	gctx->any_root_overrides = 1;
+#else
+	gctx->any_root_overrides = testenv("vfs.root.mountfrom");
+#endif
+
+	/*
 	 * Find a network interface.
 	 */
 	CURVNET_SET(TD_TO_VNET(td));
 #ifdef BOOTP_WIRED_TO
-	printf("bootpc_init: wired to interface '%s'\n",
+	printf("%s: wired to interface '%s'\n", __func__, 
 	       __XSTRING(BOOTP_WIRED_TO));
 	allocifctx(gctx);
 #else
@@ -1633,32 +1631,38 @@
 	 * Preallocate interface context storage, if another interface
 	 * attaches and wins the race, it won't be eligible for bootp.
 	 */
+	ifcnt = 0;
 	IFNET_RLOCK();
-	for (ifp = TAILQ_FIRST(&V_ifnet), ifcnt = 0;
-	     ifp != NULL;
-	     ifp = TAILQ_NEXT(ifp, if_link)) {
+	TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
 		if ((ifp->if_flags &
 		     (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_BROADCAST)) !=
 		    IFF_BROADCAST)
 			continue;
+		switch (ifp->if_alloctype) {
+			case IFT_ETHER:
+			case IFT_FDDI:
+			case IFT_ISO88025:
+				break;
+			default:
+				continue;
+		}
 		ifcnt++;
 	}
 	IFNET_RUNLOCK();
 	if (ifcnt == 0)
-		panic("bootpc_init: no eligible interfaces");
+		panic("%s: no eligible interfaces", __func__);
 	for (; ifcnt > 0; ifcnt--)
 		allocifctx(gctx);
 #endif
 
+retry:
+	ifctx = STAILQ_FIRST(&gctx->interfaces);
 	IFNET_RLOCK();
-	for (ifp = TAILQ_FIRST(&V_ifnet), ifctx = gctx->interfaces;
-	     ifp != NULL && ifctx != NULL;
-	     ifp = TAILQ_NEXT(ifp, if_link)) {
-		strlcpy(ifctx->ireq.ifr_name, ifp->if_xname,
-		    sizeof(ifctx->ireq.ifr_name));
+	TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
+		if (ifctx == NULL)
+			break;
 #ifdef BOOTP_WIRED_TO
-		if (strcmp(ifctx->ireq.ifr_name,
-			   __XSTRING(BOOTP_WIRED_TO)) != 0)
+		if (strcmp(ifp->if_xname, __XSTRING(BOOTP_WIRED_TO)) != 0)
 			continue;
 #else
 		if ((ifp->if_flags &
@@ -1665,67 +1669,89 @@
 		     (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_BROADCAST)) !=
 		    IFF_BROADCAST)
 			continue;
+		switch (ifp->if_alloctype) {
+			case IFT_ETHER:
+			case IFT_FDDI:
+			case IFT_ISO88025:
+				break;
+			default:
+				continue;
+		}
 #endif
+		strlcpy(ifctx->ireq.ifr_name, ifp->if_xname,
+		    sizeof(ifctx->ireq.ifr_name));
 		ifctx->ifp = ifp;
-		ifctx = ifctx->next;
+
+		/* Get HW address */
+		sdl = NULL;
+		TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
+			if (ifa->ifa_addr->sa_family == AF_LINK) {
+				sdl = (struct sockaddr_dl *)ifa->ifa_addr;
+				if (sdl->sdl_type == IFT_ETHER)
+					break;
+			}
+		if (sdl == NULL)
+			panic("bootpc: Unable to find HW address for %s",
+			    ifctx->ireq.ifr_name);
+		ifctx->sdl = sdl;
+
+		ifctx = STAILQ_NEXT(ifctx, next);
 	}
 	IFNET_RUNLOCK();
 	CURVNET_RESTORE();
 
-	if (gctx->interfaces == NULL || gctx->interfaces->ifp == NULL) {
+	if (STAILQ_EMPTY(&gctx->interfaces) ||
+	    STAILQ_FIRST(&gctx->interfaces)->ifp == NULL) {
+		if (timeout > 0) {
+			pause("bootpc", delay);
+			timeout -= delay;
+			goto retry;
+		}
 #ifdef BOOTP_WIRED_TO
-		panic("bootpc_init: Could not find interface specified "
+		panic("%s: Could not find interface specified "
 		      "by BOOTP_WIRED_TO: "
-		      __XSTRING(BOOTP_WIRED_TO));
+		      __XSTRING(BOOTP_WIRED_TO), __func__);
 #else
-		panic("bootpc_init: no suitable interface");
+		panic("%s: no suitable interface", __func__);
 #endif
 	}
 
-	for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next)
-		bootpc_fakeup_interface(ifctx, gctx, td);
+	error = socreate(AF_INET, &bootp_so, SOCK_DGRAM, 0, td->td_ucred, td);
+	if (error != 0)
+		panic("%s: socreate, error=%d", __func__, error);
 
-	for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next)
-		bootpc_compose_query(ifctx, gctx, td);
+	STAILQ_FOREACH(ifctx, &gctx->interfaces, next)
+		bootpc_fakeup_interface(ifctx, td);
 
+	STAILQ_FOREACH(ifctx, &gctx->interfaces, next)
+		bootpc_compose_query(ifctx, td);
+
 	error = bootpc_call(gctx, td);
-
 	if (error != 0) {
-#ifdef BOOTP_NFSROOT
-		panic("BOOTP call failed");
-#else
 		printf("BOOTP call failed\n");
-#endif
 	}
 
-	rootdevnames[0] = "nfs:";
-#ifdef NFSCLIENT
-	rootdevnames[1] = "oldnfs:";
-#endif
 	mountopts(&nd->root_args, NULL);
 
-	for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next)
+	STAILQ_FOREACH(ifctx, &gctx->interfaces, next)
 		if (bootpc_ifctx_isresolved(ifctx) != 0)
 			bootpc_decode_reply(nd, ifctx, gctx);
 
 #ifdef BOOTP_NFSROOT
-	if (gctx->gotrootpath == 0)
+	if (gctx->gotrootpath == 0 && gctx->any_root_overrides == 0)
 		panic("bootpc: No root path offered");
 #endif
 
-	for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next) {
+	STAILQ_FOREACH(ifctx, &gctx->interfaces, next)
 		bootpc_adjust_interface(ifctx, gctx, td);
 
-		soclose(ifctx->so);
-	}
+	soclose(bootp_so);
 
-	for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next)
+	STAILQ_FOREACH(ifctx, &gctx->interfaces, next)
 		if (ifctx->gotrootpath != 0)
 			break;
 	if (ifctx == NULL) {
-		for (ifctx = gctx->interfaces;
-		     ifctx != NULL;
-		     ifctx = ifctx->next)
+		STAILQ_FOREACH(ifctx, &gctx->interfaces, next)
 			if (bootpc_ifctx_isresolved(ifctx) != 0)
 				break;
 	}
@@ -1736,12 +1762,21 @@
 
 		setenv("boot.netif.name", ifctx->ifp->if_xname);
 
+		bootpc_add_default_route(ifctx);
 		error = md_mount(&nd->root_saddr, nd->root_hostnam,
 				 nd->root_fh, &nd->root_fhsize,
 				 &nd->root_args, td);
-		if (error != 0)
-			panic("nfs_boot: mountd root, error=%d", error);
-
+		bootpc_remove_default_route(ifctx);
+		if (error != 0) {
+			if (gctx->any_root_overrides == 0)
+				panic("nfs_boot: mount root, error=%d", error);
+			else
+				goto out;
+		}
+		rootdevnames[0] = "nfs:";
+#ifdef NFSCLIENT
+		rootdevnames[1] = "oldnfs:";
+#endif
 		nfs_diskless_valid = 3;
 	}
 
@@ -1752,10 +1787,11 @@
 		ifctx->myaddr.sin_addr.s_addr |
 		~ ifctx->netmask.sin_addr.s_addr;
 	bcopy(&ifctx->netmask, &nd->myif.ifra_mask, sizeof(ifctx->netmask));
+	bcopy(&ifctx->gw, &nd->mygateway, sizeof(ifctx->gw));
 
 out:
-	for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = nctx) {
-		nctx = ifctx->next;
+	while((ifctx = STAILQ_FIRST(&gctx->interfaces)) != NULL) {
+		STAILQ_REMOVE_HEAD(&gctx->interfaces, next);
 		free(ifctx, M_TEMP);
 	}
 	free(gctx, M_TEMP);

Modified: trunk/sys/nfs/krpc.h
===================================================================
--- trunk/sys/nfs/krpc.h	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfs/krpc.h	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,5 +1,6 @@
+/* $MidnightBSD$ */
 /*	$NetBSD: krpc.h,v 1.4 1995/12/19 23:07:11 cgd Exp $	*/
-/* $MidnightBSD$	*/
+/* $FreeBSD: stable/10/sys/nfs/krpc.h 221032 2011-04-25 22:22:51Z rmacklem $	*/
 
 #include <sys/cdefs.h>
 

Modified: trunk/sys/nfs/krpc_subr.c
===================================================================
--- trunk/sys/nfs/krpc_subr.c	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfs/krpc_subr.c	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	$NetBSD: krpc_subr.c,v 1.12.4.1 1996/06/07 00:52:26 cgd Exp $	*/
 
 /*-
@@ -43,7 +44,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/nfs/krpc_subr.c 248207 2013-03-12 13:42:47Z glebius $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -154,7 +155,7 @@
 		return 0;
 	}
 
-	m = m_get(M_WAIT, MT_DATA);
+	m = m_get(M_WAITOK, MT_DATA);
 	sdata = mtod(m, struct sdata *);
 	m->m_len = sizeof(*sdata);
 
@@ -275,7 +276,7 @@
 	/*
 	 * Prepend RPC message header.
 	 */
-	mhead = m_gethdr(M_WAIT, MT_DATA);
+	mhead = m_gethdr(M_WAITOK, MT_DATA);
 	mhead->m_next = *data;
 	call = mtod(mhead, struct krpc_call *);
 	mhead->m_len = sizeof(*call);
@@ -309,7 +310,7 @@
 	timo = 0;
 	for (;;) {
 		/* Send RPC request (or re-send). */
-		m = m_copym(mhead, 0, M_COPYALL, M_WAIT);
+		m = m_copym(mhead, 0, M_COPYALL, M_WAITOK);
 		error = sosend(so, (struct sockaddr *)sa, NULL, m,
 			       NULL, 0, td);
 		if (error) {
@@ -459,9 +460,7 @@
 	if (mlen > MCLBYTES)		/* If too big, we just can't do it. */
 		return (NULL);
 
-	m = m_get(M_WAIT, MT_DATA);
-	if (mlen > MLEN)
-		MCLGET(m, M_WAIT);
+	m = m_get2(mlen, M_WAITOK, MT_DATA, 0);
 	xs = mtod(m, struct xdr_string *);
 	m->m_len = mlen;
 	xs->len = txdr_unsigned(len);

Modified: trunk/sys/nfs/nfs_common.c
===================================================================
--- trunk/sys/nfs/nfs_common.c	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfs/nfs_common.c	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1989, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -33,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/nfs/nfs_common.c 248318 2013-03-15 10:21:18Z glebius $");
 
 /*
  * These functions support the macros and help fiddle mbuf chains for
@@ -192,7 +193,7 @@
 	} else if (siz > MHLEN) {
 		panic("nfs S too big");
 	} else {
-		MGET(mp2, how, MT_DATA);
+		mp2 = m_get(how, MT_DATA);
 		if (mp2 == NULL)
 			return (NULL);
 		mp2->m_len = siz;
@@ -266,7 +267,7 @@
 	void *ret;
 
 	if (s > M_TRAILINGSPACE(*mb)) {
-		MGET(mb2, M_WAIT, MT_DATA);
+		mb2 = m_get(M_WAITOK, MT_DATA);
 		if (s > MLEN)
 			panic("build > MLEN");
 		(*mb)->m_next = mb2;
@@ -284,7 +285,7 @@
 nfsm_dissect_xx(int s, struct mbuf **md, caddr_t *dpos)
 {
 
-	return (nfsm_dissect_xx_sub(s, md, dpos, M_WAIT));
+	return (nfsm_dissect_xx_sub(s, md, dpos, M_WAITOK));
 }
 
 void *
@@ -291,7 +292,7 @@
 nfsm_dissect_xx_nonblock(int s, struct mbuf **md, caddr_t *dpos)
 {
 
-	return (nfsm_dissect_xx_sub(s, md, dpos, M_DONTWAIT));
+	return (nfsm_dissect_xx_sub(s, md, dpos, M_NOWAIT));
 }
 
 static void *

Modified: trunk/sys/nfs/nfs_common.h
===================================================================
--- trunk/sys/nfs/nfs_common.h	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfs/nfs_common.h	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1989, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -30,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)nfsm_subs.h	8.2 (Berkeley) 3/30/95
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/nfs/nfs_common.h 245568 2013-01-17 19:03:24Z jhb $
  */
 
 #ifndef _NFS_NFS_COMMON_H_

Modified: trunk/sys/nfs/nfs_diskless.c
===================================================================
--- trunk/sys/nfs/nfs_diskless.c	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfs/nfs_diskless.c	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
  * All rights reserved.
@@ -33,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/nfs/nfs_diskless.c 221436 2011-05-04 13:27:45Z ru $");
 
 #include "opt_bootp.h"
 

Modified: trunk/sys/nfs/nfs_fha.c
===================================================================
--- trunk/sys/nfs/nfs_fha.c	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfs/nfs_fha.c	2018-05-25 13:03:43 UTC (rev 9922)
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/nfs/nfs_fha.c 322138 2017-08-07 07:40:00Z mav $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -52,60 +52,47 @@
 void
 fha_init(struct fha_params *softc)
 {
-	char tmpstr[128];
+	int i;
 
-	/*
-	 * A small hash table to map filehandles to fha_hash_entry
-	 * structures.
-	 */
-	softc->g_fha.hashtable = hashinit(256, M_NFS_FHA,
-	    &softc->g_fha.hashmask);
+	for (i = 0; i < FHA_HASH_SIZE; i++)
+		mtx_init(&softc->fha_hash[i].mtx, "fhalock", NULL, MTX_DEF);
 
 	/*
 	 * Set the default tuning parameters.
 	 */
 	softc->ctls.enable = FHA_DEF_ENABLE;
+	softc->ctls.read = FHA_DEF_READ;
+	softc->ctls.write = FHA_DEF_WRITE;
 	softc->ctls.bin_shift = FHA_DEF_BIN_SHIFT;
 	softc->ctls.max_nfsds_per_fh = FHA_DEF_MAX_NFSDS_PER_FH;
 	softc->ctls.max_reqs_per_nfsd = FHA_DEF_MAX_REQS_PER_NFSD;
 
 	/*
-	 * Allow the user to override the defaults at boot time with
-	 * tunables.
+	 * Add sysctls so the user can change the tuning parameters.
 	 */
-	snprintf(tmpstr, sizeof(tmpstr), "vfs.%s.fha.enable",
-	    softc->server_name);
-	TUNABLE_INT_FETCH(tmpstr, &softc->ctls.enable);
-	snprintf(tmpstr, sizeof(tmpstr), "vfs.%s.fha.bin_shift",
-	    softc->server_name);
-	TUNABLE_INT_FETCH(tmpstr, &softc->ctls.bin_shift);
-	snprintf(tmpstr, sizeof(tmpstr), "vfs.%s.fha.max_nfsds_per_fh",
-	    softc->server_name);
-	TUNABLE_INT_FETCH(tmpstr, &softc->ctls.max_nfsds_per_fh);
-	snprintf(tmpstr, sizeof(tmpstr), "vfs.%s.fha.max_reqs_per_nfsd",
-	    softc->server_name);
-	TUNABLE_INT_FETCH(tmpstr, &softc->ctls.max_reqs_per_nfsd);
-
-	/*
-	 * Add sysctls so the user can change the tuning parameters at
-	 * runtime.
-	 */
 	SYSCTL_ADD_UINT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
-	    OID_AUTO, "enable", CTLFLAG_RW,
+	    OID_AUTO, "enable", CTLFLAG_RWTUN,
 	    &softc->ctls.enable, 0, "Enable NFS File Handle Affinity (FHA)");
 
 	SYSCTL_ADD_UINT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
-	    OID_AUTO, "bin_shift", CTLFLAG_RW,
-	    &softc->ctls.bin_shift, 0, "For FHA reads, no two requests will "
-	    "contend if they're 2^(bin_shift) bytes apart");
+	    OID_AUTO, "read", CTLFLAG_RWTUN,
+	    &softc->ctls.read, 0, "Enable NFS FHA read locality");
 
 	SYSCTL_ADD_UINT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
-	    OID_AUTO, "max_nfsds_per_fh", CTLFLAG_RW,
+	    OID_AUTO, "write", CTLFLAG_RWTUN,
+	    &softc->ctls.write, 0, "Enable NFS FHA write locality");
+
+	SYSCTL_ADD_UINT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
+	    OID_AUTO, "bin_shift", CTLFLAG_RWTUN,
+	    &softc->ctls.bin_shift, 0, "Maximum locality distance 2^(bin_shift) bytes");
+
+	SYSCTL_ADD_UINT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
+	    OID_AUTO, "max_nfsds_per_fh", CTLFLAG_RWTUN,
 	    &softc->ctls.max_nfsds_per_fh, 0, "Maximum nfsd threads that "
 	    "should be working on requests for the same file handle");
 
 	SYSCTL_ADD_UINT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
-	    OID_AUTO, "max_reqs_per_nfsd", CTLFLAG_RW,
+	    OID_AUTO, "max_reqs_per_nfsd", CTLFLAG_RWTUN,
 	    &softc->ctls.max_reqs_per_nfsd, 0, "Maximum requests that "
 	    "single nfsd thread should be working on at any time");
 
@@ -118,8 +105,11 @@
 void
 fha_uninit(struct fha_params *softc)
 {
+	int i;
+
 	sysctl_ctx_free(&softc->sysctl_ctx);
-	hashdestroy(softc->g_fha.hashtable, M_NFS_FHA, softc->g_fha.hashmask);
+	for (i = 0; i < FHA_HASH_SIZE; i++)
+		mtx_destroy(&softc->fha_hash[i].mtx);
 }
 
 /*
@@ -131,7 +121,6 @@
     struct fha_callbacks *cb)
 {
 	struct mbuf *md;
-	fhandle_t fh;
 	caddr_t dpos;
 	static u_int64_t random_fh = 0;
 	int error;
@@ -146,6 +135,7 @@
 	i->fh = ++random_fh;
 	i->offset = 0;
 	i->locktype = LK_EXCLUSIVE;
+	i->read = i->write = 0;
 
 	/*
 	 * Extract the procnum and convert to v3 form if necessary,
@@ -171,6 +161,9 @@
 	if (cb->no_offset(procnum))
 		goto out;
 
+	i->read = cb->is_read(procnum);
+	i->write = cb->is_write(procnum);
+
 	error = cb->realign(&req->rq_args, M_NOWAIT);
 	if (error)
 		goto out;
@@ -178,14 +171,12 @@
 	dpos = mtod(md, caddr_t);
 
 	/* Grab the filehandle. */
-	error = cb->get_fh(&fh, v3, &md, &dpos);
+	error = cb->get_fh(&i->fh, v3, &md, &dpos);
 	if (error)
 		goto out;
 
-	bcopy(fh.fh_fid.fid_data, &i->fh, sizeof(i->fh));
-
 	/* Content ourselves with zero offset for all but reads. */
-	if (cb->is_read(procnum) || cb->is_write(procnum))
+	if (i->read || i->write)
 		cb->get_offset(&md, &dpos, v3, i);
 
 out:
@@ -211,8 +202,13 @@
 fha_hash_entry_destroy(struct fha_hash_entry *e)
 {
 
-	if (e->num_rw + e->num_exclusive)
-		panic("nonempty fhe");
+	mtx_assert(e->mtx, MA_OWNED);
+	KASSERT(e->num_rw == 0,
+	    ("%d reqs on destroyed fhe %p", e->num_rw, e));
+	KASSERT(e->num_exclusive == 0,
+	    ("%d exclusive reqs on destroyed fhe %p", e->num_exclusive, e));
+	KASSERT(e->num_threads == 0,
+	    ("%d threads on destroyed fhe %p", e->num_threads, e));
 	free(e, M_NFS_FHA);
 }
 
@@ -220,6 +216,7 @@
 fha_hash_entry_remove(struct fha_hash_entry *e)
 {
 
+	mtx_assert(e->mtx, MA_OWNED);
 	LIST_REMOVE(e, link);
 	fha_hash_entry_destroy(e);
 }
@@ -228,36 +225,22 @@
 fha_hash_entry_lookup(struct fha_params *softc, u_int64_t fh)
 {
 	SVCPOOL *pool;
+	struct fha_hash_slot *fhs;
+	struct fha_hash_entry *fhe, *new_fhe;
 
 	pool = *softc->pool;
-
-	struct fha_hash_entry *fhe, *new_fhe;
-
-	LIST_FOREACH(fhe, &softc->g_fha.hashtable[fh % softc->g_fha.hashmask],
-	    link)
+	fhs = &softc->fha_hash[fh % FHA_HASH_SIZE];
+	new_fhe = fha_hash_entry_new(fh);
+	new_fhe->mtx = &fhs->mtx;
+	mtx_lock(&fhs->mtx);
+	LIST_FOREACH(fhe, &fhs->list, link)
 		if (fhe->fh == fh)
 			break;
-
 	if (!fhe) {
-		/* Allocate a new entry. */
-		mtx_unlock(&pool->sp_lock);
-		new_fhe = fha_hash_entry_new(fh);
-		mtx_lock(&pool->sp_lock);
-
-		/* Double-check to make sure we still need the new entry. */
-		LIST_FOREACH(fhe,
-		    &softc->g_fha.hashtable[fh % softc->g_fha.hashmask], link)
-			if (fhe->fh == fh)
-				break;
-		if (!fhe) {
-			fhe = new_fhe;
-			LIST_INSERT_HEAD(
-			    &softc->g_fha.hashtable[fh % softc->g_fha.hashmask],
-			    fhe, link);
-		} else
-			fha_hash_entry_destroy(new_fhe);
-	}
-
+		fhe = new_fhe;
+		LIST_INSERT_HEAD(&fhs->list, fhe, link);
+	} else
+		fha_hash_entry_destroy(new_fhe);
 	return (fhe);
 }
 
@@ -265,6 +248,8 @@
 fha_hash_entry_add_thread(struct fha_hash_entry *fhe, SVCTHREAD *thread)
 {
 
+	mtx_assert(fhe->mtx, MA_OWNED);
+	thread->st_p2 = 0;
 	LIST_INSERT_HEAD(&fhe->threads, thread, st_alink);
 	fhe->num_threads++;
 }
@@ -273,6 +258,9 @@
 fha_hash_entry_remove_thread(struct fha_hash_entry *fhe, SVCTHREAD *thread)
 {
 
+	mtx_assert(fhe->mtx, MA_OWNED);
+	KASSERT(thread->st_p2 == 0,
+	    ("%d reqs on removed thread %p", thread->st_p2, thread));
 	LIST_REMOVE(thread, st_alink);
 	fhe->num_threads--;
 }
@@ -284,6 +272,7 @@
 fha_hash_entry_add_op(struct fha_hash_entry *fhe, int locktype, int count)
 {
 
+	mtx_assert(fhe->mtx, MA_OWNED);
 	if (LK_EXCLUSIVE == locktype)
 		fhe->num_exclusive += count;
 	else
@@ -290,29 +279,12 @@
 		fhe->num_rw += count;
 }
 
-static SVCTHREAD *
-get_idle_thread(SVCPOOL *pool)
-{
-	SVCTHREAD *st;
-
-	LIST_FOREACH(st, &pool->sp_idlethreads, st_ilink) {
-		if (st->st_xprt == NULL && STAILQ_EMPTY(&st->st_reqs))
-			return (st);
-	}
-	return (NULL);
-}
-
-
 /*
  * Get the service thread currently associated with the fhe that is
  * appropriate to handle this operation.
  */
-SVCTHREAD *
+static SVCTHREAD *
 fha_hash_entry_choose_thread(struct fha_params *softc,
-    struct fha_hash_entry *fhe, struct fha_info *i, SVCTHREAD *this_thread);
-
-SVCTHREAD *
-fha_hash_entry_choose_thread(struct fha_params *softc,
     struct fha_hash_entry *fhe, struct fha_info *i, SVCTHREAD *this_thread)
 {
 	SVCTHREAD *thread, *min_thread = NULL;
@@ -323,7 +295,7 @@
 	pool = *softc->pool;
 
 	LIST_FOREACH(thread, &fhe->threads, st_alink) {
-		req_count = thread->st_reqcount;
+		req_count = thread->st_p2;
 
 		/* If there are any writes in progress, use the first thread. */
 		if (fhe->num_exclusive) {
@@ -334,12 +306,17 @@
 			return (thread);
 		}
 
+		/* Check whether we should consider locality. */
+		if ((i->read && !softc->ctls.read) ||
+		    (i->write && !softc->ctls.write))
+			goto noloc;
+
 		/*
-		 * Check for read locality, making sure that we won't
+		 * Check for locality, making sure that we won't
 		 * exceed our per-thread load limit in the process.
 		 */
 		offset1 = i->offset;
-		offset2 = STAILQ_FIRST(&thread->st_reqs)->rq_p3;
+		offset2 = thread->st_p3;
 
 		if (((offset1 >= offset2)
 		  && ((offset1 - offset2) < (1 << softc->ctls.bin_shift)))
@@ -355,6 +332,7 @@
 			}
 		}
 
+noloc:
 		/*
 		 * We don't have a locality match, so skip this thread,
 		 * but keep track of the most attractive thread in case
@@ -377,28 +355,11 @@
 	 */
 	if ((softc->ctls.max_nfsds_per_fh == 0) ||
 	    (fhe->num_threads < softc->ctls.max_nfsds_per_fh)) {
-		/*
-		 * We can add a new thread, so try for an idle thread
-		 * first, and fall back to this_thread if none are idle.
-		 */
-		if (STAILQ_EMPTY(&this_thread->st_reqs)) {
-			thread = this_thread;
+		thread = this_thread;
 #if 0
-			ITRACE_CURPROC(ITRACE_NFS, ITRACE_INFO,
-			    "fha: %p(%d)t", thread, thread->st_reqcount);
+		ITRACE_CURPROC(ITRACE_NFS, ITRACE_INFO,
+		    "fha: %p(%d)t", thread, thread->st_p2);
 #endif
-		} else if ((thread = get_idle_thread(pool))) {
-#if 0
-			ITRACE_CURPROC(ITRACE_NFS, ITRACE_INFO,
-			    "fha: %p(%d)i", thread, thread->st_reqcount);
-#endif
-		} else {
-			thread = this_thread;
-#if 0
-			ITRACE_CURPROC(ITRACE_NFS, ITRACE_INFO,
-			    "fha: %p(%d)b", thread, thread->st_reqcount);
-#endif
-		}
 		fha_hash_entry_add_thread(fhe, thread);
 	} else {
 		/*
@@ -419,7 +380,6 @@
 fha_assign(SVCTHREAD *this_thread, struct svc_req *req,
     struct fha_params *softc)
 {
-	SVCPOOL *pool;
 	SVCTHREAD *thread;
 	struct fha_info i;
 	struct fha_hash_entry *fhe;
@@ -429,18 +389,17 @@
 
 	/* Check to see whether we're enabled. */
 	if (softc->ctls.enable == 0)
-		return (this_thread);
+		goto thist;
 
 	/*
 	 * Only do placement if this is an NFS request.
 	 */
 	if (req->rq_prog != NFS_PROG)
-		return (this_thread);
+		goto thist;
 
 	if (req->rq_vers != 2 && req->rq_vers != 3)
-		return (this_thread);
+		goto thist;
 
-	pool = req->rq_xprt->xp_pool;
 	fha_extract_info(req, &i, cb);
 
 	/*
@@ -459,8 +418,21 @@
 	thread = fha_hash_entry_choose_thread(softc, fhe, &i, this_thread);
 	KASSERT(thread, ("fha_assign: NULL thread!"));
 	fha_hash_entry_add_op(fhe, i.locktype, 1);
+	thread->st_p2++;
+	thread->st_p3 = i.offset;
 
+	/*
+	 * Grab the pool lock here to not let chosen thread go away before
+	 * the new request inserted to its queue while we drop fhe lock.
+	 */
+	mtx_lock(&thread->st_lock);
+	mtx_unlock(fhe->mtx);
+
 	return (thread);
+thist:
+	req->rq_p1 = NULL;
+	mtx_lock(&this_thread->st_lock);
+	return (this_thread);
 }
 
 /*
@@ -471,6 +443,7 @@
 fha_nd_complete(SVCTHREAD *thread, struct svc_req *req)
 {
 	struct fha_hash_entry *fhe = req->rq_p1;
+	struct mtx *mtx;
 
 	/*
 	 * This may be called for reqs that didn't go through
@@ -479,26 +452,31 @@
 	if (!fhe)
 		return;
 
+	mtx = fhe->mtx;
+	mtx_lock(mtx);
 	fha_hash_entry_add_op(fhe, req->rq_p2, -1);
-
-	if (thread->st_reqcount == 0) {
+	thread->st_p2--;
+	KASSERT(thread->st_p2 >= 0, ("Negative request count %d on %p",
+	    thread->st_p2, thread));
+	if (thread->st_p2 == 0) {
 		fha_hash_entry_remove_thread(fhe, thread);
 		if (0 == fhe->num_rw + fhe->num_exclusive)
 			fha_hash_entry_remove(fhe);
 	}
+	mtx_unlock(mtx);
 }
 
 int
 fhe_stats_sysctl(SYSCTL_HANDLER_ARGS, struct fha_params *softc)
 {
-	int error, count, i;
+	int error, i;
 	struct sbuf sb;
 	struct fha_hash_entry *fhe;
-	bool_t first = TRUE;
+	bool_t first, hfirst;
 	SVCTHREAD *thread;
 	SVCPOOL *pool;
 
-	sbuf_new(&sb, NULL, 4096, SBUF_FIXEDLEN);
+	sbuf_new(&sb, NULL, 65536, SBUF_FIXEDLEN);
 
 	pool = NULL;
 
@@ -508,47 +486,47 @@
 	}
 	pool = *softc->pool;
 
-	mtx_lock(&pool->sp_lock);
-	count = 0;
-	for (i = 0; i <= softc->g_fha.hashmask; i++)
-		if (!LIST_EMPTY(&softc->g_fha.hashtable[i]))
-			count++;
+	for (i = 0; i < FHA_HASH_SIZE; i++)
+		if (!LIST_EMPTY(&softc->fha_hash[i].list))
+			break;
 
-	if (count == 0) {
+	if (i == FHA_HASH_SIZE) {
 		sbuf_printf(&sb, "No file handle entries.\n");
 		goto out;
 	}
 
-	for (i = 0; i <= softc->g_fha.hashmask; i++) {
-		LIST_FOREACH(fhe, &softc->g_fha.hashtable[i], link) {
-			sbuf_printf(&sb, "%sfhe %p: {\n", first ? "" : ", ", fhe);
+	hfirst = TRUE;
+	for (; i < FHA_HASH_SIZE; i++) {
+		mtx_lock(&softc->fha_hash[i].mtx);
+		if (LIST_EMPTY(&softc->fha_hash[i].list)) {
+			mtx_unlock(&softc->fha_hash[i].mtx);
+			continue;
+		}
+		sbuf_printf(&sb, "%shash %d: {\n", hfirst ? "" : ", ", i);
+		first = TRUE;
+		LIST_FOREACH(fhe, &softc->fha_hash[i].list, link) {
+			sbuf_printf(&sb, "%sfhe %p: {\n", first ? "  " : ", ", fhe);
 
 			sbuf_printf(&sb, "    fh: %ju\n", (uintmax_t) fhe->fh);
-			sbuf_printf(&sb, "    num_rw: %d\n", fhe->num_rw);
-			sbuf_printf(&sb, "    num_exclusive: %d\n", fhe->num_exclusive);
+			sbuf_printf(&sb, "    num_rw/exclusive: %d/%d\n",
+			    fhe->num_rw, fhe->num_exclusive);
 			sbuf_printf(&sb, "    num_threads: %d\n", fhe->num_threads);
 
 			LIST_FOREACH(thread, &fhe->threads, st_alink) {
-				sbuf_printf(&sb, "    thread %p offset %ju "
-				    "(count %d)\n", thread,
-				    STAILQ_FIRST(&thread->st_reqs)->rq_p3,
-				    thread->st_reqcount);
+				sbuf_printf(&sb, "      thread %p offset %ju "
+				    "reqs %d\n", thread,
+				    thread->st_p3, thread->st_p2);
 			}
 
-			sbuf_printf(&sb, "}");
+			sbuf_printf(&sb, "  }");
 			first = FALSE;
-
-			/* Limit the output. */
-			if (++count > 128) {
-				sbuf_printf(&sb, "...");
-				break;
-			}
 		}
+		sbuf_printf(&sb, "\n}");
+		mtx_unlock(&softc->fha_hash[i].mtx);
+		hfirst = FALSE;
 	}
 
  out:
-	if (pool)
-		mtx_unlock(&pool->sp_lock);
 	sbuf_trim(&sb);
 	sbuf_finish(&sb);
 	error = sysctl_handle_string(oidp, sbuf_data(&sb), sbuf_len(&sb), req);

Modified: trunk/sys/nfs/nfs_fha.h
===================================================================
--- trunk/sys/nfs/nfs_fha.h	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfs/nfs_fha.h	2018-05-25 13:03:43 UTC (rev 9922)
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-/* $FreeBSD$ */
+/* $FreeBSD: stable/10/sys/nfs/nfs_fha.h 322138 2017-08-07 07:40:00Z mav $ */
 
 #ifndef	_NFS_FHA_H
 #define	_NFS_FHA_H 1
@@ -32,18 +32,18 @@
 
 /* Sysctl defaults. */
 #define FHA_DEF_ENABLE			1
+#define FHA_DEF_READ			1
+#define FHA_DEF_WRITE			1
 #define FHA_DEF_BIN_SHIFT		22 /* 4MB */
 #define FHA_DEF_MAX_NFSDS_PER_FH	8
 #define FHA_DEF_MAX_REQS_PER_NFSD	0  /* Unlimited */
 
-/* This is the global structure that represents the state of the fha system. */
-struct fha_global {
-	struct fha_hash_entry_list *hashtable;
-	u_long hashmask;
-};
+#define FHA_HASH_SIZE	251
 
 struct fha_ctls {
 	int	 enable;
+	int	 read;
+	int	 write;
 	uint32_t bin_shift;
 	uint32_t max_nfsds_per_fh;
 	uint32_t max_reqs_per_nfsd;
@@ -63,6 +63,7 @@
  * avoid contention between threads over single files.
  */
 struct fha_hash_entry {
+	struct mtx *mtx;
 	LIST_ENTRY(fha_hash_entry) link;
 	u_int64_t fh;
 	u_int32_t num_rw;
@@ -73,17 +74,24 @@
 
 LIST_HEAD(fha_hash_entry_list, fha_hash_entry);
 
+struct fha_hash_slot {
+	struct fha_hash_entry_list list;
+	struct mtx mtx;
+};
+
 /* A structure used for passing around data internally. */
 struct fha_info {
 	u_int64_t fh;
 	off_t offset;
 	int locktype;
+	int read;
+	int write;
 };
 
 struct fha_callbacks {
 	rpcproc_t (*get_procnum)(rpcproc_t procnum);
 	int (*realign)(struct mbuf **mb, int malloc_flags);
-	int (*get_fh)(fhandle_t *fh, int v3, struct mbuf **md, caddr_t *dpos);
+	int (*get_fh)(uint64_t *fh, int v3, struct mbuf **md, caddr_t *dpos);
 	int (*is_read)(rpcproc_t procnum);
 	int (*is_write)(rpcproc_t procnum);
 	int (*get_offset)(struct mbuf **md, caddr_t *dpos, int v3, struct
@@ -94,7 +102,7 @@
 };
 
 struct fha_params {
-	struct fha_global g_fha; 
+	struct fha_hash_slot fha_hash[FHA_HASH_SIZE];
 	struct sysctl_ctx_list sysctl_ctx;
 	struct sysctl_oid *sysctl_tree;
 	struct fha_ctls ctls;

Modified: trunk/sys/nfs/nfs_kdtrace.h
===================================================================
--- trunk/sys/nfs/nfs_kdtrace.h	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfs/nfs_kdtrace.h	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2009 Robert N. M. Watson
  * All rights reserved.
@@ -26,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/nfs/nfs_kdtrace.h 222813 2011-06-07 08:46:13Z attilio $
  */
 
 #ifndef _NFSCLIENT_NFS_KDTRACE_H_

Modified: trunk/sys/nfs/nfs_lock.c
===================================================================
--- trunk/sys/nfs/nfs_lock.c	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfs/nfs_lock.c	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1997 Berkeley Software Design, Inc. All rights reserved.
  *
@@ -29,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/nfs/nfs_lock.c 227293 2011-11-07 06:44:47Z ed $");
 
 #include <sys/param.h>
 #include <sys/systm.h>

Modified: trunk/sys/nfs/nfs_lock.h
===================================================================
--- trunk/sys/nfs/nfs_lock.h	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfs/nfs_lock.h	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1998 Berkeley Software Design, Inc. All rights reserved.
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +26,7 @@
  * SUCH DAMAGE.
  *
  *      from nfs_lock.h,v 2.2 1998/04/28 19:38:41 don Exp
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/nfs/nfs_lock.h 214048 2010-10-19 00:20:00Z rmacklem $
  */
 
 /*

Modified: trunk/sys/nfs/nfs_mountcommon.h
===================================================================
--- trunk/sys/nfs/nfs_mountcommon.h	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfs/nfs_mountcommon.h	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2009 Rick Macklem, University of Guelph
  * All rights reserved.
@@ -23,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/nfs/nfs_mountcommon.h 216931 2011-01-03 20:37:31Z rmacklem $
  */
 
 #ifndef _NFS_MOUNTCOMMON_H_

Modified: trunk/sys/nfs/nfs_nfssvc.c
===================================================================
--- trunk/sys/nfs/nfs_nfssvc.c	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfs/nfs_nfssvc.c	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1989, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -32,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/nfs/nfs_nfssvc.c 243782 2012-12-02 01:16:04Z rmacklem $");
 
 #include "opt_nfs.h"
 

Modified: trunk/sys/nfs/nfsdiskless.h
===================================================================
--- trunk/sys/nfs/nfsdiskless.h	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfs/nfsdiskless.h	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1991, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -30,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)nfsdiskless.h	8.2 (Berkeley) 3/30/95
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/nfs/nfsdiskless.h 221032 2011-04-25 22:22:51Z rmacklem $
  */
 
 #ifndef _NFSCLIENT_NFSDISKLESS_H_

Modified: trunk/sys/nfs/nfsproto.h
===================================================================
--- trunk/sys/nfs/nfsproto.h	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfs/nfsproto.h	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1989, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -30,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)nfsproto.h  8.2 (Berkeley) 3/30/95
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/nfs/nfsproto.h 164725 2006-11-28 19:33:28Z rees $
  */
 
 #ifndef _NFS_NFSPROTO_H_

Modified: trunk/sys/nfs/nfssvc.h
===================================================================
--- trunk/sys/nfs/nfssvc.h	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfs/nfssvc.h	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1989, 1993, 1995
  *	The Regents of the University of California.  All rights reserved.
@@ -29,7 +30,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/nfs/nfssvc.h 292223 2015-12-14 21:21:43Z rmacklem $
  */
 
 #ifndef _NFS_NFSSVC_H_
@@ -69,6 +70,7 @@
 #define	NFSSVC_SUSPENDNFSD	0x04000000
 #define	NFSSVC_RESUMENFSD	0x08000000
 #define	NFSSVC_DUMPMNTOPTS	0x10000000
+#define	NFSSVC_NEWSTRUCT	0x20000000
 
 /* Argument structure for NFSSVC_DUMPMNTOPTS. */
 struct nfscl_dumpmntopts {

Modified: trunk/sys/nfs/xdr_subs.h
===================================================================
--- trunk/sys/nfs/xdr_subs.h	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfs/xdr_subs.h	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1989, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -30,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)xdr_subs.h	8.3 (Berkeley) 3/30/95
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/nfs/xdr_subs.h 139823 2005-01-07 01:45:51Z imp $
  */
 
 

Modified: trunk/sys/nfsclient/nfs.h
===================================================================
--- trunk/sys/nfsclient/nfs.h	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfsclient/nfs.h	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1989, 1993, 1995
  *	The Regents of the University of California.  All rights reserved.
@@ -30,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)nfs.h	8.4 (Berkeley) 5/1/95
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/nfsclient/nfs.h 221986 2011-05-16 13:12:09Z rmacklem $
  */
 
 #ifndef _NFSCLIENT_NFS_H_

Modified: trunk/sys/nfsclient/nfs_bio.c
===================================================================
--- trunk/sys/nfsclient/nfs_bio.c	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfsclient/nfs_bio.c	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1989, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -33,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/nfsclient/nfs_bio.c 249623 2013-04-18 13:09:04Z rmacklem $");
 
 #include "opt_kdtrace.h"
 
@@ -45,6 +46,7 @@
 #include <sys/mbuf.h>
 #include <sys/mount.h>
 #include <sys/proc.h>
+#include <sys/rwlock.h>
 #include <sys/vmmeter.h>
 #include <sys/vnode.h>
 
@@ -128,7 +130,7 @@
 	 * allow the pager to zero-out the blanks.  Partially valid pages
 	 * can only occur at the file EOF.
 	 */
-	VM_OBJECT_LOCK(object);
+	VM_OBJECT_WLOCK(object);
 	if (pages[ap->a_reqpage]->valid != 0) {
 		for (i = 0; i < npages; ++i) {
 			if (i != ap->a_reqpage) {
@@ -137,10 +139,10 @@
 				vm_page_unlock(pages[i]);
 			}
 		}
-		VM_OBJECT_UNLOCK(object);
+		VM_OBJECT_WUNLOCK(object);
 		return (0);
 	}
-	VM_OBJECT_UNLOCK(object);
+	VM_OBJECT_WUNLOCK(object);
 
 	/*
 	 * We use only the kva address for the buffer, but this is extremely
@@ -170,7 +172,7 @@
 
 	if (error && (uio.uio_resid == count)) {
 		nfs_printf("nfs_getpages: error %d\n", error);
-		VM_OBJECT_LOCK(object);
+		VM_OBJECT_WLOCK(object);
 		for (i = 0; i < npages; ++i) {
 			if (i != ap->a_reqpage) {
 				vm_page_lock(pages[i]);
@@ -178,7 +180,7 @@
 				vm_page_unlock(pages[i]);
 			}
 		}
-		VM_OBJECT_UNLOCK(object);
+		VM_OBJECT_WUNLOCK(object);
 		return (VM_PAGER_ERROR);
 	}
 
@@ -189,7 +191,7 @@
 	 */
 
 	size = count - uio.uio_resid;
-	VM_OBJECT_LOCK(object);
+	VM_OBJECT_WLOCK(object);
 	for (i = 0, toff = 0; i < npages; i++, toff = nextoff) {
 		vm_page_t m;
 		nextoff = toff + PAGE_SIZE;
@@ -207,7 +209,7 @@
 			 * Read operation filled a partial page.
 			 */
 			m->valid = 0;
-			vm_page_set_valid(m, 0, size - toff);
+			vm_page_set_valid_range(m, 0, size - toff);
 			KASSERT(m->dirty == 0,
 			    ("nfs_getpages: page %p is dirty", m));
 		} else {
@@ -225,7 +227,7 @@
 		if (i != ap->a_reqpage)
 			vm_page_readahead_finish(m);
 	}
-	VM_OBJECT_UNLOCK(object);
+	VM_OBJECT_WUNLOCK(object);
 	return (0);
 }
 
@@ -474,7 +476,7 @@
 	    case VREG:
 		nfsstats.biocache_reads++;
 		lbn = uio->uio_offset / biosize;
-		on = uio->uio_offset & (biosize - 1);
+		on = uio->uio_offset - (lbn * biosize);
 
 		/*
 		 * Start the read ahead(s), as required.
@@ -1010,7 +1012,7 @@
 	do {
 		nfsstats.biocache_writes++;
 		lbn = uio->uio_offset / biosize;
-		on = uio->uio_offset & (biosize-1);
+		on = uio->uio_offset - (lbn * biosize);
 		n = MIN((unsigned)(biosize - on), uio->uio_resid);
 again:
 		/*
@@ -1241,7 +1243,7 @@
  		sigset_t oldset;
 
  		nfs_set_sigmask(td, &oldset);
-		bp = getblk(vp, bn, size, NFS_PCATCH, 0, 0);
+		bp = getblk(vp, bn, size, PCATCH, 0, 0);
  		nfs_restore_sigmask(td, &oldset);
 		while (bp == NULL) {
 			if (nfs_sigintr(nmp, td))
@@ -1274,7 +1276,7 @@
 	if ((nmp->nm_flag & NFSMNT_INT) == 0)
 		intrflg = 0;
 	if (intrflg) {
-		slpflag = NFS_PCATCH;
+		slpflag = PCATCH;
 		slptimeo = 2 * hz;
 	} else {
 		slpflag = 0;
@@ -1296,9 +1298,9 @@
 	 * Now, flush as required.
 	 */
 	if ((flags & V_SAVE) && (vp->v_bufobj.bo_object != NULL)) {
-		VM_OBJECT_LOCK(vp->v_bufobj.bo_object);
+		VM_OBJECT_WLOCK(vp->v_bufobj.bo_object);
 		vm_object_page_clean(vp->v_bufobj.bo_object, 0, 0, OBJPC_SYNC);
-		VM_OBJECT_UNLOCK(vp->v_bufobj.bo_object);
+		VM_OBJECT_WUNLOCK(vp->v_bufobj.bo_object);
 		/*
 		 * If the page clean was interrupted, fail the invalidation.
 		 * Not doing so, we run the risk of losing dirty pages in the 
@@ -1361,7 +1363,7 @@
 	}
 again:
 	if (nmp->nm_flag & NFSMNT_INT)
-		slpflag = NFS_PCATCH;
+		slpflag = PCATCH;
 	gotiod = FALSE;
 
 	/*
@@ -1426,7 +1428,7 @@
 					mtx_unlock(&nfs_iod_mtx);
 					return (error2);
 				}
-				if (slpflag == NFS_PCATCH) {
+				if (slpflag == PCATCH) {
 					slpflag = 0;
 					slptimeo = 2 * hz;
 				}
@@ -1786,9 +1788,9 @@
 		 * truncation point.  We may have a B_DELWRI and/or B_CACHE
 		 * buffer that now needs to be truncated.
 		 */
-		error = vtruncbuf(vp, cred, td, nsize, biosize);
+		error = vtruncbuf(vp, cred, nsize, biosize);
 		lbn = nsize / biosize;
-		bufsize = nsize & (biosize - 1);
+		bufsize = nsize - (lbn * biosize);
 		bp = nfs_getcacheblk(vp, lbn, bufsize, td);
  		if (!bp)
  			return EINTR;

Modified: trunk/sys/nfsclient/nfs_kdtrace.c
===================================================================
--- trunk/sys/nfsclient/nfs_kdtrace.c	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfsclient/nfs_kdtrace.c	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2009 Robert N. M. Watson
  * All rights reserved.
@@ -28,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/nfsclient/nfs_kdtrace.c 221542 2011-05-06 19:55:15Z rmacklem $");
 
 #include <sys/param.h>
 #include <sys/systm.h>

Modified: trunk/sys/nfsclient/nfs_krpc.c
===================================================================
--- trunk/sys/nfsclient/nfs_krpc.c	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfsclient/nfs_krpc.c	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1989, 1991, 1993, 1995
  *	The Regents of the University of California.  All rights reserved.
@@ -33,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/nfsclient/nfs_krpc.c 247116 2013-02-21 19:02:50Z jhb $");
 
 /*
  * Socket operations for use by nfs
@@ -572,7 +573,7 @@
 	 * These could cause pointer alignment problems, so copy them to
 	 * well aligned mbufs.
 	 */
-	error = nfs_realign(&mrep, M_DONTWAIT);
+	error = nfs_realign(&mrep, M_NOWAIT);
 	if (error == ENOMEM) {
 		m_freem(mrep);
 		AUTH_DESTROY(auth);

Modified: trunk/sys/nfsclient/nfs_nfsiod.c
===================================================================
--- trunk/sys/nfsclient/nfs_nfsiod.c	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfsclient/nfs_nfsiod.c	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1989, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -33,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/nfsclient/nfs_nfsiod.c 249630 2013-04-18 23:20:16Z rmacklem $");
 
 #include <sys/param.h>
 #include <sys/systm.h>

Modified: trunk/sys/nfsclient/nfs_node.c
===================================================================
--- trunk/sys/nfsclient/nfs_node.c	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfsclient/nfs_node.c	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1989, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -33,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/nfsclient/nfs_node.c 243311 2012-11-19 22:43:45Z attilio $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -128,12 +129,6 @@
 		*npp = VTONFS(nvp);
 		return (0);
 	}
-
-	/*
-	 * Allocate before getnewvnode since doing so afterward
-	 * might cause a bogus v_data pointer to get dereferenced
-	 * elsewhere if zalloc should block.
-	 */
 	np = uma_zalloc(nfsnode_zone, M_WAITOK | M_ZERO);
 
 	error = getnewvnode("nfs", mntp, &nfs_vnodeops, &nvp);

Modified: trunk/sys/nfsclient/nfs_subs.c
===================================================================
--- trunk/sys/nfsclient/nfs_subs.c	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfsclient/nfs_subs.c	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1989, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -33,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/nfsclient/nfs_subs.c 252673 2013-07-04 00:54:23Z rmacklem $");
 
 /*
  * These functions support the macros and help fiddle mbuf chains for
@@ -56,6 +57,7 @@
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/malloc.h>
+#include <sys/rwlock.h>
 #include <sys/sysent.h>
 #include <sys/syscall.h>
 #include <sys/sysproto.h>
@@ -172,23 +174,6 @@
 }
 
 /*
- * Create the header for an rpc request packet
- * The hsiz is the size of the rest of the nfs request header.
- * (just used to decide if a cluster is a good idea)
- */
-struct mbuf *
-nfsm_reqhead(struct vnode *vp, u_long procid, int hsiz)
-{
-	struct mbuf *mb;
-
-	MGET(mb, M_WAIT, MT_DATA);
-	if (hsiz >= MINCLSIZE)
-		MCLGET(mb, M_WAIT);
-	mb->m_len = 0;
-	return (mb);
-}
-
-/*
  * copies a uio scatter/gather list to an mbuf chain.
  * NOTE: can ony handle iovcnt == 1
  */
@@ -218,10 +203,10 @@
 		while (left > 0) {
 			mlen = M_TRAILINGSPACE(mp);
 			if (mlen == 0) {
-				MGET(mp, M_WAIT, MT_DATA);
 				if (clflg)
-					MCLGET(mp, M_WAIT);
-				mp->m_len = 0;
+					mp = m_getcl(M_WAITOK, MT_DATA, 0);
+				else
+					mp = m_get(M_WAITOK, MT_DATA);
 				mp2->m_next = mp;
 				mp2 = mp;
 				mlen = M_TRAILINGSPACE(mp);
@@ -251,8 +236,7 @@
 	}
 	if (rem > 0) {
 		if (rem > M_TRAILINGSPACE(mp)) {
-			MGET(mp, M_WAIT, MT_DATA);
-			mp->m_len = 0;
+			mp = m_get(M_WAITOK, MT_DATA);
 			mp2->m_next = mp;
 		}
 		cp = mtod(mp, caddr_t)+mp->m_len;
@@ -296,10 +280,13 @@
 	}
 	/* Loop around adding mbufs */
 	while (siz > 0) {
-		MGET(m1, M_WAIT, MT_DATA);
-		if (siz > MLEN)
-			MCLGET(m1, M_WAIT);
-		m1->m_len = NFSMSIZ(m1);
+		if (siz > MLEN) {
+			m1 = m_getcl(M_WAITOK, MT_DATA, 0);
+			m1->m_len = MCLBYTES;
+		} else {
+			m1 = m_get(M_WAITOK, MT_DATA);
+			m1->m_len = MLEN;
+		}
 		m2->m_next = m1;
 		m2 = m1;
 		tl = mtod(m1, u_int32_t *);
@@ -478,10 +465,12 @@
 	struct timespec mtime, mtime_save;
 	int v3 = NFS_ISV3(vp);
 	int error = 0;
+	u_quad_t nsize;
+	int setnsize;
 
 	md = *mdp;
 	t1 = (mtod(md, caddr_t) + md->m_len) - *dposp;
-	cp2 = nfsm_disct(mdp, dposp, NFSX_FATTR(v3), t1, M_WAIT);
+	cp2 = nfsm_disct(mdp, dposp, NFSX_FATTR(v3), t1, M_WAITOK);
 	if (cp2 == NULL) {
 		error = EBADRPC;
 		goto out;
@@ -580,6 +569,8 @@
 		vap->va_filerev = 0;
 	}
 	np->n_attrstamp = time_second;
+	setnsize = 0;
+	nsize = 0;
 	if (vap->va_size != np->n_size) {
 		if (vap->va_type == VREG) {
 			if (dontshrink && vap->va_size < np->n_size) {
@@ -591,6 +582,7 @@
 				vap->va_size = np->n_size;
 				np->n_attrstamp = 0;
 				KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
+				vnode_pager_setsize(vp, np->n_size);
 			} else if (np->n_flag & NMODIFIED) {
 				/*
 				 * We've modified the file: Use the larger
@@ -602,11 +594,22 @@
 					np->n_size = vap->va_size;
 					np->n_flag |= NSIZECHANGED;
 				}
+				vnode_pager_setsize(vp, np->n_size);
+			} else if (vap->va_size < np->n_size) {
+				/*
+				 * When shrinking the size, the call to
+				 * vnode_pager_setsize() cannot be done
+				 * with the mutex held, so delay it until
+				 * after the mtx_unlock call.
+				 */
+				nsize = np->n_size = vap->va_size;
+				np->n_flag |= NSIZECHANGED;
+				setnsize = 1;
 			} else {
 				np->n_size = vap->va_size;
 				np->n_flag |= NSIZECHANGED;
+				vnode_pager_setsize(vp, np->n_size);
 			}
-			vnode_pager_setsize(vp, np->n_size);
 		} else {
 			np->n_size = vap->va_size;
 		}
@@ -643,6 +646,8 @@
 		KDTRACE_NFS_ATTRCACHE_LOAD_DONE(vp, &np->n_vattr, 0);
 #endif
 	mtx_unlock(&np->n_mtx);
+	if (setnsize)
+		vnode_pager_setsize(vp, nsize);
 out:
 #ifdef KDTRACE_HOOKS
 	if (error)

Modified: trunk/sys/nfsclient/nfs_vfsops.c
===================================================================
--- trunk/sys/nfsclient/nfs_vfsops.c	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfsclient/nfs_vfsops.c	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1989, 1993, 1995
  *	The Regents of the University of California.  All rights reserved.
@@ -33,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/nfsclient/nfs_vfsops.c 249630 2013-04-18 23:20:16Z rmacklem $");
 
 
 #include "opt_bootp.h"
@@ -298,7 +299,7 @@
 	} else
 		mtx_unlock(&nmp->nm_mtx);
 	nfsstats.rpccnt[NFSPROC_FSSTAT]++;
-	mreq = nfsm_reqhead(vp, NFSPROC_FSSTAT, NFSX_FH(v3));
+	mreq = m_get2(NFSX_FH(v3), M_WAITOK, MT_DATA, 0);
 	mb = mreq;
 	bpos = mtod(mb, caddr_t);
 	nfsm_fhtom(vp, v3);
@@ -356,7 +357,7 @@
 	u_int64_t maxfsize;
 	
 	nfsstats.rpccnt[NFSPROC_FSINFO]++;
-	mreq = nfsm_reqhead(vp, NFSPROC_FSINFO, NFSX_FH(1));
+	mreq = m_get2(NFSX_FH(1), M_WAITOK, MT_DATA, 0);
 	mb = mreq;
 	bpos = mtod(mb, caddr_t);
 	nfsm_fhtom(vp, 1);
@@ -1193,7 +1194,7 @@
 out:
 	if (!error) {
 		MNT_ILOCK(mp);
-		mp->mnt_kern_flag |= (MNTK_MPSAFE|MNTK_LOOKUP_SHARED);
+		mp->mnt_kern_flag |= MNTK_LOOKUP_SHARED;
 		MNT_IUNLOCK(mp);
 	}
 	return (error);

Modified: trunk/sys/nfsclient/nfs_vnops.c
===================================================================
--- trunk/sys/nfsclient/nfs_vnops.c	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfsclient/nfs_vnops.c	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1989, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -33,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/nfsclient/nfs_vnops.c 276500 2015-01-01 10:44:20Z kib $");
 
 /*
  * vnode op calls for Sun NFS version 2 and 3
@@ -67,8 +68,6 @@
 #include <vm/vm_extern.h>
 #include <vm/vm_object.h>
 
-#include <fs/fifofs/fifo.h>
-
 #include <nfs/nfsproto.h>
 #include <nfsclient/nfs.h>
 #include <nfsclient/nfsnode.h>
@@ -296,7 +295,7 @@
 	struct nfsnode *np = VTONFS(vp);
 
 	nfsstats.rpccnt[NFSPROC_ACCESS]++;
-	mreq = nfsm_reqhead(vp, NFSPROC_ACCESS, NFSX_FH(v3) + NFSX_UNSIGNED);
+	mreq = m_get2(NFSX_FH(v3) + NFSX_UNSIGNED, M_WAITOK, MT_DATA, 0);
 	mb = mreq;
 	bpos = mtod(mb, caddr_t);
 	nfsm_fhtom(vp, v3);
@@ -631,9 +630,9 @@
 	     * mmap'ed writes or via write().
 	     */
 	    if (nfs_clean_pages_on_close && vp->v_object) {
-		VM_OBJECT_LOCK(vp->v_object);
+		VM_OBJECT_WLOCK(vp->v_object);
 		vm_object_page_clean(vp->v_object, 0, 0, 0);
-		VM_OBJECT_UNLOCK(vp->v_object);
+		VM_OBJECT_WUNLOCK(vp->v_object);
 	    }
 	    mtx_lock(&np->n_mtx);
 	    if (np->n_flag & NMODIFIED) {
@@ -716,7 +715,7 @@
 			goto nfsmout;
 	}
 	nfsstats.rpccnt[NFSPROC_GETATTR]++;
-	mreq = nfsm_reqhead(vp, NFSPROC_GETATTR, NFSX_FH(v3));
+	mreq = m_get2(NFSX_FH(v3), M_WAITOK, MT_DATA, 0);
 	mb = mreq;
 	bpos = mtod(mb, caddr_t);
 	nfsm_fhtom(vp, v3);
@@ -875,7 +874,7 @@
 	int v3 = NFS_ISV3(vp);
 
 	nfsstats.rpccnt[NFSPROC_SETATTR]++;
-	mreq = nfsm_reqhead(vp, NFSPROC_SETATTR, NFSX_FH(v3) + NFSX_SATTR(v3));
+	mreq = m_get2(NFSX_FH(v3) + NFSX_SATTR(v3), M_WAITOK, MT_DATA, 0);
 	mb = mreq;
 	bpos = mtod(mb, caddr_t);
 	nfsm_fhtom(vp, v3);
@@ -954,7 +953,7 @@
 		*vpp = NULLVP;
 		return (error);
 	}
-	error = cache_lookup_times(dvp, vpp, cnp, &nctime, &ncticks);
+	error = cache_lookup(dvp, vpp, cnp, &nctime, &ncticks);
 	if (error > 0 && error != ENOENT)
 		return (error);
 	if (error == -1) {
@@ -1039,8 +1038,8 @@
 	nfsstats.lookupcache_misses++;
 	nfsstats.rpccnt[NFSPROC_LOOKUP]++;
 	len = cnp->cn_namelen;
-	mreq = nfsm_reqhead(dvp, NFSPROC_LOOKUP,
-		NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len));
+	mreq = m_get2(NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len), M_WAITOK,
+	    MT_DATA, 0);
 	mb = mreq;
 	bpos = mtod(mb, caddr_t);
 	nfsm_fhtom(dvp, v3);
@@ -1183,8 +1182,7 @@
 			return (EJUSTRETURN);
 		}
 
-		if ((cnp->cn_flags & MAKEENTRY) && cnp->cn_nameiop != CREATE &&
-		    dattrflag) {
+		if ((cnp->cn_flags & MAKEENTRY) != 0 && dattrflag) {
 			/*
 			 * Cache the modification time of the parent
 			 * directory from the post-op attributes in
@@ -1253,7 +1251,7 @@
 	int v3 = NFS_ISV3(vp);
 
 	nfsstats.rpccnt[NFSPROC_READLINK]++;
-	mreq = nfsm_reqhead(vp, NFSPROC_READLINK, NFSX_FH(v3));
+	mreq = m_get2(NFSX_FH(v3), M_WAITOK, MT_DATA, 0);
 	mb = mreq;
 	bpos = mtod(mb, caddr_t);
 	nfsm_fhtom(vp, v3);
@@ -1308,7 +1306,8 @@
 	while (tsiz > 0) {
 		nfsstats.rpccnt[NFSPROC_READ]++;
 		len = (tsiz > rsize) ? rsize : tsiz;
-		mreq = nfsm_reqhead(vp, NFSPROC_READ, NFSX_FH(v3) + NFSX_UNSIGNED * 3);
+		mreq = m_get2(NFSX_FH(v3) + NFSX_UNSIGNED * 3, M_WAITOK,
+		    MT_DATA, 0);
 		mb = mreq;
 		bpos = mtod(mb, caddr_t);
 		nfsm_fhtom(vp, v3);
@@ -1380,8 +1379,8 @@
 	while (tsiz > 0) {
 		nfsstats.rpccnt[NFSPROC_WRITE]++;
 		len = (tsiz > wsize) ? wsize : tsiz;
-		mreq = nfsm_reqhead(vp, NFSPROC_WRITE,
-			NFSX_FH(v3) + 5 * NFSX_UNSIGNED + nfsm_rndup(len));
+		mreq = m_get2(NFSX_FH(v3) + 5 * NFSX_UNSIGNED, M_WAITOK,
+		    MT_DATA, 0);
 		mb = mreq;
 		bpos = mtod(mb, caddr_t);
 		nfsm_fhtom(vp, v3);
@@ -1503,8 +1502,8 @@
 	if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred)) != 0)
 		return (error);
 	nfsstats.rpccnt[NFSPROC_MKNOD]++;
-	mreq = nfsm_reqhead(dvp, NFSPROC_MKNOD, NFSX_FH(v3) + 4 * NFSX_UNSIGNED +
-		+ nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(v3));
+	mreq = m_get2(NFSX_FH(v3) + 4 * NFSX_UNSIGNED +
+	    nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(v3), M_WAITOK, MT_DATA, 0);
 	mb = mreq;
 	bpos = mtod(mb, caddr_t);
 	nfsm_fhtom(dvp, v3);
@@ -1607,8 +1606,8 @@
 		fmode |= O_EXCL;
 again:
 	nfsstats.rpccnt[NFSPROC_CREATE]++;
-	mreq = nfsm_reqhead(dvp, NFSPROC_CREATE, NFSX_FH(v3) + 2 * NFSX_UNSIGNED +
-		nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(v3));
+	mreq = m_get2(NFSX_FH(v3) + 2 * NFSX_UNSIGNED +
+	    nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(v3), M_WAITOK, MT_DATA, 0);
 	mb = mreq;
 	bpos = mtod(mb, caddr_t);
 	nfsm_fhtom(dvp, v3);
@@ -1789,8 +1788,8 @@
 	int v3 = NFS_ISV3(dvp);
 
 	nfsstats.rpccnt[NFSPROC_REMOVE]++;
-	mreq = nfsm_reqhead(dvp, NFSPROC_REMOVE,
-		NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(namelen));
+	mreq = m_get2(NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(namelen),
+	    M_WAITOK, MT_DATA, 0);
 	mb = mreq;
 	bpos = mtod(mb, caddr_t);
 	nfsm_fhtom(dvp, v3);
@@ -1925,9 +1924,8 @@
 	int v3 = NFS_ISV3(fdvp);
 
 	nfsstats.rpccnt[NFSPROC_RENAME]++;
-	mreq = nfsm_reqhead(fdvp, NFSPROC_RENAME,
-		(NFSX_FH(v3) + NFSX_UNSIGNED)*2 + nfsm_rndup(fnamelen) +
-		nfsm_rndup(tnamelen));
+	mreq = m_get2((NFSX_FH(v3) + NFSX_UNSIGNED)*2 + nfsm_rndup(fnamelen) +
+	    nfsm_rndup(tnamelen), M_WAITOK, MT_DATA, 0);
 	mb = mreq;
 	bpos = mtod(mb, caddr_t);
 	nfsm_fhtom(fdvp, v3);
@@ -1985,8 +1983,8 @@
 
 	v3 = NFS_ISV3(vp);
 	nfsstats.rpccnt[NFSPROC_LINK]++;
-	mreq = nfsm_reqhead(vp, NFSPROC_LINK,
-		NFSX_FH(v3)*2 + NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen));
+	mreq = m_get2(NFSX_FH(v3)*2 + NFSX_UNSIGNED +
+	    nfsm_rndup(cnp->cn_namelen), M_WAITOK, MT_DATA, 0);
 	mb = mreq;
 	bpos = mtod(mb, caddr_t);
 	nfsm_fhtom(vp, v3);
@@ -2031,8 +2029,9 @@
 
 	nfsstats.rpccnt[NFSPROC_SYMLINK]++;
 	slen = strlen(ap->a_target);
-	mreq = nfsm_reqhead(dvp, NFSPROC_SYMLINK, NFSX_FH(v3) + 2*NFSX_UNSIGNED +
-	    nfsm_rndup(cnp->cn_namelen) + nfsm_rndup(slen) + NFSX_SATTR(v3));
+	mreq = m_get2(NFSX_FH(v3) + 2*NFSX_UNSIGNED +
+	    nfsm_rndup(cnp->cn_namelen) + nfsm_rndup(slen) + NFSX_SATTR(v3),
+	    M_WAITOK, MT_DATA, 0);
 	mb = mreq;
 	bpos = mtod(mb, caddr_t);
 	nfsm_fhtom(dvp, v3);
@@ -2125,8 +2124,8 @@
 		return (error);
 	len = cnp->cn_namelen;
 	nfsstats.rpccnt[NFSPROC_MKDIR]++;
-	mreq = nfsm_reqhead(dvp, NFSPROC_MKDIR,
-	  NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len) + NFSX_SATTR(v3));
+	mreq = m_get2(NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len) +
+	    NFSX_SATTR(v3), M_WAITOK, MT_DATA, 0);
 	mb = mreq;
 	bpos = mtod(mb, caddr_t);
 	nfsm_fhtom(dvp, v3);
@@ -2190,8 +2189,8 @@
 	if (dvp == vp)
 		return (EINVAL);
 	nfsstats.rpccnt[NFSPROC_RMDIR]++;
-	mreq = nfsm_reqhead(dvp, NFSPROC_RMDIR,
-		NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen));
+	mreq = m_get2(NFSX_FH(v3) + NFSX_UNSIGNED +
+	    nfsm_rndup(cnp->cn_namelen), M_WAITOK, MT_DATA, 0);
 	mb = mreq;
 	bpos = mtod(mb, caddr_t);
 	nfsm_fhtom(dvp, v3);
@@ -2309,8 +2308,8 @@
 	 */
 	while (more_dirs && bigenough) {
 		nfsstats.rpccnt[NFSPROC_READDIR]++;
-		mreq = nfsm_reqhead(vp, NFSPROC_READDIR, NFSX_FH(v3) +
-			NFSX_READDIR(v3));
+		mreq = m_get2(NFSX_FH(v3) + NFSX_READDIR(v3), M_WAITOK,
+		    MT_DATA, 0);
 		mb = mreq;
 		bpos = mtod(mb, caddr_t);
 		nfsm_fhtom(vp, v3);
@@ -2515,8 +2514,8 @@
 	 */
 	while (more_dirs && bigenough) {
 		nfsstats.rpccnt[NFSPROC_READDIRPLUS]++;
-		mreq = nfsm_reqhead(vp, NFSPROC_READDIRPLUS,
-			NFSX_FH(1) + 6 * NFSX_UNSIGNED);
+		mreq = m_get2(NFSX_FH(1) + 6 * NFSX_UNSIGNED, M_WAITOK,
+		    MT_DATA, 0);
 		mb = mreq;
 		bpos = mtod(mb, caddr_t);
 		nfsm_fhtom(vp, 1);
@@ -2820,8 +2819,8 @@
 	int v3 = NFS_ISV3(dvp);
 
 	nfsstats.rpccnt[NFSPROC_LOOKUP]++;
-	mreq = nfsm_reqhead(dvp, NFSPROC_LOOKUP,
-		NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len));
+	mreq = m_get2(NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len),
+	    M_WAITOK, MT_DATA, 0);
 	mb = mreq;
 	bpos = mtod(mb, caddr_t);
 	nfsm_fhtom(dvp, v3);
@@ -2899,7 +2898,7 @@
 	}
 	mtx_unlock(&nmp->nm_mtx);
 	nfsstats.rpccnt[NFSPROC_COMMIT]++;
-	mreq = nfsm_reqhead(vp, NFSPROC_COMMIT, NFSX_FH(1));
+	mreq = m_get2(NFSX_FH(1), M_WAITOK, MT_DATA, 0);
 	mb = mreq;
 	bpos = mtod(mb, caddr_t);
 	nfsm_fhtom(vp, 1);
@@ -2993,7 +2992,7 @@
 	int bvecsize = 0, bveccount;
 
 	if (nmp->nm_flag & NFSMNT_INT)
-		slpflag = NFS_PCATCH;
+		slpflag = PCATCH;
 	if (!commit)
 		passone = 0;
 	bo = &vp->v_bufobj;
@@ -3178,7 +3177,7 @@
 
 			error = BUF_TIMELOCK(bp,
 			    LK_EXCLUSIVE | LK_SLEEPFAIL | LK_INTERLOCK,
-			    BO_MTX(bo), "nfsfsync", slpflag, slptimeo);
+			    BO_LOCKPTR(bo), "nfsfsync", slpflag, slptimeo);
 			if (error == 0) {
 				BUF_UNLOCK(bp);
 				goto loop;
@@ -3191,7 +3190,7 @@
 				error = EINTR;
 				goto done;
 			}
-			if (slpflag & PCATCH) {
+			if (slpflag == PCATCH) {
 				slpflag = 0;
 				slptimeo = 2 * hz;
 			}
@@ -3229,7 +3228,7 @@
 			    error = nfs_sigintr(nmp, td);
 			    if (error)
 				goto done;
-			    if (slpflag & PCATCH) {
+			    if (slpflag == PCATCH) {
 				slpflag = 0;
 				slptimeo = 2 * hz;
 			    }

Modified: trunk/sys/nfsclient/nfsargs.h
===================================================================
--- trunk/sys/nfsclient/nfsargs.h	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfsclient/nfsargs.h	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1989, 1993, 1995
  *	The Regents of the University of California.  All rights reserved.
@@ -30,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)nfs.h	8.4 (Berkeley) 5/1/95
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/nfsclient/nfsargs.h 317525 2017-04-27 21:37:39Z rmacklem $
  */
 
 #ifndef _NFSCLIENT_NFSARGS_H_
@@ -76,7 +77,7 @@
 #define	NFSMNT_MAXGRPS		0x00000020  /* set maximum grouplist size */
 #define	NFSMNT_INT		0x00000040  /* allow interrupts on hard mount */
 #define	NFSMNT_NOCONN		0x00000080  /* Don't Connect the socket */
-/* 0x100 free, was NFSMNT_NQNFS */
+#define	NFSMNT_ONEOPENOWN	0x00000100  /* Use one OpenOwner for NFSv4.1 */
 #define	NFSMNT_NFSV3		0x00000200  /* Use NFS Version 3 protocol */
 #define	NFSMNT_KERB		0x00000400  /* Use RPCSEC_GSS/Krb5 */
 #define	NFSMNT_DUMBTIMR		0x00000800  /* Don't estimate rtt dynamically */
@@ -98,5 +99,7 @@
 #define	NFSMNT_ALLGSSNAME	0x08000000 /* Use principal for all accesses */
 #define	NFSMNT_STRICT3530	0x10000000 /* Adhere strictly to RFC3530 */
 #define	NFSMNT_NOCTO		0x20000000 /* Don't flush attrcache on open */
+#define	NFSMNT_PNFS		0x40000000 /* Enable pNFS support */
+#define	NFSMNT_NONCONTIGWR	0x80000000 /* Enable non-contiguous writes */
 
 #endif

Modified: trunk/sys/nfsclient/nfsm_subs.h
===================================================================
--- trunk/sys/nfsclient/nfsm_subs.h	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfsclient/nfsm_subs.h	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1989, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -30,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)nfsm_subs.h	8.2 (Berkeley) 3/30/95
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/nfsclient/nfsm_subs.h 248198 2013-03-12 12:23:47Z glebius $
  */
 
 #ifndef _NFSCLIENT_NFSM_SUBS_H_
@@ -53,35 +54,7 @@
  * First define what the actual subs. return
  */
 u_int32_t nfs_xid_gen(void);
-struct mbuf *nfsm_reqhead(struct vnode *vp, u_long procid, int hsiz);
 
-#define	M_HASCL(m)	((m)->m_flags & M_EXT)
-#define	NFSMINOFF(m) \
-	do { \
-		if (M_HASCL(m)) \
-			(m)->m_data = (m)->m_ext.ext_buf; \
-		else if ((m)->m_flags & M_PKTHDR) \
-			(m)->m_data = (m)->m_pktdat; \
-		else \
-			(m)->m_data = (m)->m_dat; \
-	} while (0)
-#define	NFSMSIZ(m)	((M_HASCL(m))?MCLBYTES: \
-				(((m)->m_flags & M_PKTHDR)?MHLEN:MLEN))
-
-/*
- * Now for the macros that do the simple stuff and call the functions
- * for the hard stuff.
- * These macros use several vars. declared in nfsm_reqhead and these
- * vars. must not be used elsewhere unless you are careful not to corrupt
- * them. The vars. starting with pN and tN (N=1,2,3,..) are temporaries
- * that may be used so long as the value is not expected to retained
- * after a macro.
- * I know, this is kind of dorkey, but it makes the actual op functions
- * fairly clean and deals with the mess caused by the xdr discriminating
- * unions.
- */
-
-
 /* *********************************** */
 /* Request generation phase macros */
 

Modified: trunk/sys/nfsclient/nfsmount.h
===================================================================
--- trunk/sys/nfsclient/nfsmount.h	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfsclient/nfsmount.h	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1989, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -30,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)nfsmount.h	8.3 (Berkeley) 3/30/95
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/nfsclient/nfsmount.h 248255 2013-03-13 21:06:03Z jhb $
  */
 
 #ifndef _NFSCLIENT_NFSMOUNT_H_
@@ -125,8 +126,6 @@
 #define NFS_DEFAULT_NEGNAMETIMEO	60
 #endif
 
-#define	NFS_PCATCH	(PCATCH | PBDRY)
-
 #endif
 
 #endif

Modified: trunk/sys/nfsclient/nfsnode.h
===================================================================
--- trunk/sys/nfsclient/nfsnode.h	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfsclient/nfsnode.h	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1989, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -30,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)nfsnode.h	8.9 (Berkeley) 5/14/95
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/nfsclient/nfsnode.h 235332 2012-05-12 12:02:51Z rmacklem $
  */
 
 #ifndef _NFSCLIENT_NFSNODE_H_
@@ -104,9 +105,6 @@
 	time_t			n_attrstamp;	/* Attr. cache timestamp */
 	struct nfs_accesscache	n_accesscache[NFS_ACCESSCACHESIZE];
 	struct timespec		n_mtime;	/* Prev modify time. */
-	struct timespec		n_unused0;
-	struct timespec		n_unused1;
-	int			n_unused2;
 	nfsfh_t			*n_fhp;		/* NFS File Handle */
 	struct vnode		*n_vnode;	/* associated vnode */
 	struct vnode		*n_dvp;		/* parent vnode */

Modified: trunk/sys/nfsclient/nfsstats.h
===================================================================
--- trunk/sys/nfsclient/nfsstats.h	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfsclient/nfsstats.h	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1989, 1993, 1995
  *	The Regents of the University of California.  All rights reserved.
@@ -30,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)nfs.h	8.4 (Berkeley) 5/1/95
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/nfsclient/nfsstats.h 139823 2005-01-07 01:45:51Z imp $
  */
 
 #ifndef _NFSCLIENT_NFSSTATS_H_

Modified: trunk/sys/nfsclient/nlminfo.h
===================================================================
--- trunk/sys/nfsclient/nlminfo.h	2018-05-25 13:03:01 UTC (rev 9921)
+++ trunk/sys/nfsclient/nlminfo.h	2018-05-25 13:03:43 UTC (rev 9922)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1998 Berkeley Software Design, Inc. All rights reserved.
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +26,7 @@
  * SUCH DAMAGE.
  *
  *      from BSDI nlminfo.h,v 2.1 1998/03/18 01:30:38 don Exp
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/nfsclient/nlminfo.h 151695 2005-10-26 07:18:37Z glebius $
  */
 
 /*



More information about the Midnightbsd-cvs mailing list