[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