2 * Copyright (c) 1989, 1993, 1995
3 * The Regents of the University of California. All rights reserved.
5 * This code is derived from software contributed to Berkeley by
6 * Rick Macklem at The University of Guelph.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 4. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * @(#)nfs_vfsops.c 8.12 (Berkeley) 5/20/95
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
39 #include "opt_bootp.h"
40 #include "opt_nfsroot.h"
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
47 #include <sys/clock.h>
49 #include <sys/malloc.h>
51 #include <sys/module.h>
52 #include <sys/mount.h>
54 #include <sys/socket.h>
55 #include <sys/socketvar.h>
56 #include <sys/sockio.h>
57 #include <sys/sysctl.h>
58 #include <sys/vnode.h>
59 #include <sys/signalvar.h>
62 #include <vm/vm_extern.h>
66 #include <net/route.h>
67 #include <netinet/in.h>
69 #include <rpc/rpcclnt.h>
71 #include <nfs/rpcv2.h>
72 #include <nfs/nfsproto.h>
73 #include <nfsclient/nfs.h>
74 #include <nfsclient/nfsnode.h>
75 #include <nfsclient/nfsmount.h>
76 #include <nfs/xdr_subs.h>
77 #include <nfsclient/nfsm_subs.h>
78 #include <nfsclient/nfsdiskless.h>
80 MALLOC_DEFINE(M_NFSREQ, "nfsclient_req", "NFS request header");
81 MALLOC_DEFINE(M_NFSBIGFH, "nfsclient_bigfh", "NFS version 3 file handle");
82 MALLOC_DEFINE(M_NFSDIROFF, "nfsclient_diroff", "NFS directory offset data");
83 MALLOC_DEFINE(M_NFSHASH, "nfsclient_hash", "NFS hash tables");
84 MALLOC_DEFINE(M_NFSDIRECTIO, "nfsclient_directio", "NFS Direct IO async write state");
86 uma_zone_t nfsmount_zone;
88 struct nfsstats nfsstats;
90 SYSCTL_NODE(_vfs, OID_AUTO, nfs, CTLFLAG_RW, 0, "NFS filesystem");
91 SYSCTL_STRUCT(_vfs_nfs, NFS_NFSSTATS, nfsstats, CTLFLAG_RW,
92 &nfsstats, nfsstats, "S,nfsstats");
93 static int nfs_ip_paranoia = 1;
94 SYSCTL_INT(_vfs_nfs, OID_AUTO, nfs_ip_paranoia, CTLFLAG_RW,
95 &nfs_ip_paranoia, 0, "");
98 SYSCTL_INT(_vfs_nfs, OID_AUTO, debug, CTLFLAG_RW, &nfs_debug, 0, "");
100 static int nfs_tprintf_initial_delay = NFS_TPRINTF_INITIAL_DELAY;
101 SYSCTL_INT(_vfs_nfs, NFS_TPRINTF_INITIAL_DELAY,
102 downdelayinitial, CTLFLAG_RW, &nfs_tprintf_initial_delay, 0, "");
103 /* how long between console messages "nfs server foo not responding" */
104 static int nfs_tprintf_delay = NFS_TPRINTF_DELAY;
105 SYSCTL_INT(_vfs_nfs, NFS_TPRINTF_DELAY,
106 downdelayinterval, CTLFLAG_RW, &nfs_tprintf_delay, 0, "");
108 static void nfs_decode_args(struct mount *mp, struct nfsmount *nmp,
109 struct nfs_args *argp, const char *hostname);
110 static int mountnfs(struct nfs_args *, struct mount *,
111 struct sockaddr *, char *, struct vnode **,
113 static vfs_mount_t nfs_mount;
114 static vfs_cmount_t nfs_cmount;
115 static vfs_unmount_t nfs_unmount;
116 static vfs_root_t nfs_root;
117 static vfs_statfs_t nfs_statfs;
118 static vfs_sync_t nfs_sync;
119 static vfs_sysctl_t nfs_sysctl;
122 * nfs vfs operations.
124 static struct vfsops nfs_vfsops = {
125 .vfs_init = nfs_init,
126 .vfs_mount = nfs_mount,
127 .vfs_cmount = nfs_cmount,
128 .vfs_root = nfs_root,
129 .vfs_statfs = nfs_statfs,
130 .vfs_sync = nfs_sync,
131 .vfs_uninit = nfs_uninit,
132 .vfs_unmount = nfs_unmount,
133 .vfs_sysctl = nfs_sysctl,
135 VFS_SET(nfs_vfsops, nfs, VFCF_NETWORK);
137 /* So that loader and kldload(2) can find us, wherever we are.. */
138 MODULE_VERSION(nfs, 1);
140 static struct nfs_rpcops nfs_rpcops = {
150 * This structure must be filled in by a primary bootstrap or bootstrap
151 * server for a diskless/dataless machine. It is initialized below just
152 * to ensure that it is allocated to initialized data (.data not .bss).
154 struct nfs_diskless nfs_diskless = { { { 0 } } };
155 struct nfsv3_diskless nfsv3_diskless = { { { 0 } } };
156 int nfs_diskless_valid = 0;
158 SYSCTL_INT(_vfs_nfs, OID_AUTO, diskless_valid, CTLFLAG_RD,
159 &nfs_diskless_valid, 0, "");
161 SYSCTL_STRING(_vfs_nfs, OID_AUTO, diskless_rootpath, CTLFLAG_RD,
162 nfsv3_diskless.root_hostnam, 0, "");
164 SYSCTL_OPAQUE(_vfs_nfs, OID_AUTO, diskless_rootaddr, CTLFLAG_RD,
165 &nfsv3_diskless.root_saddr, sizeof nfsv3_diskless.root_saddr,
166 "%Ssockaddr_in", "");
169 void nfsargs_ntoh(struct nfs_args *);
170 static int nfs_mountdiskless(char *, int,
171 struct sockaddr_in *, struct nfs_args *,
172 struct thread *, struct vnode **, struct mount *);
173 static void nfs_convert_diskless(void);
174 static void nfs_convert_oargs(struct nfs_args *args,
175 struct onfs_args *oargs);
178 nfs_iosize(struct nfsmount *nmp)
183 * Calculate the size used for io buffers. Use the larger
184 * of the two sizes to minimise nfs requests but make sure
185 * that it is at least one VM page to avoid wasting buffer
188 iosize = imax(nmp->nm_rsize, nmp->nm_wsize);
189 iosize = imax(iosize, PAGE_SIZE);
194 nfs_convert_oargs(struct nfs_args *args, struct onfs_args *oargs)
197 args->version = NFS_ARGSVERSION;
198 args->addr = oargs->addr;
199 args->addrlen = oargs->addrlen;
200 args->sotype = oargs->sotype;
201 args->proto = oargs->proto;
202 args->fh = oargs->fh;
203 args->fhsize = oargs->fhsize;
204 args->flags = oargs->flags;
205 args->wsize = oargs->wsize;
206 args->rsize = oargs->rsize;
207 args->readdirsize = oargs->readdirsize;
208 args->timeo = oargs->timeo;
209 args->retrans = oargs->retrans;
210 args->maxgrouplist = oargs->maxgrouplist;
211 args->readahead = oargs->readahead;
212 args->deadthresh = oargs->deadthresh;
213 args->hostname = oargs->hostname;
217 nfs_convert_diskless(void)
220 bcopy(&nfs_diskless.myif, &nfsv3_diskless.myif,
221 sizeof(struct ifaliasreq));
222 bcopy(&nfs_diskless.mygateway, &nfsv3_diskless.mygateway,
223 sizeof(struct sockaddr_in));
224 nfs_convert_oargs(&nfsv3_diskless.root_args,&nfs_diskless.root_args);
225 if (nfsv3_diskless.root_args.flags & NFSMNT_NFSV3) {
226 nfsv3_diskless.root_fhsize = NFSX_V3FH;
227 bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V3FH);
229 nfsv3_diskless.root_fhsize = NFSX_V2FH;
230 bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V2FH);
232 bcopy(&nfs_diskless.root_saddr,&nfsv3_diskless.root_saddr,
233 sizeof(struct sockaddr_in));
234 bcopy(nfs_diskless.root_hostnam, nfsv3_diskless.root_hostnam, MNAMELEN);
235 nfsv3_diskless.root_time = nfs_diskless.root_time;
236 bcopy(nfs_diskless.my_hostnam, nfsv3_diskless.my_hostnam,
238 nfs_diskless_valid = 3;
245 nfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td)
248 struct nfs_statfs *sfp;
250 struct nfsmount *nmp = VFSTONFS(mp);
251 int error = 0, v3 = (nmp->nm_flag & NFSMNT_NFSV3), retattr;
252 struct mbuf *mreq, *mrep, *md, *mb;
259 error = vfs_busy(mp, 0, NULL, td);
262 error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
268 mtx_lock(&nmp->nm_mtx);
269 if (v3 && (nmp->nm_state & NFSSTA_GOTFSINFO) == 0) {
270 mtx_unlock(&nmp->nm_mtx);
271 (void)nfs_fsinfo(nmp, vp, td->td_ucred, td);
273 mtx_unlock(&nmp->nm_mtx);
274 nfsstats.rpccnt[NFSPROC_FSSTAT]++;
275 mreq = nfsm_reqhead(vp, NFSPROC_FSSTAT, NFSX_FH(v3));
277 bpos = mtod(mb, caddr_t);
279 nfsm_request(vp, NFSPROC_FSSTAT, td, td->td_ucred);
281 nfsm_postop_attr(vp, retattr);
287 sfp = nfsm_dissect(struct nfs_statfs *, NFSX_STATFS(v3));
288 mtx_lock(&nmp->nm_mtx);
289 sbp->f_iosize = nfs_iosize(nmp);
290 mtx_unlock(&nmp->nm_mtx);
292 sbp->f_bsize = NFS_FABLKSIZE;
293 tquad = fxdr_hyper(&sfp->sf_tbytes);
294 sbp->f_blocks = tquad / NFS_FABLKSIZE;
295 tquad = fxdr_hyper(&sfp->sf_fbytes);
296 sbp->f_bfree = tquad / NFS_FABLKSIZE;
297 tquad = fxdr_hyper(&sfp->sf_abytes);
298 sbp->f_bavail = tquad / NFS_FABLKSIZE;
299 sbp->f_files = (fxdr_unsigned(int32_t,
300 sfp->sf_tfiles.nfsuquad[1]) & 0x7fffffff);
301 sbp->f_ffree = (fxdr_unsigned(int32_t,
302 sfp->sf_ffiles.nfsuquad[1]) & 0x7fffffff);
304 sbp->f_bsize = fxdr_unsigned(int32_t, sfp->sf_bsize);
305 sbp->f_blocks = fxdr_unsigned(int32_t, sfp->sf_blocks);
306 sbp->f_bfree = fxdr_unsigned(int32_t, sfp->sf_bfree);
307 sbp->f_bavail = fxdr_unsigned(int32_t, sfp->sf_bavail);
319 * nfs version 3 fsinfo rpc call
322 nfs_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct ucred *cred,
325 struct nfsv3_fsinfo *fsp;
328 int error = 0, retattr;
329 struct mbuf *mreq, *mrep, *md, *mb;
332 nfsstats.rpccnt[NFSPROC_FSINFO]++;
333 mreq = nfsm_reqhead(vp, NFSPROC_FSINFO, NFSX_FH(1));
335 bpos = mtod(mb, caddr_t);
337 nfsm_request(vp, NFSPROC_FSINFO, td, cred);
338 nfsm_postop_attr(vp, retattr);
340 fsp = nfsm_dissect(struct nfsv3_fsinfo *, NFSX_V3FSINFO);
341 pref = fxdr_unsigned(u_int32_t, fsp->fs_wtpref);
342 mtx_lock(&nmp->nm_mtx);
343 if (pref < nmp->nm_wsize && pref >= NFS_FABLKSIZE)
344 nmp->nm_wsize = (pref + NFS_FABLKSIZE - 1) &
345 ~(NFS_FABLKSIZE - 1);
346 max = fxdr_unsigned(u_int32_t, fsp->fs_wtmax);
347 if (max < nmp->nm_wsize && max > 0) {
348 nmp->nm_wsize = max & ~(NFS_FABLKSIZE - 1);
349 if (nmp->nm_wsize == 0)
352 pref = fxdr_unsigned(u_int32_t, fsp->fs_rtpref);
353 if (pref < nmp->nm_rsize && pref >= NFS_FABLKSIZE)
354 nmp->nm_rsize = (pref + NFS_FABLKSIZE - 1) &
355 ~(NFS_FABLKSIZE - 1);
356 max = fxdr_unsigned(u_int32_t, fsp->fs_rtmax);
357 if (max < nmp->nm_rsize && max > 0) {
358 nmp->nm_rsize = max & ~(NFS_FABLKSIZE - 1);
359 if (nmp->nm_rsize == 0)
362 pref = fxdr_unsigned(u_int32_t, fsp->fs_dtpref);
363 if (pref < nmp->nm_readdirsize && pref >= NFS_DIRBLKSIZ)
364 nmp->nm_readdirsize = (pref + NFS_DIRBLKSIZ - 1) &
365 ~(NFS_DIRBLKSIZ - 1);
366 if (max < nmp->nm_readdirsize && max > 0) {
367 nmp->nm_readdirsize = max & ~(NFS_DIRBLKSIZ - 1);
368 if (nmp->nm_readdirsize == 0)
369 nmp->nm_readdirsize = max;
371 maxfsize = fxdr_hyper(&fsp->fs_maxfilesize);
372 if (maxfsize > 0 && maxfsize < nmp->nm_maxfilesize)
373 nmp->nm_maxfilesize = maxfsize;
374 nmp->nm_mountp->mnt_stat.f_iosize = nfs_iosize(nmp);
375 nmp->nm_state |= NFSSTA_GOTFSINFO;
376 mtx_unlock(&nmp->nm_mtx);
384 * Mount a remote root fs via. nfs. This depends on the info in the
385 * nfs_diskless structure that has been filled in properly by some primary
387 * It goes something like this:
388 * - do enough of "ifconfig" by calling ifioctl() so that the system
389 * can talk to the server
390 * - If nfs_diskless.mygateway is filled in, use that address as
392 * - build the rootfs mount point and call mountnfs() to do the rest.
394 * It is assumed to be safe to read, modify, and write the nfsv3_diskless
395 * structure, as well as other global NFS client variables here, as
396 * nfs_mountroot() will be called once in the boot before any other NFS
397 * client activity occurs.
400 nfs_mountroot(struct mount *mp, struct thread *td)
402 struct nfsv3_diskless *nd = &nfsv3_diskless;
411 #if defined(BOOTP_NFSROOT) && defined(BOOTP)
412 bootpc_init(); /* use bootp to get nfs_diskless filled in */
413 #elif defined(NFS_ROOT)
414 nfs_setup_diskless();
417 if (nfs_diskless_valid == 0)
419 if (nfs_diskless_valid == 1)
420 nfs_convert_diskless();
423 * XXX splnet, so networks will receive...
428 * Do enough of ifconfig(8) so that the critical net interface can
429 * talk to the server.
431 error = socreate(nd->myif.ifra_addr.sa_family, &so, nd->root_args.sotype, 0,
434 panic("nfs_mountroot: socreate(%04x): %d",
435 nd->myif.ifra_addr.sa_family, error);
437 #if 0 /* XXX Bad idea */
439 * We might not have been told the right interface, so we pass
440 * over the first ten interfaces of the same kind, until we get
441 * one of them configured.
444 for (i = strlen(nd->myif.ifra_name) - 1;
445 nd->myif.ifra_name[i] >= '0' &&
446 nd->myif.ifra_name[i] <= '9';
447 nd->myif.ifra_name[i] ++) {
448 error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
453 error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
455 panic("nfs_mountroot: SIOCAIFADDR: %d", error);
456 if ((cp = getenv("boot.netif.mtu")) != NULL) {
457 ir.ifr_mtu = strtol(cp, NULL, 10);
458 bcopy(nd->myif.ifra_name, ir.ifr_name, IFNAMSIZ);
460 error = ifioctl(so, SIOCSIFMTU, (caddr_t)&ir, td);
462 printf("nfs_mountroot: SIOCSIFMTU: %d", error);
467 * If the gateway field is filled in, set it as the default route.
468 * Note that pxeboot will set a default route of 0 if the route
469 * is not set by the DHCP server. Check also for a value of 0
470 * to avoid panicking inappropriately in that situation.
472 if (nd->mygateway.sin_len != 0 &&
473 nd->mygateway.sin_addr.s_addr != 0) {
474 struct sockaddr_in mask, sin;
476 bzero((caddr_t)&mask, sizeof(mask));
478 sin.sin_family = AF_INET;
479 sin.sin_len = sizeof(sin);
480 /* XXX MRT use table 0 for this sort of thing */
481 error = rtrequest(RTM_ADD, (struct sockaddr *)&sin,
482 (struct sockaddr *)&nd->mygateway,
483 (struct sockaddr *)&mask,
484 RTF_UP | RTF_GATEWAY, NULL);
486 panic("nfs_mountroot: RTM_ADD: %d", error);
490 * Create the rootfs mount point.
492 nd->root_args.fh = nd->root_fh;
493 nd->root_args.fhsize = nd->root_fhsize;
494 l = ntohl(nd->root_saddr.sin_addr.s_addr);
495 snprintf(buf, sizeof(buf), "%ld.%ld.%ld.%ld:%s",
496 (l >> 24) & 0xff, (l >> 16) & 0xff,
497 (l >> 8) & 0xff, (l >> 0) & 0xff, nd->root_hostnam);
498 printf("NFS ROOT: %s\n", buf);
499 nd->root_args.hostname = buf;
500 if ((error = nfs_mountdiskless(buf, MNT_RDONLY,
501 &nd->root_saddr, &nd->root_args, td, &vp, mp)) != 0) {
506 * This is not really an nfs issue, but it is much easier to
507 * set hostname here and then let the "/etc/rc.xxx" files
508 * mount the right /var based upon its preset value.
510 bcopy(nd->my_hostnam, hostname, MAXHOSTNAMELEN);
511 hostname[MAXHOSTNAMELEN - 1] = '\0';
512 for (i = 0; i < MAXHOSTNAMELEN; i++)
513 if (hostname[i] == '\0')
515 inittodr(ntohl(nd->root_time));
520 * Internal version of mount system call for diskless setup.
523 nfs_mountdiskless(char *path, int mountflag,
524 struct sockaddr_in *sin, struct nfs_args *args, struct thread *td,
525 struct vnode **vpp, struct mount *mp)
527 struct sockaddr *nam;
531 mp->mnt_kern_flag = 0;
532 mp->mnt_flag = mountflag;
534 nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK);
535 if ((error = mountnfs(args, mp, nam, path, vpp,
536 td->td_ucred)) != 0) {
537 printf("nfs_mountroot: mount %s on /: %d\n", path, error);
544 nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
545 const char *hostname)
555 * Set read-only flag if requested; otherwise, clear it if this is
556 * an update. If this is not an update, then either the read-only
557 * flag is already clear, or this is a root mount and it was set
558 * intentionally at some previous point.
560 if (vfs_getopt(mp->mnt_optnew, "ro", NULL, NULL) == 0) {
562 mp->mnt_flag |= MNT_RDONLY;
564 } else if (mp->mnt_flag & MNT_UPDATE) {
566 mp->mnt_flag &= ~MNT_RDONLY;
571 * Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes
572 * no sense in that context. Also, set up appropriate retransmit
573 * and soft timeout behavior.
575 if (argp->sotype == SOCK_STREAM) {
576 nmp->nm_flag &= ~NFSMNT_NOCONN;
577 nmp->nm_flag |= NFSMNT_DUMBTIMR;
578 nmp->nm_timeo = NFS_MAXTIMEO;
579 nmp->nm_retry = NFS_RETRANS_TCP;
582 /* Also clear RDIRPLUS if not NFSv3, it crashes some servers */
583 if ((argp->flags & NFSMNT_NFSV3) == 0)
584 nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
586 /* Re-bind if rsrvd port requested and wasn't on one */
587 adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT)
588 && (argp->flags & NFSMNT_RESVPORT);
589 /* Also re-bind if we're switching to/from a connected UDP socket */
590 adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) !=
591 (argp->flags & NFSMNT_NOCONN));
593 /* Update flags atomically. Don't change the lock bits. */
594 nmp->nm_flag = argp->flags | nmp->nm_flag;
597 if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) {
598 nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10;
599 if (nmp->nm_timeo < NFS_MINTIMEO)
600 nmp->nm_timeo = NFS_MINTIMEO;
601 else if (nmp->nm_timeo > NFS_MAXTIMEO)
602 nmp->nm_timeo = NFS_MAXTIMEO;
605 if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) {
606 nmp->nm_retry = argp->retrans;
607 if (nmp->nm_retry > NFS_MAXREXMIT)
608 nmp->nm_retry = NFS_MAXREXMIT;
611 if (argp->flags & NFSMNT_NFSV3) {
612 if (argp->sotype == SOCK_DGRAM)
613 maxio = NFS_MAXDGRAMDATA;
617 maxio = NFS_V2MAXDATA;
619 if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) {
620 nmp->nm_wsize = argp->wsize;
621 /* Round down to multiple of blocksize */
622 nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1);
623 if (nmp->nm_wsize <= 0)
624 nmp->nm_wsize = NFS_FABLKSIZE;
626 if (nmp->nm_wsize > maxio)
627 nmp->nm_wsize = maxio;
628 if (nmp->nm_wsize > MAXBSIZE)
629 nmp->nm_wsize = MAXBSIZE;
631 if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) {
632 nmp->nm_rsize = argp->rsize;
633 /* Round down to multiple of blocksize */
634 nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1);
635 if (nmp->nm_rsize <= 0)
636 nmp->nm_rsize = NFS_FABLKSIZE;
638 if (nmp->nm_rsize > maxio)
639 nmp->nm_rsize = maxio;
640 if (nmp->nm_rsize > MAXBSIZE)
641 nmp->nm_rsize = MAXBSIZE;
643 if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) {
644 nmp->nm_readdirsize = argp->readdirsize;
646 if (nmp->nm_readdirsize > maxio)
647 nmp->nm_readdirsize = maxio;
648 if (nmp->nm_readdirsize > nmp->nm_rsize)
649 nmp->nm_readdirsize = nmp->nm_rsize;
651 if ((argp->flags & NFSMNT_ACREGMIN) && argp->acregmin >= 0)
652 nmp->nm_acregmin = argp->acregmin;
654 nmp->nm_acregmin = NFS_MINATTRTIMO;
655 if ((argp->flags & NFSMNT_ACREGMAX) && argp->acregmax >= 0)
656 nmp->nm_acregmax = argp->acregmax;
658 nmp->nm_acregmax = NFS_MAXATTRTIMO;
659 if ((argp->flags & NFSMNT_ACDIRMIN) && argp->acdirmin >= 0)
660 nmp->nm_acdirmin = argp->acdirmin;
662 nmp->nm_acdirmin = NFS_MINDIRATTRTIMO;
663 if ((argp->flags & NFSMNT_ACDIRMAX) && argp->acdirmax >= 0)
664 nmp->nm_acdirmax = argp->acdirmax;
666 nmp->nm_acdirmax = NFS_MAXDIRATTRTIMO;
667 if (nmp->nm_acdirmin > nmp->nm_acdirmax)
668 nmp->nm_acdirmin = nmp->nm_acdirmax;
669 if (nmp->nm_acregmin > nmp->nm_acregmax)
670 nmp->nm_acregmin = nmp->nm_acregmax;
672 if ((argp->flags & NFSMNT_MAXGRPS) && argp->maxgrouplist >= 0) {
673 if (argp->maxgrouplist <= NFS_MAXGRPS)
674 nmp->nm_numgrps = argp->maxgrouplist;
676 nmp->nm_numgrps = NFS_MAXGRPS;
678 if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0) {
679 if (argp->readahead <= NFS_MAXRAHEAD)
680 nmp->nm_readahead = argp->readahead;
682 nmp->nm_readahead = NFS_MAXRAHEAD;
684 if ((argp->flags & NFSMNT_WCOMMITSIZE) && argp->wcommitsize >= 0) {
685 if (argp->wcommitsize < nmp->nm_wsize)
686 nmp->nm_wcommitsize = nmp->nm_wsize;
688 nmp->nm_wcommitsize = argp->wcommitsize;
690 if ((argp->flags & NFSMNT_DEADTHRESH) && argp->deadthresh >= 0) {
691 if (argp->deadthresh <= NFS_MAXDEADTHRESH)
692 nmp->nm_deadthresh = argp->deadthresh;
694 nmp->nm_deadthresh = NFS_MAXDEADTHRESH;
697 adjsock |= ((nmp->nm_sotype != argp->sotype) ||
698 (nmp->nm_soproto != argp->proto));
699 nmp->nm_sotype = argp->sotype;
700 nmp->nm_soproto = argp->proto;
702 if (nmp->nm_so && adjsock) {
703 nfs_safedisconnect(nmp);
704 if (nmp->nm_sotype == SOCK_DGRAM)
705 while (nfs_connect(nmp, NULL)) {
706 printf("nfs_args: retrying connect\n");
707 (void) tsleep((caddr_t)&lbolt, PSOCK, "nfscon", 0);
712 strlcpy(nmp->nm_hostname, hostname,
713 sizeof(nmp->nm_hostname));
714 p = strchr(nmp->nm_hostname, ':');
720 static const char *nfs_opts[] = { "from", "nfs_args",
721 "noatime", "noexec", "suiddir", "nosuid", "nosymfollow", "union",
722 "noclusterr", "noclusterw", "multilabel", "acls", "force", "update",
723 "async", "dumbtimer", "noconn", "nolockd", "intr", "rdirplus", "resvport",
724 "readdirsize", "soft", "hard", "mntudp", "tcp", "udp", "wsize", "rsize",
725 "retrans", "acregmin", "acregmax", "acdirmin", "acdirmax",
726 "deadthresh", "hostname", "timeout", "addr", "fh", "nfsv3",
734 * It seems a bit dumb to copyinstr() the host and path here and then
735 * bcopy() them in mountnfs(), but I wanted to detect errors before
736 * doing the sockargs() call because sockargs() allocates an mbuf and
737 * an error after that means that I have to release the mbuf.
741 nfs_mount(struct mount *mp, struct thread *td)
743 int error, ret, has_nfs_args_opt;
744 int has_addr_opt, has_fh_opt, has_hostname_opt;
745 struct nfs_args args;
746 struct sockaddr *nam;
750 u_char nfh[NFSX_V3FHMAX];
753 has_nfs_args_opt = 0;
756 has_hostname_opt = 0;
758 if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) {
763 if (mp->mnt_flag & MNT_ROOTFS) {
764 error = nfs_mountroot(mp, td);
769 * The old mount_nfs program passed the struct nfs_args
770 * from userspace to kernel. The new mount_nfs program
771 * passes string options via nmount() from userspace to kernel
772 * and we populate the struct nfs_args in the kernel.
774 if (vfs_getopt(mp->mnt_optnew, "nfs_args", NULL, NULL) == 0) {
775 error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args,
780 if (args.version != NFS_ARGSVERSION) {
781 error = EPROGMISMATCH;
784 has_nfs_args_opt = 1;
787 if (vfs_getopt(mp->mnt_optnew, "dumbtimer", NULL, NULL) == 0)
788 args.flags |= NFSMNT_DUMBTIMR;
789 if (vfs_getopt(mp->mnt_optnew, "noconn", NULL, NULL) == 0)
790 args.flags |= NFSMNT_NOCONN;
791 if (vfs_getopt(mp->mnt_optnew, "conn", NULL, NULL) == 0)
792 args.flags |= NFSMNT_NOCONN;
793 if (vfs_getopt(mp->mnt_optnew, "nolockd", NULL, NULL) == 0)
794 args.flags |= NFSMNT_NOLOCKD;
795 if (vfs_getopt(mp->mnt_optnew, "lockd", NULL, NULL) == 0)
796 args.flags &= ~NFSMNT_NOLOCKD;
797 if (vfs_getopt(mp->mnt_optnew, "intr", NULL, NULL) == 0)
798 args.flags |= NFSMNT_INT;
799 if (vfs_getopt(mp->mnt_optnew, "rdirplus", NULL, NULL) == 0)
800 args.flags |= NFSMNT_RDIRPLUS;
801 if (vfs_getopt(mp->mnt_optnew, "resvport", NULL, NULL) == 0)
802 args.flags |= NFSMNT_RESVPORT;
803 if (vfs_getopt(mp->mnt_optnew, "noresvport", NULL, NULL) == 0)
804 args.flags &= ~NFSMNT_RESVPORT;
805 if (vfs_getopt(mp->mnt_optnew, "soft", NULL, NULL) == 0)
806 args.flags |= NFSMNT_SOFT;
807 if (vfs_getopt(mp->mnt_optnew, "hard", NULL, NULL) == 0)
808 args.flags &= ~NFSMNT_SOFT;
809 if (vfs_getopt(mp->mnt_optnew, "mntudp", NULL, NULL) == 0)
810 args.sotype = SOCK_DGRAM;
811 if (vfs_getopt(mp->mnt_optnew, "udp", NULL, NULL) == 0)
812 args.sotype = SOCK_DGRAM;
813 if (vfs_getopt(mp->mnt_optnew, "tcp", NULL, NULL) == 0)
814 args.sotype = SOCK_STREAM;
815 if (vfs_getopt(mp->mnt_optnew, "nfsv3", NULL, NULL) == 0)
816 args.flags |= NFSMNT_NFSV3;
817 if (vfs_getopt(mp->mnt_optnew, "readdirsize", (void **)&opt, NULL) == 0) {
819 vfs_mount_error(mp, "illegal readdirsize");
823 ret = sscanf(opt, "%d", &args.readdirsize);
824 if (ret != 1 || args.readdirsize <= 0) {
825 vfs_mount_error(mp, "illegal readdirsize: %s",
830 args.flags |= NFSMNT_READDIRSIZE;
832 if (vfs_getopt(mp->mnt_optnew, "readahead", (void **)&opt, NULL) == 0) {
834 vfs_mount_error(mp, "illegal readahead");
838 ret = sscanf(opt, "%d", &args.readahead);
839 if (ret != 1 || args.readahead <= 0) {
840 vfs_mount_error(mp, "illegal readahead: %s",
845 args.flags |= NFSMNT_READAHEAD;
847 if (vfs_getopt(mp->mnt_optnew, "wsize", (void **)&opt, NULL) == 0) {
849 vfs_mount_error(mp, "illegal wsize");
853 ret = sscanf(opt, "%d", &args.wsize);
854 if (ret != 1 || args.wsize <= 0) {
855 vfs_mount_error(mp, "illegal wsize: %s",
860 args.flags |= NFSMNT_WSIZE;
862 if (vfs_getopt(mp->mnt_optnew, "rsize", (void **)&opt, NULL) == 0) {
864 vfs_mount_error(mp, "illegal rsize");
868 ret = sscanf(opt, "%d", &args.rsize);
869 if (ret != 1 || args.rsize <= 0) {
870 vfs_mount_error(mp, "illegal wsize: %s",
875 args.flags |= NFSMNT_RSIZE;
877 if (vfs_getopt(mp->mnt_optnew, "retrans", (void **)&opt, NULL) == 0) {
879 vfs_mount_error(mp, "illegal retrans");
883 ret = sscanf(opt, "%d", &args.retrans);
884 if (ret != 1 || args.retrans <= 0) {
885 vfs_mount_error(mp, "illegal retrans: %s",
890 args.flags |= NFSMNT_RETRANS;
892 if (vfs_getopt(mp->mnt_optnew, "acregmin", (void **)&opt, NULL) == 0) {
893 ret = sscanf(opt, "%d", &args.acregmin);
894 if (ret != 1 || args.acregmin < 0) {
895 vfs_mount_error(mp, "illegal acregmin: %s",
900 args.flags |= NFSMNT_ACREGMIN;
902 if (vfs_getopt(mp->mnt_optnew, "acregmax", (void **)&opt, NULL) == 0) {
903 ret = sscanf(opt, "%d", &args.acregmax);
904 if (ret != 1 || args.acregmax < 0) {
905 vfs_mount_error(mp, "illegal acregmax: %s",
910 args.flags |= NFSMNT_ACREGMAX;
912 if (vfs_getopt(mp->mnt_optnew, "acdirmin", (void **)&opt, NULL) == 0) {
913 ret = sscanf(opt, "%d", &args.acdirmin);
914 if (ret != 1 || args.acdirmin < 0) {
915 vfs_mount_error(mp, "illegal acdirmin: %s",
920 args.flags |= NFSMNT_ACDIRMIN;
922 if (vfs_getopt(mp->mnt_optnew, "acdirmax", (void **)&opt, NULL) == 0) {
923 ret = sscanf(opt, "%d", &args.acdirmax);
924 if (ret != 1 || args.acdirmax < 0) {
925 vfs_mount_error(mp, "illegal acdirmax: %s",
930 args.flags |= NFSMNT_ACDIRMAX;
932 if (vfs_getopt(mp->mnt_optnew, "deadthresh", (void **)&opt, NULL) == 0) {
933 ret = sscanf(opt, "%d", &args.deadthresh);
934 if (ret != 1 || args.deadthresh <= 0) {
935 vfs_mount_error(mp, "illegal deadthresh: %s",
940 args.flags |= NFSMNT_DEADTHRESH;
942 if (vfs_getopt(mp->mnt_optnew, "timeout", (void **)&opt, NULL) == 0) {
943 ret = sscanf(opt, "%d", &args.timeo);
944 if (ret != 1 || args.timeo <= 0) {
945 vfs_mount_error(mp, "illegal timeout: %s",
950 args.flags |= NFSMNT_TIMEO;
952 if (vfs_getopt(mp->mnt_optnew, "maxgroups", (void **)&opt, NULL) == 0) {
953 ret = sscanf(opt, "%d", &args.maxgrouplist);
954 if (ret != 1 || args.timeo <= 0) {
955 vfs_mount_error(mp, "illegal maxgroups: %s",
960 args.flags |= NFSMNT_MAXGRPS;
962 if (vfs_getopt(mp->mnt_optnew, "addr", (void **)&args.addr,
963 &args.addrlen) == 0) {
965 if (args.addrlen > SOCK_MAXADDRLEN) {
966 error = ENAMETOOLONG;
969 MALLOC(nam, struct sockaddr *, args.addrlen, M_SONAME,
971 bcopy(args.addr, nam, args.addrlen);
972 nam->sa_len = args.addrlen;
974 if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh,
975 &args.fhsize) == 0) {
978 if (vfs_getopt(mp->mnt_optnew, "hostname", (void **)&args.hostname,
980 has_hostname_opt = 1;
982 if (args.hostname == NULL) {
983 vfs_mount_error(mp, "Invalid hostname");
987 if (mp->mnt_flag & MNT_UPDATE) {
988 struct nfsmount *nmp = VFSTONFS(mp);
995 * When doing an update, we can't change from or to
996 * v3, switch lockd strategies or change cookie translation
998 args.flags = (args.flags &
999 ~(NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) |
1001 (NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
1002 nfs_decode_args(mp, nmp, &args, NULL);
1007 * Make the nfs_ip_paranoia sysctl serve as the default connection
1008 * or no-connection mode for those protocols that support
1009 * no-connection mode (the flag will be cleared later for protocols
1010 * that do not support no-connection mode). This will allow a client
1011 * to receive replies from a different IP then the request was
1012 * sent to. Note: default value for nfs_ip_paranoia is 1 (paranoid),
1015 if (nfs_ip_paranoia == 0)
1016 args.flags |= NFSMNT_NOCONN;
1018 if (has_nfs_args_opt) {
1020 * In the 'nfs_args' case, the pointers in the args
1021 * structure are in userland - we copy them in here.
1024 error = copyin((caddr_t)args.fh, (caddr_t)nfh,
1031 if (!has_hostname_opt) {
1032 error = copyinstr(args.hostname, hst, MNAMELEN-1, &len);
1036 bzero(&hst[len], MNAMELEN - len);
1037 args.hostname = hst;
1039 if (!has_addr_opt) {
1040 /* sockargs() call must be after above copyin() calls */
1041 error = getsockaddr(&nam, (caddr_t)args.addr,
1048 error = mountnfs(&args, mp, nam, args.hostname, &vp, td->td_ucred);
1052 mp->mnt_kern_flag |= (MNTK_MPSAFE|MNTK_LOOKUP_SHARED);
1063 * It seems a bit dumb to copyinstr() the host and path here and then
1064 * bcopy() them in mountnfs(), but I wanted to detect errors before
1065 * doing the sockargs() call because sockargs() allocates an mbuf and
1066 * an error after that means that I have to release the mbuf.
1070 nfs_cmount(struct mntarg *ma, void *data, int flags, struct thread *td)
1073 struct nfs_args args;
1075 error = copyin(data, &args, sizeof (struct nfs_args));
1079 ma = mount_arg(ma, "nfs_args", &args, sizeof args);
1081 error = kernel_mount(ma, flags);
1086 * Common code for mount and mountroot
1089 mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
1090 char *hst, struct vnode **vpp, struct ucred *cred)
1092 struct nfsmount *nmp;
1097 if (mp->mnt_flag & MNT_UPDATE) {
1099 /* update paths, file handles, etc, here XXX */
1100 FREE(nam, M_SONAME);
1103 nmp = uma_zalloc(nfsmount_zone, M_WAITOK);
1104 bzero((caddr_t)nmp, sizeof (struct nfsmount));
1105 TAILQ_INIT(&nmp->nm_bufq);
1106 mp->mnt_data = (qaddr_t)nmp;
1109 nmp->nm_mountp = mp;
1110 mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF);
1113 * V2 can only handle 32 bit filesizes. A 4GB-1 limit may be too
1114 * high, depending on whether we end up with negative offsets in
1115 * the client or server somewhere. 2GB-1 may be safer.
1117 * For V3, nfs_fsinfo will adjust this as necessary. Assume maximum
1118 * that we can handle until we find out otherwise.
1119 * XXX Our "safe" limit on the client is what we can store in our
1120 * buffer cache using signed(!) block numbers.
1122 if ((argp->flags & NFSMNT_NFSV3) == 0)
1123 nmp->nm_maxfilesize = 0xffffffffLL;
1125 nmp->nm_maxfilesize = (u_int64_t)0x80000000 * DEV_BSIZE - 1;
1127 nmp->nm_timeo = NFS_TIMEO;
1128 nmp->nm_retry = NFS_RETRANS;
1129 if ((argp->flags & NFSMNT_NFSV3) && argp->sotype == SOCK_STREAM) {
1130 nmp->nm_wsize = nmp->nm_rsize = NFS_MAXDATA;
1132 nmp->nm_wsize = NFS_WSIZE;
1133 nmp->nm_rsize = NFS_RSIZE;
1135 nmp->nm_wcommitsize = hibufspace / (desiredvnodes / 1000);
1136 nmp->nm_readdirsize = NFS_READDIRSIZE;
1137 nmp->nm_numgrps = NFS_MAXGRPS;
1138 nmp->nm_readahead = NFS_DEFRAHEAD;
1139 nmp->nm_deadthresh = NFS_MAXDEADTHRESH;
1140 nmp->nm_tprintf_delay = nfs_tprintf_delay;
1141 if (nmp->nm_tprintf_delay < 0)
1142 nmp->nm_tprintf_delay = 0;
1143 nmp->nm_tprintf_initial_delay = nfs_tprintf_initial_delay;
1144 if (nmp->nm_tprintf_initial_delay < 0)
1145 nmp->nm_tprintf_initial_delay = 0;
1146 nmp->nm_fhsize = argp->fhsize;
1147 bcopy((caddr_t)argp->fh, (caddr_t)nmp->nm_fh, argp->fhsize);
1148 bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);
1150 /* Set up the sockets and per-host congestion */
1151 nmp->nm_sotype = argp->sotype;
1152 nmp->nm_soproto = argp->proto;
1153 nmp->nm_rpcops = &nfs_rpcops;
1155 nfs_decode_args(mp, nmp, argp, hst);
1158 * For Connection based sockets (TCP,...) defer the connect until
1159 * the first request, in case the server is not responding.
1161 if (nmp->nm_sotype == SOCK_DGRAM &&
1162 (error = nfs_connect(nmp, NULL)))
1166 * This is silly, but it has to be set so that vinifod() works.
1167 * We do not want to do an nfs_statfs() here since we can get
1168 * stuck on a dead server and we are holding a lock on the mount
1171 mtx_lock(&nmp->nm_mtx);
1172 mp->mnt_stat.f_iosize = nfs_iosize(nmp);
1173 mtx_unlock(&nmp->nm_mtx);
1175 * A reference count is needed on the nfsnode representing the
1176 * remote root. If this object is not persistent, then backward
1177 * traversals of the mount point (i.e. "..") will not work if
1178 * the nfsnode gets flushed out of the cache. Ufs does not have
1179 * this problem, because one can identify root inodes by their
1180 * number == ROOTINO (2).
1182 error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
1188 * Get file attributes and transfer parameters for the
1189 * mountpoint. This has the side effect of filling in
1190 * (*vpp)->v_type with the correct value.
1192 if (argp->flags & NFSMNT_NFSV3)
1193 nfs_fsinfo(nmp, *vpp, curthread->td_ucred, curthread);
1195 VOP_GETATTR(*vpp, &attrs, curthread->td_ucred, curthread);
1198 * Lose the lock but keep the ref.
1200 VOP_UNLOCK(*vpp, 0, curthread);
1204 nfs_disconnect(nmp);
1205 mtx_destroy(&nmp->nm_mtx);
1206 uma_zfree(nfsmount_zone, nmp);
1207 FREE(nam, M_SONAME);
1212 * unmount system call
1215 nfs_unmount(struct mount *mp, int mntflags, struct thread *td)
1217 struct nfsmount *nmp;
1218 int error, flags = 0;
1220 if (mntflags & MNT_FORCE)
1221 flags |= FORCECLOSE;
1224 * Goes something like this..
1225 * - Call vflush() to clear out vnodes for this filesystem
1226 * - Close the socket
1227 * - Free up the data structures
1229 /* In the forced case, cancel any outstanding requests. */
1230 if (flags & FORCECLOSE) {
1231 error = nfs_nmcancelreqs(nmp);
1235 /* We hold 1 extra ref on the root vnode; see comment in mountnfs(). */
1236 error = vflush(mp, 1, flags, td);
1241 * We are now committed to the unmount.
1243 nfs_disconnect(nmp);
1244 FREE(nmp->nm_nam, M_SONAME);
1246 mtx_destroy(&nmp->nm_mtx);
1247 uma_zfree(nfsmount_zone, nmp);
1253 * Return root of a filesystem
1256 nfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td)
1259 struct nfsmount *nmp;
1264 error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, flags);
1269 * Get transfer parameters and attributes for root vnode once.
1271 mtx_lock(&nmp->nm_mtx);
1272 if ((nmp->nm_state & NFSSTA_GOTFSINFO) == 0 &&
1273 (nmp->nm_flag & NFSMNT_NFSV3)) {
1274 mtx_unlock(&nmp->nm_mtx);
1275 nfs_fsinfo(nmp, vp, curthread->td_ucred, curthread);
1277 mtx_unlock(&nmp->nm_mtx);
1278 if (vp->v_type == VNON)
1280 vp->v_vflag |= VV_ROOT;
1286 * Flush out the buffer cache
1290 nfs_sync(struct mount *mp, int waitfor, struct thread *td)
1292 struct vnode *vp, *mvp;
1293 int error, allerror = 0;
1296 * Force stale buffer cache information to be flushed.
1300 MNT_VNODE_FOREACH(vp, mp, mvp) {
1303 if (VOP_ISLOCKED(vp, NULL) ||
1304 vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
1305 waitfor == MNT_LAZY) {
1310 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
1312 MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp);
1315 error = VOP_FSYNC(vp, waitfor, td);
1318 VOP_UNLOCK(vp, 0, td);
1328 nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req)
1330 struct nfsmount *nmp = VFSTONFS(mp);
1334 bzero(&vq, sizeof(vq));
1337 case VFS_CTL_NOLOCKS:
1338 val = (nmp->nm_flag & NFSMNT_NOLOCKS) ? 1 : 0;
1339 if (req->oldptr != NULL) {
1340 error = SYSCTL_OUT(req, &val, sizeof(val));
1344 if (req->newptr != NULL) {
1345 error = SYSCTL_IN(req, &val, sizeof(val));
1349 nmp->nm_flag |= NFSMNT_NOLOCKS;
1351 nmp->nm_flag &= ~NFSMNT_NOLOCKS;
1356 mtx_lock(&nmp->nm_mtx);
1357 if (nmp->nm_state & NFSSTA_TIMEO)
1358 vq.vq_flags |= VQ_NOTRESP;
1359 mtx_unlock(&nmp->nm_mtx);
1361 if (!(nmp->nm_flag & NFSMNT_NOLOCKS) &&
1362 (nmp->nm_state & NFSSTA_LOCKTIMEO))
1363 vq.vq_flags |= VQ_NOTRESPLOCK;
1365 error = SYSCTL_OUT(req, &vq, sizeof(vq));
1368 if (req->oldptr != NULL) {
1369 error = SYSCTL_OUT(req, &nmp->nm_tprintf_initial_delay,
1370 sizeof(nmp->nm_tprintf_initial_delay));
1374 if (req->newptr != NULL) {
1375 error = vfs_suser(mp, req->td);
1378 error = SYSCTL_IN(req, &nmp->nm_tprintf_initial_delay,
1379 sizeof(nmp->nm_tprintf_initial_delay));
1382 if (nmp->nm_tprintf_initial_delay < 0)
1383 nmp->nm_tprintf_initial_delay = 0;