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>
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>
71 #include <nfs/nfsproto.h>
72 #include <nfsclient/nfs.h>
73 #include <nfsclient/nfsnode.h>
74 #include <nfsclient/nfsmount.h>
75 #include <nfs/xdr_subs.h>
76 #include <nfsclient/nfsm_subs.h>
77 #include <nfsclient/nfsdiskless.h>
79 MALLOC_DEFINE(M_NFSREQ, "nfsclient_req", "NFS request header");
80 MALLOC_DEFINE(M_NFSBIGFH, "nfsclient_bigfh", "NFS version 3 file handle");
81 MALLOC_DEFINE(M_NFSDIROFF, "nfsclient_diroff", "NFS directory offset data");
82 MALLOC_DEFINE(M_NFSHASH, "nfsclient_hash", "NFS hash tables");
83 MALLOC_DEFINE(M_NFSDIRECTIO, "nfsclient_directio", "NFS Direct IO async write state");
85 uma_zone_t nfsmount_zone;
87 struct nfsstats nfsstats;
89 SYSCTL_NODE(_vfs, OID_AUTO, nfs, CTLFLAG_RW, 0, "NFS filesystem");
90 SYSCTL_STRUCT(_vfs_nfs, NFS_NFSSTATS, nfsstats, CTLFLAG_RW,
91 &nfsstats, nfsstats, "S,nfsstats");
92 static int nfs_ip_paranoia = 1;
93 SYSCTL_INT(_vfs_nfs, OID_AUTO, nfs_ip_paranoia, CTLFLAG_RW,
95 "Disallow accepting replies from IPs which differ from those sent");
98 SYSCTL_INT(_vfs_nfs, OID_AUTO, debug, CTLFLAG_RW, &nfs_debug, 0,
101 static int nfs_tprintf_initial_delay = NFS_TPRINTF_INITIAL_DELAY;
102 SYSCTL_INT(_vfs_nfs, NFS_TPRINTF_INITIAL_DELAY,
103 downdelayinitial, CTLFLAG_RW, &nfs_tprintf_initial_delay, 0,
104 "Delay before printing \"nfs server not responding\" messages");
105 /* how long between console messages "nfs server foo not responding" */
106 static int nfs_tprintf_delay = NFS_TPRINTF_DELAY;
107 SYSCTL_INT(_vfs_nfs, NFS_TPRINTF_DELAY,
108 downdelayinterval, CTLFLAG_RW, &nfs_tprintf_delay, 0,
109 "Delay between printing \"nfs server not responding\" messages");
111 static void nfs_decode_args(struct mount *mp, struct nfsmount *nmp,
112 struct nfs_args *argp, const char *hostname);
113 static int mountnfs(struct nfs_args *, struct mount *,
114 struct sockaddr *, char *, struct vnode **,
116 static vfs_mount_t nfs_mount;
117 static vfs_cmount_t nfs_cmount;
118 static vfs_unmount_t nfs_unmount;
119 static vfs_root_t nfs_root;
120 static vfs_statfs_t nfs_statfs;
121 static vfs_sync_t nfs_sync;
122 static vfs_sysctl_t nfs_sysctl;
124 static int fake_wchan;
127 * nfs vfs operations.
129 static struct vfsops nfs_vfsops = {
130 .vfs_init = nfs_init,
131 .vfs_mount = nfs_mount,
132 .vfs_cmount = nfs_cmount,
133 .vfs_root = nfs_root,
134 .vfs_statfs = nfs_statfs,
135 .vfs_sync = nfs_sync,
136 .vfs_uninit = nfs_uninit,
137 .vfs_unmount = nfs_unmount,
138 .vfs_sysctl = nfs_sysctl,
140 VFS_SET(nfs_vfsops, nfs, VFCF_NETWORK);
142 /* So that loader and kldload(2) can find us, wherever we are.. */
143 MODULE_VERSION(nfs, 1);
144 MODULE_DEPEND(nfs, krpc, 1, 1, 1);
146 MODULE_DEPEND(nfs, kgssapi, 1, 1, 1);
149 static struct nfs_rpcops nfs_rpcops = {
159 * This structure must be filled in by a primary bootstrap or bootstrap
160 * server for a diskless/dataless machine. It is initialized below just
161 * to ensure that it is allocated to initialized data (.data not .bss).
163 struct nfs_diskless nfs_diskless = { { { 0 } } };
164 struct nfsv3_diskless nfsv3_diskless = { { { 0 } } };
165 int nfs_diskless_valid = 0;
167 SYSCTL_INT(_vfs_nfs, OID_AUTO, diskless_valid, CTLFLAG_RD,
168 &nfs_diskless_valid, 0,
169 "Has the diskless struct been filled correctly");
171 SYSCTL_STRING(_vfs_nfs, OID_AUTO, diskless_rootpath, CTLFLAG_RD,
172 nfsv3_diskless.root_hostnam, 0, "Path to nfs root");
174 SYSCTL_OPAQUE(_vfs_nfs, OID_AUTO, diskless_rootaddr, CTLFLAG_RD,
175 &nfsv3_diskless.root_saddr, sizeof nfsv3_diskless.root_saddr,
176 "%Ssockaddr_in", "Diskless root nfs address");
179 void nfsargs_ntoh(struct nfs_args *);
180 static int nfs_mountdiskless(char *,
181 struct sockaddr_in *, struct nfs_args *,
182 struct thread *, struct vnode **, struct mount *);
183 static void nfs_convert_diskless(void);
184 static void nfs_convert_oargs(struct nfs_args *args,
185 struct onfs_args *oargs);
188 nfs_iosize(struct nfsmount *nmp)
193 * Calculate the size used for io buffers. Use the larger
194 * of the two sizes to minimise nfs requests but make sure
195 * that it is at least one VM page to avoid wasting buffer
198 iosize = imax(nmp->nm_rsize, nmp->nm_wsize);
199 iosize = imax(iosize, PAGE_SIZE);
204 nfs_convert_oargs(struct nfs_args *args, struct onfs_args *oargs)
207 args->version = NFS_ARGSVERSION;
208 args->addr = oargs->addr;
209 args->addrlen = oargs->addrlen;
210 args->sotype = oargs->sotype;
211 args->proto = oargs->proto;
212 args->fh = oargs->fh;
213 args->fhsize = oargs->fhsize;
214 args->flags = oargs->flags;
215 args->wsize = oargs->wsize;
216 args->rsize = oargs->rsize;
217 args->readdirsize = oargs->readdirsize;
218 args->timeo = oargs->timeo;
219 args->retrans = oargs->retrans;
220 args->maxgrouplist = oargs->maxgrouplist;
221 args->readahead = oargs->readahead;
222 args->deadthresh = oargs->deadthresh;
223 args->hostname = oargs->hostname;
227 nfs_convert_diskless(void)
230 bcopy(&nfs_diskless.myif, &nfsv3_diskless.myif,
231 sizeof(struct ifaliasreq));
232 bcopy(&nfs_diskless.mygateway, &nfsv3_diskless.mygateway,
233 sizeof(struct sockaddr_in));
234 nfs_convert_oargs(&nfsv3_diskless.root_args,&nfs_diskless.root_args);
235 if (nfsv3_diskless.root_args.flags & NFSMNT_NFSV3) {
236 nfsv3_diskless.root_fhsize = NFSX_V3FH;
237 bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V3FH);
239 nfsv3_diskless.root_fhsize = NFSX_V2FH;
240 bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V2FH);
242 bcopy(&nfs_diskless.root_saddr,&nfsv3_diskless.root_saddr,
243 sizeof(struct sockaddr_in));
244 bcopy(nfs_diskless.root_hostnam, nfsv3_diskless.root_hostnam, MNAMELEN);
245 nfsv3_diskless.root_time = nfs_diskless.root_time;
246 bcopy(nfs_diskless.my_hostnam, nfsv3_diskless.my_hostnam,
248 nfs_diskless_valid = 3;
255 nfs_statfs(struct mount *mp, struct statfs *sbp)
259 struct nfs_statfs *sfp;
261 struct nfsmount *nmp = VFSTONFS(mp);
262 int error = 0, v3 = (nmp->nm_flag & NFSMNT_NFSV3), retattr;
263 struct mbuf *mreq, *mrep, *md, *mb;
271 error = vfs_busy(mp, MBF_NOWAIT);
274 error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
280 mtx_lock(&nmp->nm_mtx);
281 if (v3 && (nmp->nm_state & NFSSTA_GOTFSINFO) == 0) {
282 mtx_unlock(&nmp->nm_mtx);
283 (void)nfs_fsinfo(nmp, vp, td->td_ucred, td);
285 mtx_unlock(&nmp->nm_mtx);
286 nfsstats.rpccnt[NFSPROC_FSSTAT]++;
287 mreq = nfsm_reqhead(vp, NFSPROC_FSSTAT, NFSX_FH(v3));
289 bpos = mtod(mb, caddr_t);
291 nfsm_request(vp, NFSPROC_FSSTAT, td, td->td_ucred);
293 nfsm_postop_attr(vp, retattr);
299 sfp = nfsm_dissect(struct nfs_statfs *, NFSX_STATFS(v3));
300 mtx_lock(&nmp->nm_mtx);
301 sbp->f_iosize = nfs_iosize(nmp);
302 mtx_unlock(&nmp->nm_mtx);
304 sbp->f_bsize = NFS_FABLKSIZE;
305 tquad = fxdr_hyper(&sfp->sf_tbytes);
306 sbp->f_blocks = tquad / NFS_FABLKSIZE;
307 tquad = fxdr_hyper(&sfp->sf_fbytes);
308 sbp->f_bfree = tquad / NFS_FABLKSIZE;
309 tquad = fxdr_hyper(&sfp->sf_abytes);
310 sbp->f_bavail = tquad / NFS_FABLKSIZE;
311 sbp->f_files = (fxdr_unsigned(int32_t,
312 sfp->sf_tfiles.nfsuquad[1]) & 0x7fffffff);
313 sbp->f_ffree = (fxdr_unsigned(int32_t,
314 sfp->sf_ffiles.nfsuquad[1]) & 0x7fffffff);
316 sbp->f_bsize = fxdr_unsigned(int32_t, sfp->sf_bsize);
317 sbp->f_blocks = fxdr_unsigned(int32_t, sfp->sf_blocks);
318 sbp->f_bfree = fxdr_unsigned(int32_t, sfp->sf_bfree);
319 sbp->f_bavail = fxdr_unsigned(int32_t, sfp->sf_bavail);
331 * nfs version 3 fsinfo rpc call
334 nfs_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct ucred *cred,
337 struct nfsv3_fsinfo *fsp;
340 int error = 0, retattr;
341 struct mbuf *mreq, *mrep, *md, *mb;
344 nfsstats.rpccnt[NFSPROC_FSINFO]++;
345 mreq = nfsm_reqhead(vp, NFSPROC_FSINFO, NFSX_FH(1));
347 bpos = mtod(mb, caddr_t);
349 nfsm_request(vp, NFSPROC_FSINFO, td, cred);
350 nfsm_postop_attr(vp, retattr);
352 fsp = nfsm_dissect(struct nfsv3_fsinfo *, NFSX_V3FSINFO);
353 pref = fxdr_unsigned(u_int32_t, fsp->fs_wtpref);
354 mtx_lock(&nmp->nm_mtx);
355 if (pref < nmp->nm_wsize && pref >= NFS_FABLKSIZE)
356 nmp->nm_wsize = (pref + NFS_FABLKSIZE - 1) &
357 ~(NFS_FABLKSIZE - 1);
358 max = fxdr_unsigned(u_int32_t, fsp->fs_wtmax);
359 if (max < nmp->nm_wsize && max > 0) {
360 nmp->nm_wsize = max & ~(NFS_FABLKSIZE - 1);
361 if (nmp->nm_wsize == 0)
364 pref = fxdr_unsigned(u_int32_t, fsp->fs_rtpref);
365 if (pref < nmp->nm_rsize && pref >= NFS_FABLKSIZE)
366 nmp->nm_rsize = (pref + NFS_FABLKSIZE - 1) &
367 ~(NFS_FABLKSIZE - 1);
368 max = fxdr_unsigned(u_int32_t, fsp->fs_rtmax);
369 if (max < nmp->nm_rsize && max > 0) {
370 nmp->nm_rsize = max & ~(NFS_FABLKSIZE - 1);
371 if (nmp->nm_rsize == 0)
374 pref = fxdr_unsigned(u_int32_t, fsp->fs_dtpref);
375 if (pref < nmp->nm_readdirsize && pref >= NFS_DIRBLKSIZ)
376 nmp->nm_readdirsize = (pref + NFS_DIRBLKSIZ - 1) &
377 ~(NFS_DIRBLKSIZ - 1);
378 if (max < nmp->nm_readdirsize && max > 0) {
379 nmp->nm_readdirsize = max & ~(NFS_DIRBLKSIZ - 1);
380 if (nmp->nm_readdirsize == 0)
381 nmp->nm_readdirsize = max;
383 maxfsize = fxdr_hyper(&fsp->fs_maxfilesize);
384 if (maxfsize > 0 && maxfsize < nmp->nm_maxfilesize)
385 nmp->nm_maxfilesize = maxfsize;
386 nmp->nm_mountp->mnt_stat.f_iosize = nfs_iosize(nmp);
387 nmp->nm_state |= NFSSTA_GOTFSINFO;
388 mtx_unlock(&nmp->nm_mtx);
396 * Mount a remote root fs via. nfs. This depends on the info in the
397 * nfs_diskless structure that has been filled in properly by some primary
399 * It goes something like this:
400 * - do enough of "ifconfig" by calling ifioctl() so that the system
401 * can talk to the server
402 * - If nfs_diskless.mygateway is filled in, use that address as
404 * - build the rootfs mount point and call mountnfs() to do the rest.
406 * It is assumed to be safe to read, modify, and write the nfsv3_diskless
407 * structure, as well as other global NFS client variables here, as
408 * nfs_mountroot() will be called once in the boot before any other NFS
409 * client activity occurs.
412 nfs_mountroot(struct mount *mp)
414 struct thread *td = curthread;
415 struct nfsv3_diskless *nd = &nfsv3_diskless;
424 #if defined(BOOTP_NFSROOT) && defined(BOOTP)
425 bootpc_init(); /* use bootp to get nfs_diskless filled in */
426 #elif defined(NFS_ROOT)
427 nfs_setup_diskless();
430 if (nfs_diskless_valid == 0)
432 if (nfs_diskless_valid == 1)
433 nfs_convert_diskless();
436 * XXX splnet, so networks will receive...
441 * Do enough of ifconfig(8) so that the critical net interface can
442 * talk to the server.
444 error = socreate(nd->myif.ifra_addr.sa_family, &so, nd->root_args.sotype, 0,
447 panic("nfs_mountroot: socreate(%04x): %d",
448 nd->myif.ifra_addr.sa_family, error);
450 #if 0 /* XXX Bad idea */
452 * We might not have been told the right interface, so we pass
453 * over the first ten interfaces of the same kind, until we get
454 * one of them configured.
457 for (i = strlen(nd->myif.ifra_name) - 1;
458 nd->myif.ifra_name[i] >= '0' &&
459 nd->myif.ifra_name[i] <= '9';
460 nd->myif.ifra_name[i] ++) {
461 error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
466 error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
468 panic("nfs_mountroot: SIOCAIFADDR: %d", error);
469 if ((cp = getenv("boot.netif.mtu")) != NULL) {
470 ir.ifr_mtu = strtol(cp, NULL, 10);
471 bcopy(nd->myif.ifra_name, ir.ifr_name, IFNAMSIZ);
473 error = ifioctl(so, SIOCSIFMTU, (caddr_t)&ir, td);
475 printf("nfs_mountroot: SIOCSIFMTU: %d", error);
480 * If the gateway field is filled in, set it as the default route.
481 * Note that pxeboot will set a default route of 0 if the route
482 * is not set by the DHCP server. Check also for a value of 0
483 * to avoid panicking inappropriately in that situation.
485 if (nd->mygateway.sin_len != 0 &&
486 nd->mygateway.sin_addr.s_addr != 0) {
487 struct sockaddr_in mask, sin;
489 bzero((caddr_t)&mask, sizeof(mask));
491 sin.sin_family = AF_INET;
492 sin.sin_len = sizeof(sin);
493 /* XXX MRT use table 0 for this sort of thing */
494 error = rtrequest(RTM_ADD, (struct sockaddr *)&sin,
495 (struct sockaddr *)&nd->mygateway,
496 (struct sockaddr *)&mask,
497 RTF_UP | RTF_GATEWAY, NULL);
499 panic("nfs_mountroot: RTM_ADD: %d", error);
503 * Create the rootfs mount point.
505 nd->root_args.fh = nd->root_fh;
506 nd->root_args.fhsize = nd->root_fhsize;
507 l = ntohl(nd->root_saddr.sin_addr.s_addr);
508 snprintf(buf, sizeof(buf), "%ld.%ld.%ld.%ld:%s",
509 (l >> 24) & 0xff, (l >> 16) & 0xff,
510 (l >> 8) & 0xff, (l >> 0) & 0xff, nd->root_hostnam);
511 printf("NFS ROOT: %s\n", buf);
512 nd->root_args.hostname = buf;
513 if ((error = nfs_mountdiskless(buf,
514 &nd->root_saddr, &nd->root_args, td, &vp, mp)) != 0) {
519 * This is not really an nfs issue, but it is much easier to
520 * set hostname here and then let the "/etc/rc.xxx" files
521 * mount the right /var based upon its preset value.
523 mtx_lock(&prison0.pr_mtx);
524 strlcpy(prison0.pr_hostname, nd->my_hostnam,
525 sizeof (prison0.pr_hostname));
526 mtx_unlock(&prison0.pr_mtx);
527 inittodr(ntohl(nd->root_time));
532 * Internal version of mount system call for diskless setup.
535 nfs_mountdiskless(char *path,
536 struct sockaddr_in *sin, struct nfs_args *args, struct thread *td,
537 struct vnode **vpp, struct mount *mp)
539 struct sockaddr *nam;
542 nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK);
543 if ((error = mountnfs(args, mp, nam, path, vpp,
544 td->td_ucred)) != 0) {
545 printf("nfs_mountroot: mount %s on /: %d\n", path, error);
552 nfs_sec_name_to_num(char *sec)
554 if (!strcmp(sec, "krb5"))
555 return (RPCSEC_GSS_KRB5);
556 if (!strcmp(sec, "krb5i"))
557 return (RPCSEC_GSS_KRB5I);
558 if (!strcmp(sec, "krb5p"))
559 return (RPCSEC_GSS_KRB5P);
560 if (!strcmp(sec, "sys"))
563 * Userland should validate the string but we will try and
564 * cope with unexpected values.
570 nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
571 const char *hostname)
583 * Set read-only flag if requested; otherwise, clear it if this is
584 * an update. If this is not an update, then either the read-only
585 * flag is already clear, or this is a root mount and it was set
586 * intentionally at some previous point.
588 if (vfs_getopt(mp->mnt_optnew, "ro", NULL, NULL) == 0) {
590 mp->mnt_flag |= MNT_RDONLY;
592 } else if (mp->mnt_flag & MNT_UPDATE) {
594 mp->mnt_flag &= ~MNT_RDONLY;
599 * Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes
600 * no sense in that context. Also, set up appropriate retransmit
601 * and soft timeout behavior.
603 if (argp->sotype == SOCK_STREAM) {
604 nmp->nm_flag &= ~NFSMNT_NOCONN;
605 nmp->nm_flag |= NFSMNT_DUMBTIMR;
606 nmp->nm_timeo = NFS_MAXTIMEO;
607 nmp->nm_retry = NFS_RETRANS_TCP;
610 /* Also clear RDIRPLUS if not NFSv3, it crashes some servers */
611 if ((argp->flags & NFSMNT_NFSV3) == 0)
612 nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
614 /* Re-bind if rsrvd port requested and wasn't on one */
615 adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT)
616 && (argp->flags & NFSMNT_RESVPORT);
617 /* Also re-bind if we're switching to/from a connected UDP socket */
618 adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) !=
619 (argp->flags & NFSMNT_NOCONN));
621 /* Update flags atomically. Don't change the lock bits. */
622 nmp->nm_flag = argp->flags | nmp->nm_flag;
625 if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) {
626 nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10;
627 if (nmp->nm_timeo < NFS_MINTIMEO)
628 nmp->nm_timeo = NFS_MINTIMEO;
629 else if (nmp->nm_timeo > NFS_MAXTIMEO)
630 nmp->nm_timeo = NFS_MAXTIMEO;
633 if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) {
634 nmp->nm_retry = argp->retrans;
635 if (nmp->nm_retry > NFS_MAXREXMIT)
636 nmp->nm_retry = NFS_MAXREXMIT;
639 if (argp->flags & NFSMNT_NFSV3) {
640 if (argp->sotype == SOCK_DGRAM)
641 maxio = NFS_MAXDGRAMDATA;
645 maxio = NFS_V2MAXDATA;
647 if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) {
648 nmp->nm_wsize = argp->wsize;
649 /* Round down to multiple of blocksize */
650 nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1);
651 if (nmp->nm_wsize <= 0)
652 nmp->nm_wsize = NFS_FABLKSIZE;
654 if (nmp->nm_wsize > maxio)
655 nmp->nm_wsize = maxio;
656 if (nmp->nm_wsize > MAXBSIZE)
657 nmp->nm_wsize = MAXBSIZE;
659 if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) {
660 nmp->nm_rsize = argp->rsize;
661 /* Round down to multiple of blocksize */
662 nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1);
663 if (nmp->nm_rsize <= 0)
664 nmp->nm_rsize = NFS_FABLKSIZE;
666 if (nmp->nm_rsize > maxio)
667 nmp->nm_rsize = maxio;
668 if (nmp->nm_rsize > MAXBSIZE)
669 nmp->nm_rsize = MAXBSIZE;
671 if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) {
672 nmp->nm_readdirsize = argp->readdirsize;
674 if (nmp->nm_readdirsize > maxio)
675 nmp->nm_readdirsize = maxio;
676 if (nmp->nm_readdirsize > nmp->nm_rsize)
677 nmp->nm_readdirsize = nmp->nm_rsize;
679 if ((argp->flags & NFSMNT_ACREGMIN) && argp->acregmin >= 0)
680 nmp->nm_acregmin = argp->acregmin;
682 nmp->nm_acregmin = NFS_MINATTRTIMO;
683 if ((argp->flags & NFSMNT_ACREGMAX) && argp->acregmax >= 0)
684 nmp->nm_acregmax = argp->acregmax;
686 nmp->nm_acregmax = NFS_MAXATTRTIMO;
687 if ((argp->flags & NFSMNT_ACDIRMIN) && argp->acdirmin >= 0)
688 nmp->nm_acdirmin = argp->acdirmin;
690 nmp->nm_acdirmin = NFS_MINDIRATTRTIMO;
691 if ((argp->flags & NFSMNT_ACDIRMAX) && argp->acdirmax >= 0)
692 nmp->nm_acdirmax = argp->acdirmax;
694 nmp->nm_acdirmax = NFS_MAXDIRATTRTIMO;
695 if (nmp->nm_acdirmin > nmp->nm_acdirmax)
696 nmp->nm_acdirmin = nmp->nm_acdirmax;
697 if (nmp->nm_acregmin > nmp->nm_acregmax)
698 nmp->nm_acregmin = nmp->nm_acregmax;
700 if ((argp->flags & NFSMNT_MAXGRPS) && argp->maxgrouplist >= 0) {
701 if (argp->maxgrouplist <= NFS_MAXGRPS)
702 nmp->nm_numgrps = argp->maxgrouplist;
704 nmp->nm_numgrps = NFS_MAXGRPS;
706 if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0) {
707 if (argp->readahead <= NFS_MAXRAHEAD)
708 nmp->nm_readahead = argp->readahead;
710 nmp->nm_readahead = NFS_MAXRAHEAD;
712 if ((argp->flags & NFSMNT_WCOMMITSIZE) && argp->wcommitsize >= 0) {
713 if (argp->wcommitsize < nmp->nm_wsize)
714 nmp->nm_wcommitsize = nmp->nm_wsize;
716 nmp->nm_wcommitsize = argp->wcommitsize;
718 if ((argp->flags & NFSMNT_DEADTHRESH) && argp->deadthresh >= 0) {
719 if (argp->deadthresh <= NFS_MAXDEADTHRESH)
720 nmp->nm_deadthresh = argp->deadthresh;
722 nmp->nm_deadthresh = NFS_MAXDEADTHRESH;
725 adjsock |= ((nmp->nm_sotype != argp->sotype) ||
726 (nmp->nm_soproto != argp->proto));
727 nmp->nm_sotype = argp->sotype;
728 nmp->nm_soproto = argp->proto;
730 if (nmp->nm_client && adjsock) {
731 nfs_safedisconnect(nmp);
732 if (nmp->nm_sotype == SOCK_DGRAM)
733 while (nfs_connect(nmp)) {
734 printf("nfs_args: retrying connect\n");
735 (void) tsleep(&fake_wchan, PSOCK, "nfscon", hz);
740 strlcpy(nmp->nm_hostname, hostname,
741 sizeof(nmp->nm_hostname));
742 p = strchr(nmp->nm_hostname, ':');
747 if (vfs_getopt(mp->mnt_optnew, "sec",
748 (void **) &secname, NULL) == 0) {
749 nmp->nm_secflavor = nfs_sec_name_to_num(secname);
751 nmp->nm_secflavor = AUTH_SYS;
754 if (vfs_getopt(mp->mnt_optnew, "principal",
755 (void **) &principal, NULL) == 0) {
756 strlcpy(nmp->nm_principal, principal,
757 sizeof(nmp->nm_principal));
759 snprintf(nmp->nm_principal, sizeof(nmp->nm_principal),
760 "nfs@%s", nmp->nm_hostname);
764 static const char *nfs_opts[] = { "from", "nfs_args",
765 "noatime", "noexec", "suiddir", "nosuid", "nosymfollow", "union",
766 "noclusterr", "noclusterw", "multilabel", "acls", "force", "update",
767 "async", "dumbtimer", "noconn", "nolockd", "intr", "rdirplus", "resvport",
768 "readdirsize", "soft", "hard", "mntudp", "tcp", "udp", "wsize", "rsize",
769 "retrans", "acregmin", "acregmax", "acdirmin", "acdirmax",
770 "deadthresh", "hostname", "timeout", "addr", "fh", "nfsv3", "sec",
771 "maxgroups", "principal",
778 * It seems a bit dumb to copyinstr() the host and path here and then
779 * bcopy() them in mountnfs(), but I wanted to detect errors before
780 * doing the sockargs() call because sockargs() allocates an mbuf and
781 * an error after that means that I have to release the mbuf.
785 nfs_mount(struct mount *mp)
787 struct nfs_args args = {
788 .version = NFS_ARGSVERSION,
790 .addrlen = sizeof (struct sockaddr_in),
791 .sotype = SOCK_STREAM,
795 .flags = NFSMNT_RESVPORT,
798 .readdirsize = NFS_READDIRSIZE,
800 .retrans = NFS_RETRANS,
801 .maxgrouplist = NFS_MAXGRPS,
802 .readahead = NFS_DEFRAHEAD,
803 .wcommitsize = 0, /* was: NQ_DEFLEASE */
804 .deadthresh = NFS_MAXDEADTHRESH, /* was: NQ_DEADTHRESH */
807 .acregmin = NFS_MINATTRTIMO,
808 .acregmax = NFS_MAXATTRTIMO,
809 .acdirmin = NFS_MINDIRATTRTIMO,
810 .acdirmax = NFS_MAXDIRATTRTIMO,
812 int error, ret, has_nfs_args_opt;
813 int has_addr_opt, has_fh_opt, has_hostname_opt;
814 struct sockaddr *nam;
818 u_char nfh[NFSX_V3FHMAX];
821 has_nfs_args_opt = 0;
824 has_hostname_opt = 0;
826 if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) {
831 if ((mp->mnt_flag & (MNT_ROOTFS | MNT_UPDATE)) == MNT_ROOTFS) {
832 error = nfs_mountroot(mp);
837 * The old mount_nfs program passed the struct nfs_args
838 * from userspace to kernel. The new mount_nfs program
839 * passes string options via nmount() from userspace to kernel
840 * and we populate the struct nfs_args in the kernel.
842 if (vfs_getopt(mp->mnt_optnew, "nfs_args", NULL, NULL) == 0) {
843 error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args,
848 if (args.version != NFS_ARGSVERSION) {
849 error = EPROGMISMATCH;
852 has_nfs_args_opt = 1;
855 if (vfs_getopt(mp->mnt_optnew, "dumbtimer", NULL, NULL) == 0)
856 args.flags |= NFSMNT_DUMBTIMR;
857 if (vfs_getopt(mp->mnt_optnew, "noconn", NULL, NULL) == 0)
858 args.flags |= NFSMNT_NOCONN;
859 if (vfs_getopt(mp->mnt_optnew, "conn", NULL, NULL) == 0)
860 args.flags |= NFSMNT_NOCONN;
861 if (vfs_getopt(mp->mnt_optnew, "nolockd", NULL, NULL) == 0)
862 args.flags |= NFSMNT_NOLOCKD;
863 if (vfs_getopt(mp->mnt_optnew, "lockd", NULL, NULL) == 0)
864 args.flags &= ~NFSMNT_NOLOCKD;
865 if (vfs_getopt(mp->mnt_optnew, "intr", NULL, NULL) == 0)
866 args.flags |= NFSMNT_INT;
867 if (vfs_getopt(mp->mnt_optnew, "rdirplus", NULL, NULL) == 0)
868 args.flags |= NFSMNT_RDIRPLUS;
869 if (vfs_getopt(mp->mnt_optnew, "resvport", NULL, NULL) == 0)
870 args.flags |= NFSMNT_RESVPORT;
871 if (vfs_getopt(mp->mnt_optnew, "noresvport", NULL, NULL) == 0)
872 args.flags &= ~NFSMNT_RESVPORT;
873 if (vfs_getopt(mp->mnt_optnew, "soft", NULL, NULL) == 0)
874 args.flags |= NFSMNT_SOFT;
875 if (vfs_getopt(mp->mnt_optnew, "hard", NULL, NULL) == 0)
876 args.flags &= ~NFSMNT_SOFT;
877 if (vfs_getopt(mp->mnt_optnew, "mntudp", NULL, NULL) == 0)
878 args.sotype = SOCK_DGRAM;
879 if (vfs_getopt(mp->mnt_optnew, "udp", NULL, NULL) == 0)
880 args.sotype = SOCK_DGRAM;
881 if (vfs_getopt(mp->mnt_optnew, "tcp", NULL, NULL) == 0)
882 args.sotype = SOCK_STREAM;
883 if (vfs_getopt(mp->mnt_optnew, "nfsv3", NULL, NULL) == 0)
884 args.flags |= NFSMNT_NFSV3;
885 if (vfs_getopt(mp->mnt_optnew, "readdirsize", (void **)&opt, NULL) == 0) {
887 vfs_mount_error(mp, "illegal readdirsize");
891 ret = sscanf(opt, "%d", &args.readdirsize);
892 if (ret != 1 || args.readdirsize <= 0) {
893 vfs_mount_error(mp, "illegal readdirsize: %s",
898 args.flags |= NFSMNT_READDIRSIZE;
900 if (vfs_getopt(mp->mnt_optnew, "readahead", (void **)&opt, NULL) == 0) {
902 vfs_mount_error(mp, "illegal readahead");
906 ret = sscanf(opt, "%d", &args.readahead);
907 if (ret != 1 || args.readahead <= 0) {
908 vfs_mount_error(mp, "illegal readahead: %s",
913 args.flags |= NFSMNT_READAHEAD;
915 if (vfs_getopt(mp->mnt_optnew, "wsize", (void **)&opt, NULL) == 0) {
917 vfs_mount_error(mp, "illegal wsize");
921 ret = sscanf(opt, "%d", &args.wsize);
922 if (ret != 1 || args.wsize <= 0) {
923 vfs_mount_error(mp, "illegal wsize: %s",
928 args.flags |= NFSMNT_WSIZE;
930 if (vfs_getopt(mp->mnt_optnew, "rsize", (void **)&opt, NULL) == 0) {
932 vfs_mount_error(mp, "illegal rsize");
936 ret = sscanf(opt, "%d", &args.rsize);
937 if (ret != 1 || args.rsize <= 0) {
938 vfs_mount_error(mp, "illegal wsize: %s",
943 args.flags |= NFSMNT_RSIZE;
945 if (vfs_getopt(mp->mnt_optnew, "retrans", (void **)&opt, NULL) == 0) {
947 vfs_mount_error(mp, "illegal retrans");
951 ret = sscanf(opt, "%d", &args.retrans);
952 if (ret != 1 || args.retrans <= 0) {
953 vfs_mount_error(mp, "illegal retrans: %s",
958 args.flags |= NFSMNT_RETRANS;
960 if (vfs_getopt(mp->mnt_optnew, "acregmin", (void **)&opt, NULL) == 0) {
961 ret = sscanf(opt, "%d", &args.acregmin);
962 if (ret != 1 || args.acregmin < 0) {
963 vfs_mount_error(mp, "illegal acregmin: %s",
968 args.flags |= NFSMNT_ACREGMIN;
970 if (vfs_getopt(mp->mnt_optnew, "acregmax", (void **)&opt, NULL) == 0) {
971 ret = sscanf(opt, "%d", &args.acregmax);
972 if (ret != 1 || args.acregmax < 0) {
973 vfs_mount_error(mp, "illegal acregmax: %s",
978 args.flags |= NFSMNT_ACREGMAX;
980 if (vfs_getopt(mp->mnt_optnew, "acdirmin", (void **)&opt, NULL) == 0) {
981 ret = sscanf(opt, "%d", &args.acdirmin);
982 if (ret != 1 || args.acdirmin < 0) {
983 vfs_mount_error(mp, "illegal acdirmin: %s",
988 args.flags |= NFSMNT_ACDIRMIN;
990 if (vfs_getopt(mp->mnt_optnew, "acdirmax", (void **)&opt, NULL) == 0) {
991 ret = sscanf(opt, "%d", &args.acdirmax);
992 if (ret != 1 || args.acdirmax < 0) {
993 vfs_mount_error(mp, "illegal acdirmax: %s",
998 args.flags |= NFSMNT_ACDIRMAX;
1000 if (vfs_getopt(mp->mnt_optnew, "deadthresh", (void **)&opt, NULL) == 0) {
1001 ret = sscanf(opt, "%d", &args.deadthresh);
1002 if (ret != 1 || args.deadthresh <= 0) {
1003 vfs_mount_error(mp, "illegal deadthresh: %s",
1008 args.flags |= NFSMNT_DEADTHRESH;
1010 if (vfs_getopt(mp->mnt_optnew, "timeout", (void **)&opt, NULL) == 0) {
1011 ret = sscanf(opt, "%d", &args.timeo);
1012 if (ret != 1 || args.timeo <= 0) {
1013 vfs_mount_error(mp, "illegal timeout: %s",
1018 args.flags |= NFSMNT_TIMEO;
1020 if (vfs_getopt(mp->mnt_optnew, "maxgroups", (void **)&opt, NULL) == 0) {
1021 ret = sscanf(opt, "%d", &args.maxgrouplist);
1022 if (ret != 1 || args.timeo <= 0) {
1023 vfs_mount_error(mp, "illegal maxgroups: %s",
1028 args.flags |= NFSMNT_MAXGRPS;
1030 if (vfs_getopt(mp->mnt_optnew, "addr", (void **)&args.addr,
1031 &args.addrlen) == 0) {
1033 if (args.addrlen > SOCK_MAXADDRLEN) {
1034 error = ENAMETOOLONG;
1037 nam = malloc(args.addrlen, M_SONAME,
1039 bcopy(args.addr, nam, args.addrlen);
1040 nam->sa_len = args.addrlen;
1042 if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh,
1043 &args.fhsize) == 0) {
1046 if (vfs_getopt(mp->mnt_optnew, "hostname", (void **)&args.hostname,
1048 has_hostname_opt = 1;
1050 if (args.hostname == NULL) {
1051 vfs_mount_error(mp, "Invalid hostname");
1056 if (mp->mnt_flag & MNT_UPDATE) {
1057 struct nfsmount *nmp = VFSTONFS(mp);
1064 * When doing an update, we can't change from or to
1065 * v3, switch lockd strategies or change cookie translation
1067 args.flags = (args.flags &
1068 ~(NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) |
1070 (NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
1071 nfs_decode_args(mp, nmp, &args, NULL);
1076 * Make the nfs_ip_paranoia sysctl serve as the default connection
1077 * or no-connection mode for those protocols that support
1078 * no-connection mode (the flag will be cleared later for protocols
1079 * that do not support no-connection mode). This will allow a client
1080 * to receive replies from a different IP then the request was
1081 * sent to. Note: default value for nfs_ip_paranoia is 1 (paranoid),
1084 if (nfs_ip_paranoia == 0)
1085 args.flags |= NFSMNT_NOCONN;
1087 if (has_nfs_args_opt) {
1089 * In the 'nfs_args' case, the pointers in the args
1090 * structure are in userland - we copy them in here.
1093 error = copyin((caddr_t)args.fh, (caddr_t)nfh,
1100 if (!has_hostname_opt) {
1101 error = copyinstr(args.hostname, hst, MNAMELEN-1, &len);
1105 bzero(&hst[len], MNAMELEN - len);
1106 args.hostname = hst;
1108 if (!has_addr_opt) {
1109 /* sockargs() call must be after above copyin() calls */
1110 error = getsockaddr(&nam, (caddr_t)args.addr,
1117 error = mountnfs(&args, mp, nam, args.hostname, &vp,
1118 curthread->td_ucred);
1122 mp->mnt_kern_flag |= (MNTK_MPSAFE|MNTK_LOOKUP_SHARED);
1133 * It seems a bit dumb to copyinstr() the host and path here and then
1134 * bcopy() them in mountnfs(), but I wanted to detect errors before
1135 * doing the sockargs() call because sockargs() allocates an mbuf and
1136 * an error after that means that I have to release the mbuf.
1140 nfs_cmount(struct mntarg *ma, void *data, int flags)
1143 struct nfs_args args;
1145 error = copyin(data, &args, sizeof (struct nfs_args));
1149 ma = mount_arg(ma, "nfs_args", &args, sizeof args);
1151 error = kernel_mount(ma, flags);
1156 * Common code for mount and mountroot
1159 mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
1160 char *hst, struct vnode **vpp, struct ucred *cred)
1162 struct nfsmount *nmp;
1167 if (mp->mnt_flag & MNT_UPDATE) {
1169 printf("%s: MNT_UPDATE is no longer handled here\n", __func__);
1170 free(nam, M_SONAME);
1173 nmp = uma_zalloc(nfsmount_zone, M_WAITOK);
1174 bzero((caddr_t)nmp, sizeof (struct nfsmount));
1175 TAILQ_INIT(&nmp->nm_bufq);
1179 nmp->nm_mountp = mp;
1180 mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF);
1183 * V2 can only handle 32 bit filesizes. A 4GB-1 limit may be too
1184 * high, depending on whether we end up with negative offsets in
1185 * the client or server somewhere. 2GB-1 may be safer.
1187 * For V3, nfs_fsinfo will adjust this as necessary. Assume maximum
1188 * that we can handle until we find out otherwise.
1189 * XXX Our "safe" limit on the client is what we can store in our
1190 * buffer cache using signed(!) block numbers.
1192 if ((argp->flags & NFSMNT_NFSV3) == 0)
1193 nmp->nm_maxfilesize = 0xffffffffLL;
1195 nmp->nm_maxfilesize = (u_int64_t)0x80000000 * DEV_BSIZE - 1;
1197 nmp->nm_timeo = NFS_TIMEO;
1198 nmp->nm_retry = NFS_RETRANS;
1199 if ((argp->flags & NFSMNT_NFSV3) && argp->sotype == SOCK_STREAM) {
1200 nmp->nm_wsize = nmp->nm_rsize = NFS_MAXDATA;
1202 nmp->nm_wsize = NFS_WSIZE;
1203 nmp->nm_rsize = NFS_RSIZE;
1205 nmp->nm_wcommitsize = hibufspace / (desiredvnodes / 1000);
1206 nmp->nm_readdirsize = NFS_READDIRSIZE;
1207 nmp->nm_numgrps = NFS_MAXGRPS;
1208 nmp->nm_readahead = NFS_DEFRAHEAD;
1209 nmp->nm_deadthresh = NFS_MAXDEADTHRESH;
1210 nmp->nm_tprintf_delay = nfs_tprintf_delay;
1211 if (nmp->nm_tprintf_delay < 0)
1212 nmp->nm_tprintf_delay = 0;
1213 nmp->nm_tprintf_initial_delay = nfs_tprintf_initial_delay;
1214 if (nmp->nm_tprintf_initial_delay < 0)
1215 nmp->nm_tprintf_initial_delay = 0;
1216 nmp->nm_fhsize = argp->fhsize;
1217 bcopy((caddr_t)argp->fh, (caddr_t)nmp->nm_fh, argp->fhsize);
1218 bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);
1220 /* Set up the sockets and per-host congestion */
1221 nmp->nm_sotype = argp->sotype;
1222 nmp->nm_soproto = argp->proto;
1223 nmp->nm_rpcops = &nfs_rpcops;
1225 nfs_decode_args(mp, nmp, argp, hst);
1228 * For Connection based sockets (TCP,...) defer the connect until
1229 * the first request, in case the server is not responding.
1231 if (nmp->nm_sotype == SOCK_DGRAM &&
1232 (error = nfs_connect(nmp)))
1236 * This is silly, but it has to be set so that vinifod() works.
1237 * We do not want to do an nfs_statfs() here since we can get
1238 * stuck on a dead server and we are holding a lock on the mount
1241 mtx_lock(&nmp->nm_mtx);
1242 mp->mnt_stat.f_iosize = nfs_iosize(nmp);
1243 mtx_unlock(&nmp->nm_mtx);
1245 * A reference count is needed on the nfsnode representing the
1246 * remote root. If this object is not persistent, then backward
1247 * traversals of the mount point (i.e. "..") will not work if
1248 * the nfsnode gets flushed out of the cache. Ufs does not have
1249 * this problem, because one can identify root inodes by their
1250 * number == ROOTINO (2).
1252 error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
1258 * Get file attributes and transfer parameters for the
1259 * mountpoint. This has the side effect of filling in
1260 * (*vpp)->v_type with the correct value.
1262 if (argp->flags & NFSMNT_NFSV3)
1263 nfs_fsinfo(nmp, *vpp, curthread->td_ucred, curthread);
1265 VOP_GETATTR(*vpp, &attrs, curthread->td_ucred);
1268 * Lose the lock but keep the ref.
1270 VOP_UNLOCK(*vpp, 0);
1274 nfs_disconnect(nmp);
1275 mtx_destroy(&nmp->nm_mtx);
1276 uma_zfree(nfsmount_zone, nmp);
1277 free(nam, M_SONAME);
1282 * unmount system call
1285 nfs_unmount(struct mount *mp, int mntflags)
1287 struct nfsmount *nmp;
1288 int error, flags = 0;
1290 if (mntflags & MNT_FORCE)
1291 flags |= FORCECLOSE;
1294 * Goes something like this..
1295 * - Call vflush() to clear out vnodes for this filesystem
1296 * - Close the socket
1297 * - Free up the data structures
1299 /* In the forced case, cancel any outstanding requests. */
1300 if (flags & FORCECLOSE) {
1301 error = nfs_nmcancelreqs(nmp);
1305 /* We hold 1 extra ref on the root vnode; see comment in mountnfs(). */
1306 error = vflush(mp, 1, flags, curthread);
1311 * We are now committed to the unmount.
1313 nfs_disconnect(nmp);
1314 free(nmp->nm_nam, M_SONAME);
1316 mtx_destroy(&nmp->nm_mtx);
1317 uma_zfree(nfsmount_zone, nmp);
1323 * Return root of a filesystem
1326 nfs_root(struct mount *mp, int flags, struct vnode **vpp)
1329 struct nfsmount *nmp;
1334 error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, flags);
1339 * Get transfer parameters and attributes for root vnode once.
1341 mtx_lock(&nmp->nm_mtx);
1342 if ((nmp->nm_state & NFSSTA_GOTFSINFO) == 0 &&
1343 (nmp->nm_flag & NFSMNT_NFSV3)) {
1344 mtx_unlock(&nmp->nm_mtx);
1345 nfs_fsinfo(nmp, vp, curthread->td_ucred, curthread);
1347 mtx_unlock(&nmp->nm_mtx);
1348 if (vp->v_type == VNON)
1350 vp->v_vflag |= VV_ROOT;
1356 * Flush out the buffer cache
1360 nfs_sync(struct mount *mp, int waitfor)
1362 struct vnode *vp, *mvp;
1364 int error, allerror = 0;
1369 * Force stale buffer cache information to be flushed.
1373 MNT_VNODE_FOREACH(vp, mp, mvp) {
1376 /* XXX Racy bv_cnt check. */
1377 if (VOP_ISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
1378 waitfor == MNT_LAZY) {
1383 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
1385 MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp);
1388 error = VOP_FSYNC(vp, waitfor, td);
1401 nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req)
1403 struct nfsmount *nmp = VFSTONFS(mp);
1407 bzero(&vq, sizeof(vq));
1410 case VFS_CTL_NOLOCKS:
1411 val = (nmp->nm_flag & NFSMNT_NOLOCKS) ? 1 : 0;
1412 if (req->oldptr != NULL) {
1413 error = SYSCTL_OUT(req, &val, sizeof(val));
1417 if (req->newptr != NULL) {
1418 error = SYSCTL_IN(req, &val, sizeof(val));
1422 nmp->nm_flag |= NFSMNT_NOLOCKS;
1424 nmp->nm_flag &= ~NFSMNT_NOLOCKS;
1429 mtx_lock(&nmp->nm_mtx);
1430 if (nmp->nm_state & NFSSTA_TIMEO)
1431 vq.vq_flags |= VQ_NOTRESP;
1432 mtx_unlock(&nmp->nm_mtx);
1434 if (!(nmp->nm_flag & NFSMNT_NOLOCKS) &&
1435 (nmp->nm_state & NFSSTA_LOCKTIMEO))
1436 vq.vq_flags |= VQ_NOTRESPLOCK;
1438 error = SYSCTL_OUT(req, &vq, sizeof(vq));
1441 if (req->oldptr != NULL) {
1442 error = SYSCTL_OUT(req, &nmp->nm_tprintf_initial_delay,
1443 sizeof(nmp->nm_tprintf_initial_delay));
1447 if (req->newptr != NULL) {
1448 error = vfs_suser(mp, req->td);
1451 error = SYSCTL_IN(req, &nmp->nm_tprintf_initial_delay,
1452 sizeof(nmp->nm_tprintf_initial_delay));
1455 if (nmp->nm_tprintf_initial_delay < 0)
1456 nmp->nm_tprintf_initial_delay = 0;