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);
467 error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
469 panic("nfs_mountroot: SIOCAIFADDR: %d", error);
471 if ((cp = getenv("boot.netif.mtu")) != NULL) {
472 ir.ifr_mtu = strtol(cp, NULL, 10);
473 bcopy(nd->myif.ifra_name, ir.ifr_name, IFNAMSIZ);
475 error = ifioctl(so, SIOCSIFMTU, (caddr_t)&ir, td);
477 printf("nfs_mountroot: SIOCSIFMTU: %d", error);
482 * If the gateway field is filled in, set it as the default route.
483 * Note that pxeboot will set a default route of 0 if the route
484 * is not set by the DHCP server. Check also for a value of 0
485 * to avoid panicking inappropriately in that situation.
487 if (nd->mygateway.sin_len != 0 &&
488 nd->mygateway.sin_addr.s_addr != 0) {
489 struct sockaddr_in mask, sin;
491 bzero((caddr_t)&mask, sizeof(mask));
493 sin.sin_family = AF_INET;
494 sin.sin_len = sizeof(sin);
495 /* XXX MRT use table 0 for this sort of thing */
496 error = rtrequest(RTM_ADD, (struct sockaddr *)&sin,
497 (struct sockaddr *)&nd->mygateway,
498 (struct sockaddr *)&mask,
499 RTF_UP | RTF_GATEWAY, NULL);
501 panic("nfs_mountroot: RTM_ADD: %d", error);
505 * Create the rootfs mount point.
507 nd->root_args.fh = nd->root_fh;
508 nd->root_args.fhsize = nd->root_fhsize;
509 l = ntohl(nd->root_saddr.sin_addr.s_addr);
510 snprintf(buf, sizeof(buf), "%ld.%ld.%ld.%ld:%s",
511 (l >> 24) & 0xff, (l >> 16) & 0xff,
512 (l >> 8) & 0xff, (l >> 0) & 0xff, nd->root_hostnam);
513 printf("NFS ROOT: %s\n", buf);
514 nd->root_args.hostname = buf;
515 if ((error = nfs_mountdiskless(buf,
516 &nd->root_saddr, &nd->root_args, td, &vp, mp)) != 0) {
521 * This is not really an nfs issue, but it is much easier to
522 * set hostname here and then let the "/etc/rc.xxx" files
523 * mount the right /var based upon its preset value.
525 mtx_lock(&prison0.pr_mtx);
526 strlcpy(prison0.pr_hostname, nd->my_hostnam,
527 sizeof (prison0.pr_hostname));
528 mtx_unlock(&prison0.pr_mtx);
529 inittodr(ntohl(nd->root_time));
534 * Internal version of mount system call for diskless setup.
537 nfs_mountdiskless(char *path,
538 struct sockaddr_in *sin, struct nfs_args *args, struct thread *td,
539 struct vnode **vpp, struct mount *mp)
541 struct sockaddr *nam;
544 nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK);
545 if ((error = mountnfs(args, mp, nam, path, vpp,
546 td->td_ucred)) != 0) {
547 printf("nfs_mountroot: mount %s on /: %d\n", path, error);
554 nfs_sec_name_to_num(char *sec)
556 if (!strcmp(sec, "krb5"))
557 return (RPCSEC_GSS_KRB5);
558 if (!strcmp(sec, "krb5i"))
559 return (RPCSEC_GSS_KRB5I);
560 if (!strcmp(sec, "krb5p"))
561 return (RPCSEC_GSS_KRB5P);
562 if (!strcmp(sec, "sys"))
565 * Userland should validate the string but we will try and
566 * cope with unexpected values.
572 nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
573 const char *hostname)
585 * Set read-only flag if requested; otherwise, clear it if this is
586 * an update. If this is not an update, then either the read-only
587 * flag is already clear, or this is a root mount and it was set
588 * intentionally at some previous point.
590 if (vfs_getopt(mp->mnt_optnew, "ro", NULL, NULL) == 0) {
592 mp->mnt_flag |= MNT_RDONLY;
594 } else if (mp->mnt_flag & MNT_UPDATE) {
596 mp->mnt_flag &= ~MNT_RDONLY;
601 * Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes
602 * no sense in that context. Also, set up appropriate retransmit
603 * and soft timeout behavior.
605 if (argp->sotype == SOCK_STREAM) {
606 nmp->nm_flag &= ~NFSMNT_NOCONN;
607 nmp->nm_flag |= NFSMNT_DUMBTIMR;
608 nmp->nm_timeo = NFS_MAXTIMEO;
609 nmp->nm_retry = NFS_RETRANS_TCP;
612 /* Also clear RDIRPLUS if not NFSv3, it crashes some servers */
613 if ((argp->flags & NFSMNT_NFSV3) == 0)
614 nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
616 /* Re-bind if rsrvd port requested and wasn't on one */
617 adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT)
618 && (argp->flags & NFSMNT_RESVPORT);
619 /* Also re-bind if we're switching to/from a connected UDP socket */
620 adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) !=
621 (argp->flags & NFSMNT_NOCONN));
623 /* Update flags atomically. Don't change the lock bits. */
624 nmp->nm_flag = argp->flags | nmp->nm_flag;
627 if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) {
628 nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10;
629 if (nmp->nm_timeo < NFS_MINTIMEO)
630 nmp->nm_timeo = NFS_MINTIMEO;
631 else if (nmp->nm_timeo > NFS_MAXTIMEO)
632 nmp->nm_timeo = NFS_MAXTIMEO;
635 if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) {
636 nmp->nm_retry = argp->retrans;
637 if (nmp->nm_retry > NFS_MAXREXMIT)
638 nmp->nm_retry = NFS_MAXREXMIT;
641 if (argp->flags & NFSMNT_NFSV3) {
642 if (argp->sotype == SOCK_DGRAM)
643 maxio = NFS_MAXDGRAMDATA;
647 maxio = NFS_V2MAXDATA;
649 if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) {
650 nmp->nm_wsize = argp->wsize;
651 /* Round down to multiple of blocksize */
652 nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1);
653 if (nmp->nm_wsize <= 0)
654 nmp->nm_wsize = NFS_FABLKSIZE;
656 if (nmp->nm_wsize > maxio)
657 nmp->nm_wsize = maxio;
658 if (nmp->nm_wsize > MAXBSIZE)
659 nmp->nm_wsize = MAXBSIZE;
661 if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) {
662 nmp->nm_rsize = argp->rsize;
663 /* Round down to multiple of blocksize */
664 nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1);
665 if (nmp->nm_rsize <= 0)
666 nmp->nm_rsize = NFS_FABLKSIZE;
668 if (nmp->nm_rsize > maxio)
669 nmp->nm_rsize = maxio;
670 if (nmp->nm_rsize > MAXBSIZE)
671 nmp->nm_rsize = MAXBSIZE;
673 if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) {
674 nmp->nm_readdirsize = argp->readdirsize;
676 if (nmp->nm_readdirsize > maxio)
677 nmp->nm_readdirsize = maxio;
678 if (nmp->nm_readdirsize > nmp->nm_rsize)
679 nmp->nm_readdirsize = nmp->nm_rsize;
681 if ((argp->flags & NFSMNT_ACREGMIN) && argp->acregmin >= 0)
682 nmp->nm_acregmin = argp->acregmin;
684 nmp->nm_acregmin = NFS_MINATTRTIMO;
685 if ((argp->flags & NFSMNT_ACREGMAX) && argp->acregmax >= 0)
686 nmp->nm_acregmax = argp->acregmax;
688 nmp->nm_acregmax = NFS_MAXATTRTIMO;
689 if ((argp->flags & NFSMNT_ACDIRMIN) && argp->acdirmin >= 0)
690 nmp->nm_acdirmin = argp->acdirmin;
692 nmp->nm_acdirmin = NFS_MINDIRATTRTIMO;
693 if ((argp->flags & NFSMNT_ACDIRMAX) && argp->acdirmax >= 0)
694 nmp->nm_acdirmax = argp->acdirmax;
696 nmp->nm_acdirmax = NFS_MAXDIRATTRTIMO;
697 if (nmp->nm_acdirmin > nmp->nm_acdirmax)
698 nmp->nm_acdirmin = nmp->nm_acdirmax;
699 if (nmp->nm_acregmin > nmp->nm_acregmax)
700 nmp->nm_acregmin = nmp->nm_acregmax;
702 if ((argp->flags & NFSMNT_MAXGRPS) && argp->maxgrouplist >= 0) {
703 if (argp->maxgrouplist <= NFS_MAXGRPS)
704 nmp->nm_numgrps = argp->maxgrouplist;
706 nmp->nm_numgrps = NFS_MAXGRPS;
708 if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0) {
709 if (argp->readahead <= NFS_MAXRAHEAD)
710 nmp->nm_readahead = argp->readahead;
712 nmp->nm_readahead = NFS_MAXRAHEAD;
714 if ((argp->flags & NFSMNT_WCOMMITSIZE) && argp->wcommitsize >= 0) {
715 if (argp->wcommitsize < nmp->nm_wsize)
716 nmp->nm_wcommitsize = nmp->nm_wsize;
718 nmp->nm_wcommitsize = argp->wcommitsize;
720 if ((argp->flags & NFSMNT_DEADTHRESH) && argp->deadthresh >= 0) {
721 if (argp->deadthresh <= NFS_MAXDEADTHRESH)
722 nmp->nm_deadthresh = argp->deadthresh;
724 nmp->nm_deadthresh = NFS_MAXDEADTHRESH;
727 adjsock |= ((nmp->nm_sotype != argp->sotype) ||
728 (nmp->nm_soproto != argp->proto));
729 nmp->nm_sotype = argp->sotype;
730 nmp->nm_soproto = argp->proto;
732 if (nmp->nm_client && adjsock) {
733 nfs_safedisconnect(nmp);
734 if (nmp->nm_sotype == SOCK_DGRAM)
735 while (nfs_connect(nmp)) {
736 printf("nfs_args: retrying connect\n");
737 (void) tsleep(&fake_wchan, PSOCK, "nfscon", hz);
742 strlcpy(nmp->nm_hostname, hostname,
743 sizeof(nmp->nm_hostname));
744 p = strchr(nmp->nm_hostname, ':');
749 if (vfs_getopt(mp->mnt_optnew, "sec",
750 (void **) &secname, NULL) == 0) {
751 nmp->nm_secflavor = nfs_sec_name_to_num(secname);
753 nmp->nm_secflavor = AUTH_SYS;
756 if (vfs_getopt(mp->mnt_optnew, "principal",
757 (void **) &principal, NULL) == 0) {
758 strlcpy(nmp->nm_principal, principal,
759 sizeof(nmp->nm_principal));
761 snprintf(nmp->nm_principal, sizeof(nmp->nm_principal),
762 "nfs@%s", nmp->nm_hostname);
766 static const char *nfs_opts[] = { "from", "nfs_args",
767 "noatime", "noexec", "suiddir", "nosuid", "nosymfollow", "union",
768 "noclusterr", "noclusterw", "multilabel", "acls", "force", "update",
769 "async", "dumbtimer", "noconn", "nolockd", "intr", "rdirplus", "resvport",
770 "readdirsize", "soft", "hard", "mntudp", "tcp", "udp", "wsize", "rsize",
771 "retrans", "acregmin", "acregmax", "acdirmin", "acdirmax",
772 "deadthresh", "hostname", "timeout", "addr", "fh", "nfsv3", "sec",
773 "maxgroups", "principal",
780 * It seems a bit dumb to copyinstr() the host and path here and then
781 * bcopy() them in mountnfs(), but I wanted to detect errors before
782 * doing the sockargs() call because sockargs() allocates an mbuf and
783 * an error after that means that I have to release the mbuf.
787 nfs_mount(struct mount *mp)
789 struct nfs_args args = {
790 .version = NFS_ARGSVERSION,
792 .addrlen = sizeof (struct sockaddr_in),
793 .sotype = SOCK_STREAM,
797 .flags = NFSMNT_RESVPORT,
800 .readdirsize = NFS_READDIRSIZE,
802 .retrans = NFS_RETRANS,
803 .maxgrouplist = NFS_MAXGRPS,
804 .readahead = NFS_DEFRAHEAD,
805 .wcommitsize = 0, /* was: NQ_DEFLEASE */
806 .deadthresh = NFS_MAXDEADTHRESH, /* was: NQ_DEADTHRESH */
809 .acregmin = NFS_MINATTRTIMO,
810 .acregmax = NFS_MAXATTRTIMO,
811 .acdirmin = NFS_MINDIRATTRTIMO,
812 .acdirmax = NFS_MAXDIRATTRTIMO,
814 int error, ret, has_nfs_args_opt;
815 int has_addr_opt, has_fh_opt, has_hostname_opt;
816 struct sockaddr *nam;
820 u_char nfh[NFSX_V3FHMAX];
823 has_nfs_args_opt = 0;
826 has_hostname_opt = 0;
828 if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) {
833 if ((mp->mnt_flag & (MNT_ROOTFS | MNT_UPDATE)) == MNT_ROOTFS) {
834 error = nfs_mountroot(mp);
839 * The old mount_nfs program passed the struct nfs_args
840 * from userspace to kernel. The new mount_nfs program
841 * passes string options via nmount() from userspace to kernel
842 * and we populate the struct nfs_args in the kernel.
844 if (vfs_getopt(mp->mnt_optnew, "nfs_args", NULL, NULL) == 0) {
845 error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args,
850 if (args.version != NFS_ARGSVERSION) {
851 error = EPROGMISMATCH;
854 has_nfs_args_opt = 1;
857 if (vfs_getopt(mp->mnt_optnew, "dumbtimer", NULL, NULL) == 0)
858 args.flags |= NFSMNT_DUMBTIMR;
859 if (vfs_getopt(mp->mnt_optnew, "noconn", NULL, NULL) == 0)
860 args.flags |= NFSMNT_NOCONN;
861 if (vfs_getopt(mp->mnt_optnew, "conn", NULL, NULL) == 0)
862 args.flags |= NFSMNT_NOCONN;
863 if (vfs_getopt(mp->mnt_optnew, "nolockd", NULL, NULL) == 0)
864 args.flags |= NFSMNT_NOLOCKD;
865 if (vfs_getopt(mp->mnt_optnew, "lockd", NULL, NULL) == 0)
866 args.flags &= ~NFSMNT_NOLOCKD;
867 if (vfs_getopt(mp->mnt_optnew, "intr", NULL, NULL) == 0)
868 args.flags |= NFSMNT_INT;
869 if (vfs_getopt(mp->mnt_optnew, "rdirplus", NULL, NULL) == 0)
870 args.flags |= NFSMNT_RDIRPLUS;
871 if (vfs_getopt(mp->mnt_optnew, "resvport", NULL, NULL) == 0)
872 args.flags |= NFSMNT_RESVPORT;
873 if (vfs_getopt(mp->mnt_optnew, "noresvport", NULL, NULL) == 0)
874 args.flags &= ~NFSMNT_RESVPORT;
875 if (vfs_getopt(mp->mnt_optnew, "soft", NULL, NULL) == 0)
876 args.flags |= NFSMNT_SOFT;
877 if (vfs_getopt(mp->mnt_optnew, "hard", NULL, NULL) == 0)
878 args.flags &= ~NFSMNT_SOFT;
879 if (vfs_getopt(mp->mnt_optnew, "mntudp", NULL, NULL) == 0)
880 args.sotype = SOCK_DGRAM;
881 if (vfs_getopt(mp->mnt_optnew, "udp", NULL, NULL) == 0)
882 args.sotype = SOCK_DGRAM;
883 if (vfs_getopt(mp->mnt_optnew, "tcp", NULL, NULL) == 0)
884 args.sotype = SOCK_STREAM;
885 if (vfs_getopt(mp->mnt_optnew, "nfsv3", NULL, NULL) == 0)
886 args.flags |= NFSMNT_NFSV3;
887 if (vfs_getopt(mp->mnt_optnew, "readdirsize", (void **)&opt, NULL) == 0) {
889 vfs_mount_error(mp, "illegal readdirsize");
893 ret = sscanf(opt, "%d", &args.readdirsize);
894 if (ret != 1 || args.readdirsize <= 0) {
895 vfs_mount_error(mp, "illegal readdirsize: %s",
900 args.flags |= NFSMNT_READDIRSIZE;
902 if (vfs_getopt(mp->mnt_optnew, "readahead", (void **)&opt, NULL) == 0) {
904 vfs_mount_error(mp, "illegal readahead");
908 ret = sscanf(opt, "%d", &args.readahead);
909 if (ret != 1 || args.readahead <= 0) {
910 vfs_mount_error(mp, "illegal readahead: %s",
915 args.flags |= NFSMNT_READAHEAD;
917 if (vfs_getopt(mp->mnt_optnew, "wsize", (void **)&opt, NULL) == 0) {
919 vfs_mount_error(mp, "illegal wsize");
923 ret = sscanf(opt, "%d", &args.wsize);
924 if (ret != 1 || args.wsize <= 0) {
925 vfs_mount_error(mp, "illegal wsize: %s",
930 args.flags |= NFSMNT_WSIZE;
932 if (vfs_getopt(mp->mnt_optnew, "rsize", (void **)&opt, NULL) == 0) {
934 vfs_mount_error(mp, "illegal rsize");
938 ret = sscanf(opt, "%d", &args.rsize);
939 if (ret != 1 || args.rsize <= 0) {
940 vfs_mount_error(mp, "illegal wsize: %s",
945 args.flags |= NFSMNT_RSIZE;
947 if (vfs_getopt(mp->mnt_optnew, "retrans", (void **)&opt, NULL) == 0) {
949 vfs_mount_error(mp, "illegal retrans");
953 ret = sscanf(opt, "%d", &args.retrans);
954 if (ret != 1 || args.retrans <= 0) {
955 vfs_mount_error(mp, "illegal retrans: %s",
960 args.flags |= NFSMNT_RETRANS;
962 if (vfs_getopt(mp->mnt_optnew, "acregmin", (void **)&opt, NULL) == 0) {
963 ret = sscanf(opt, "%d", &args.acregmin);
964 if (ret != 1 || args.acregmin < 0) {
965 vfs_mount_error(mp, "illegal acregmin: %s",
970 args.flags |= NFSMNT_ACREGMIN;
972 if (vfs_getopt(mp->mnt_optnew, "acregmax", (void **)&opt, NULL) == 0) {
973 ret = sscanf(opt, "%d", &args.acregmax);
974 if (ret != 1 || args.acregmax < 0) {
975 vfs_mount_error(mp, "illegal acregmax: %s",
980 args.flags |= NFSMNT_ACREGMAX;
982 if (vfs_getopt(mp->mnt_optnew, "acdirmin", (void **)&opt, NULL) == 0) {
983 ret = sscanf(opt, "%d", &args.acdirmin);
984 if (ret != 1 || args.acdirmin < 0) {
985 vfs_mount_error(mp, "illegal acdirmin: %s",
990 args.flags |= NFSMNT_ACDIRMIN;
992 if (vfs_getopt(mp->mnt_optnew, "acdirmax", (void **)&opt, NULL) == 0) {
993 ret = sscanf(opt, "%d", &args.acdirmax);
994 if (ret != 1 || args.acdirmax < 0) {
995 vfs_mount_error(mp, "illegal acdirmax: %s",
1000 args.flags |= NFSMNT_ACDIRMAX;
1002 if (vfs_getopt(mp->mnt_optnew, "deadthresh", (void **)&opt, NULL) == 0) {
1003 ret = sscanf(opt, "%d", &args.deadthresh);
1004 if (ret != 1 || args.deadthresh <= 0) {
1005 vfs_mount_error(mp, "illegal deadthresh: %s",
1010 args.flags |= NFSMNT_DEADTHRESH;
1012 if (vfs_getopt(mp->mnt_optnew, "timeout", (void **)&opt, NULL) == 0) {
1013 ret = sscanf(opt, "%d", &args.timeo);
1014 if (ret != 1 || args.timeo <= 0) {
1015 vfs_mount_error(mp, "illegal timeout: %s",
1020 args.flags |= NFSMNT_TIMEO;
1022 if (vfs_getopt(mp->mnt_optnew, "maxgroups", (void **)&opt, NULL) == 0) {
1023 ret = sscanf(opt, "%d", &args.maxgrouplist);
1024 if (ret != 1 || args.timeo <= 0) {
1025 vfs_mount_error(mp, "illegal maxgroups: %s",
1030 args.flags |= NFSMNT_MAXGRPS;
1032 if (vfs_getopt(mp->mnt_optnew, "addr", (void **)&args.addr,
1033 &args.addrlen) == 0) {
1035 if (args.addrlen > SOCK_MAXADDRLEN) {
1036 error = ENAMETOOLONG;
1039 nam = malloc(args.addrlen, M_SONAME,
1041 bcopy(args.addr, nam, args.addrlen);
1042 nam->sa_len = args.addrlen;
1044 if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh,
1045 &args.fhsize) == 0) {
1048 if (vfs_getopt(mp->mnt_optnew, "hostname", (void **)&args.hostname,
1050 has_hostname_opt = 1;
1052 if (args.hostname == NULL) {
1053 vfs_mount_error(mp, "Invalid hostname");
1058 if (mp->mnt_flag & MNT_UPDATE) {
1059 struct nfsmount *nmp = VFSTONFS(mp);
1066 * When doing an update, we can't change from or to
1067 * v3, switch lockd strategies or change cookie translation
1069 args.flags = (args.flags &
1070 ~(NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) |
1072 (NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
1073 nfs_decode_args(mp, nmp, &args, NULL);
1078 * Make the nfs_ip_paranoia sysctl serve as the default connection
1079 * or no-connection mode for those protocols that support
1080 * no-connection mode (the flag will be cleared later for protocols
1081 * that do not support no-connection mode). This will allow a client
1082 * to receive replies from a different IP then the request was
1083 * sent to. Note: default value for nfs_ip_paranoia is 1 (paranoid),
1086 if (nfs_ip_paranoia == 0)
1087 args.flags |= NFSMNT_NOCONN;
1089 if (has_nfs_args_opt) {
1091 * In the 'nfs_args' case, the pointers in the args
1092 * structure are in userland - we copy them in here.
1095 error = copyin((caddr_t)args.fh, (caddr_t)nfh,
1102 if (!has_hostname_opt) {
1103 error = copyinstr(args.hostname, hst, MNAMELEN-1, &len);
1107 bzero(&hst[len], MNAMELEN - len);
1108 args.hostname = hst;
1110 if (!has_addr_opt) {
1111 /* sockargs() call must be after above copyin() calls */
1112 error = getsockaddr(&nam, (caddr_t)args.addr,
1119 error = mountnfs(&args, mp, nam, args.hostname, &vp,
1120 curthread->td_ucred);
1124 mp->mnt_kern_flag |= (MNTK_MPSAFE|MNTK_LOOKUP_SHARED);
1135 * It seems a bit dumb to copyinstr() the host and path here and then
1136 * bcopy() them in mountnfs(), but I wanted to detect errors before
1137 * doing the sockargs() call because sockargs() allocates an mbuf and
1138 * an error after that means that I have to release the mbuf.
1142 nfs_cmount(struct mntarg *ma, void *data, int flags)
1145 struct nfs_args args;
1147 error = copyin(data, &args, sizeof (struct nfs_args));
1151 ma = mount_arg(ma, "nfs_args", &args, sizeof args);
1153 error = kernel_mount(ma, flags);
1158 * Common code for mount and mountroot
1161 mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
1162 char *hst, struct vnode **vpp, struct ucred *cred)
1164 struct nfsmount *nmp;
1169 if (mp->mnt_flag & MNT_UPDATE) {
1171 printf("%s: MNT_UPDATE is no longer handled here\n", __func__);
1172 free(nam, M_SONAME);
1175 nmp = uma_zalloc(nfsmount_zone, M_WAITOK);
1176 bzero((caddr_t)nmp, sizeof (struct nfsmount));
1177 TAILQ_INIT(&nmp->nm_bufq);
1181 nmp->nm_mountp = mp;
1182 mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF);
1185 * V2 can only handle 32 bit filesizes. A 4GB-1 limit may be too
1186 * high, depending on whether we end up with negative offsets in
1187 * the client or server somewhere. 2GB-1 may be safer.
1189 * For V3, nfs_fsinfo will adjust this as necessary. Assume maximum
1190 * that we can handle until we find out otherwise.
1191 * XXX Our "safe" limit on the client is what we can store in our
1192 * buffer cache using signed(!) block numbers.
1194 if ((argp->flags & NFSMNT_NFSV3) == 0)
1195 nmp->nm_maxfilesize = 0xffffffffLL;
1197 nmp->nm_maxfilesize = (u_int64_t)0x80000000 * DEV_BSIZE - 1;
1199 nmp->nm_timeo = NFS_TIMEO;
1200 nmp->nm_retry = NFS_RETRANS;
1201 if ((argp->flags & NFSMNT_NFSV3) && argp->sotype == SOCK_STREAM) {
1202 nmp->nm_wsize = nmp->nm_rsize = NFS_MAXDATA;
1204 nmp->nm_wsize = NFS_WSIZE;
1205 nmp->nm_rsize = NFS_RSIZE;
1207 nmp->nm_wcommitsize = hibufspace / (desiredvnodes / 1000);
1208 nmp->nm_readdirsize = NFS_READDIRSIZE;
1209 nmp->nm_numgrps = NFS_MAXGRPS;
1210 nmp->nm_readahead = NFS_DEFRAHEAD;
1211 nmp->nm_deadthresh = NFS_MAXDEADTHRESH;
1212 nmp->nm_tprintf_delay = nfs_tprintf_delay;
1213 if (nmp->nm_tprintf_delay < 0)
1214 nmp->nm_tprintf_delay = 0;
1215 nmp->nm_tprintf_initial_delay = nfs_tprintf_initial_delay;
1216 if (nmp->nm_tprintf_initial_delay < 0)
1217 nmp->nm_tprintf_initial_delay = 0;
1218 nmp->nm_fhsize = argp->fhsize;
1219 bcopy((caddr_t)argp->fh, (caddr_t)nmp->nm_fh, argp->fhsize);
1220 bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);
1222 /* Set up the sockets and per-host congestion */
1223 nmp->nm_sotype = argp->sotype;
1224 nmp->nm_soproto = argp->proto;
1225 nmp->nm_rpcops = &nfs_rpcops;
1227 nfs_decode_args(mp, nmp, argp, hst);
1230 * For Connection based sockets (TCP,...) defer the connect until
1231 * the first request, in case the server is not responding.
1233 if (nmp->nm_sotype == SOCK_DGRAM &&
1234 (error = nfs_connect(nmp)))
1238 * This is silly, but it has to be set so that vinifod() works.
1239 * We do not want to do an nfs_statfs() here since we can get
1240 * stuck on a dead server and we are holding a lock on the mount
1243 mtx_lock(&nmp->nm_mtx);
1244 mp->mnt_stat.f_iosize = nfs_iosize(nmp);
1245 mtx_unlock(&nmp->nm_mtx);
1247 * A reference count is needed on the nfsnode representing the
1248 * remote root. If this object is not persistent, then backward
1249 * traversals of the mount point (i.e. "..") will not work if
1250 * the nfsnode gets flushed out of the cache. Ufs does not have
1251 * this problem, because one can identify root inodes by their
1252 * number == ROOTINO (2).
1254 error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
1260 * Get file attributes and transfer parameters for the
1261 * mountpoint. This has the side effect of filling in
1262 * (*vpp)->v_type with the correct value.
1264 if (argp->flags & NFSMNT_NFSV3)
1265 nfs_fsinfo(nmp, *vpp, curthread->td_ucred, curthread);
1267 VOP_GETATTR(*vpp, &attrs, curthread->td_ucred);
1270 * Lose the lock but keep the ref.
1272 VOP_UNLOCK(*vpp, 0);
1276 nfs_disconnect(nmp);
1277 mtx_destroy(&nmp->nm_mtx);
1278 uma_zfree(nfsmount_zone, nmp);
1279 free(nam, M_SONAME);
1284 * unmount system call
1287 nfs_unmount(struct mount *mp, int mntflags)
1289 struct nfsmount *nmp;
1290 int error, flags = 0;
1292 if (mntflags & MNT_FORCE)
1293 flags |= FORCECLOSE;
1296 * Goes something like this..
1297 * - Call vflush() to clear out vnodes for this filesystem
1298 * - Close the socket
1299 * - Free up the data structures
1301 /* In the forced case, cancel any outstanding requests. */
1302 if (flags & FORCECLOSE) {
1303 error = nfs_nmcancelreqs(nmp);
1307 /* We hold 1 extra ref on the root vnode; see comment in mountnfs(). */
1308 error = vflush(mp, 1, flags, curthread);
1313 * We are now committed to the unmount.
1315 nfs_disconnect(nmp);
1316 free(nmp->nm_nam, M_SONAME);
1318 mtx_destroy(&nmp->nm_mtx);
1319 uma_zfree(nfsmount_zone, nmp);
1325 * Return root of a filesystem
1328 nfs_root(struct mount *mp, int flags, struct vnode **vpp)
1331 struct nfsmount *nmp;
1336 error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, flags);
1341 * Get transfer parameters and attributes for root vnode once.
1343 mtx_lock(&nmp->nm_mtx);
1344 if ((nmp->nm_state & NFSSTA_GOTFSINFO) == 0 &&
1345 (nmp->nm_flag & NFSMNT_NFSV3)) {
1346 mtx_unlock(&nmp->nm_mtx);
1347 nfs_fsinfo(nmp, vp, curthread->td_ucred, curthread);
1349 mtx_unlock(&nmp->nm_mtx);
1350 if (vp->v_type == VNON)
1352 vp->v_vflag |= VV_ROOT;
1358 * Flush out the buffer cache
1362 nfs_sync(struct mount *mp, int waitfor)
1364 struct vnode *vp, *mvp;
1366 int error, allerror = 0;
1371 * Force stale buffer cache information to be flushed.
1375 MNT_VNODE_FOREACH(vp, mp, mvp) {
1378 /* XXX Racy bv_cnt check. */
1379 if (VOP_ISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
1380 waitfor == MNT_LAZY) {
1385 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
1387 MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp);
1390 error = VOP_FSYNC(vp, waitfor, td);
1403 nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req)
1405 struct nfsmount *nmp = VFSTONFS(mp);
1409 bzero(&vq, sizeof(vq));
1412 case VFS_CTL_NOLOCKS:
1413 val = (nmp->nm_flag & NFSMNT_NOLOCKS) ? 1 : 0;
1414 if (req->oldptr != NULL) {
1415 error = SYSCTL_OUT(req, &val, sizeof(val));
1419 if (req->newptr != NULL) {
1420 error = SYSCTL_IN(req, &val, sizeof(val));
1424 nmp->nm_flag |= NFSMNT_NOLOCKS;
1426 nmp->nm_flag &= ~NFSMNT_NOLOCKS;
1431 mtx_lock(&nmp->nm_mtx);
1432 if (nmp->nm_state & NFSSTA_TIMEO)
1433 vq.vq_flags |= VQ_NOTRESP;
1434 mtx_unlock(&nmp->nm_mtx);
1436 if (!(nmp->nm_flag & NFSMNT_NOLOCKS) &&
1437 (nmp->nm_state & NFSSTA_LOCKTIMEO))
1438 vq.vq_flags |= VQ_NOTRESPLOCK;
1440 error = SYSCTL_OUT(req, &vq, sizeof(vq));
1443 if (req->oldptr != NULL) {
1444 error = SYSCTL_OUT(req, &nmp->nm_tprintf_initial_delay,
1445 sizeof(nmp->nm_tprintf_initial_delay));
1449 if (req->newptr != NULL) {
1450 error = vfs_suser(mp, req->td);
1453 error = SYSCTL_IN(req, &nmp->nm_tprintf_initial_delay,
1454 sizeof(nmp->nm_tprintf_initial_delay));
1457 if (nmp->nm_tprintf_initial_delay < 0)
1458 nmp->nm_tprintf_initial_delay = 0;