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>
69 #include <netinet/in.h>
73 #include <nfs/nfsproto.h>
74 #include <nfsclient/nfs.h>
75 #include <nfsclient/nfsnode.h>
76 #include <nfsclient/nfsmount.h>
77 #include <nfs/xdr_subs.h>
78 #include <nfsclient/nfsm_subs.h>
79 #include <nfsclient/nfsdiskless.h>
81 MALLOC_DEFINE(M_NFSREQ, "nfsclient_req", "NFS request header");
82 MALLOC_DEFINE(M_NFSBIGFH, "nfsclient_bigfh", "NFS version 3 file handle");
83 MALLOC_DEFINE(M_NFSDIROFF, "nfsclient_diroff", "NFS directory offset data");
84 MALLOC_DEFINE(M_NFSHASH, "nfsclient_hash", "NFS hash tables");
85 MALLOC_DEFINE(M_NFSDIRECTIO, "nfsclient_directio", "NFS Direct IO async write state");
87 uma_zone_t nfsmount_zone;
89 struct nfsstats nfsstats;
91 SYSCTL_NODE(_vfs, OID_AUTO, nfs, CTLFLAG_RW, 0, "NFS filesystem");
92 SYSCTL_STRUCT(_vfs_nfs, NFS_NFSSTATS, nfsstats, CTLFLAG_RW,
93 &nfsstats, nfsstats, "S,nfsstats");
94 static int nfs_ip_paranoia = 1;
95 SYSCTL_INT(_vfs_nfs, OID_AUTO, nfs_ip_paranoia, CTLFLAG_RW,
97 "Disallow accepting replies from IPs which differ from those sent");
100 SYSCTL_INT(_vfs_nfs, OID_AUTO, debug, CTLFLAG_RW, &nfs_debug, 0,
101 "Toggle debug flag");
103 static int nfs_tprintf_initial_delay = NFS_TPRINTF_INITIAL_DELAY;
104 SYSCTL_INT(_vfs_nfs, NFS_TPRINTF_INITIAL_DELAY,
105 downdelayinitial, CTLFLAG_RW, &nfs_tprintf_initial_delay, 0,
106 "Delay before printing \"nfs server not responding\" messages");
107 /* how long between console messages "nfs server foo not responding" */
108 static int nfs_tprintf_delay = NFS_TPRINTF_DELAY;
109 SYSCTL_INT(_vfs_nfs, NFS_TPRINTF_DELAY,
110 downdelayinterval, CTLFLAG_RW, &nfs_tprintf_delay, 0,
111 "Delay between printing \"nfs server not responding\" messages");
113 static void nfs_decode_args(struct mount *mp, struct nfsmount *nmp,
114 struct nfs_args *argp, const char *hostname);
115 static int mountnfs(struct nfs_args *, struct mount *,
116 struct sockaddr *, char *, struct vnode **,
117 struct ucred *cred, int);
118 static vfs_mount_t nfs_mount;
119 static vfs_cmount_t nfs_cmount;
120 static vfs_unmount_t nfs_unmount;
121 static vfs_root_t nfs_root;
122 static vfs_statfs_t nfs_statfs;
123 static vfs_sync_t nfs_sync;
124 static vfs_sysctl_t nfs_sysctl;
126 static int fake_wchan;
129 * nfs vfs operations.
131 static struct vfsops nfs_vfsops = {
132 .vfs_init = nfs_init,
133 .vfs_mount = nfs_mount,
134 .vfs_cmount = nfs_cmount,
135 .vfs_root = nfs_root,
136 .vfs_statfs = nfs_statfs,
137 .vfs_sync = nfs_sync,
138 .vfs_uninit = nfs_uninit,
139 .vfs_unmount = nfs_unmount,
140 .vfs_sysctl = nfs_sysctl,
142 VFS_SET(nfs_vfsops, nfs, VFCF_NETWORK);
144 /* So that loader and kldload(2) can find us, wherever we are.. */
145 MODULE_VERSION(nfs, 1);
146 MODULE_DEPEND(nfs, krpc, 1, 1, 1);
148 MODULE_DEPEND(nfs, kgssapi, 1, 1, 1);
150 MODULE_DEPEND(nfs, nfs_common, 1, 1, 1);
152 static struct nfs_rpcops nfs_rpcops = {
162 * This structure must be filled in by a primary bootstrap or bootstrap
163 * server for a diskless/dataless machine. It is initialized below just
164 * to ensure that it is allocated to initialized data (.data not .bss).
166 struct nfs_diskless nfs_diskless = { { { 0 } } };
167 struct nfsv3_diskless nfsv3_diskless = { { { 0 } } };
168 int nfs_diskless_valid = 0;
170 SYSCTL_INT(_vfs_nfs, OID_AUTO, diskless_valid, CTLFLAG_RD,
171 &nfs_diskless_valid, 0,
172 "Has the diskless struct been filled correctly");
174 SYSCTL_STRING(_vfs_nfs, OID_AUTO, diskless_rootpath, CTLFLAG_RD,
175 nfsv3_diskless.root_hostnam, 0, "Path to nfs root");
177 SYSCTL_OPAQUE(_vfs_nfs, OID_AUTO, diskless_rootaddr, CTLFLAG_RD,
178 &nfsv3_diskless.root_saddr, sizeof nfsv3_diskless.root_saddr,
179 "%Ssockaddr_in", "Diskless root nfs address");
182 void nfsargs_ntoh(struct nfs_args *);
183 static int nfs_mountdiskless(char *,
184 struct sockaddr_in *, struct nfs_args *,
185 struct thread *, struct vnode **, struct mount *);
186 static void nfs_convert_diskless(void);
187 static void nfs_convert_oargs(struct nfs_args *args,
188 struct onfs_args *oargs);
191 nfs_iosize(struct nfsmount *nmp)
196 * Calculate the size used for io buffers. Use the larger
197 * of the two sizes to minimise nfs requests but make sure
198 * that it is at least one VM page to avoid wasting buffer
201 iosize = imax(nmp->nm_rsize, nmp->nm_wsize);
202 iosize = imax(iosize, PAGE_SIZE);
207 nfs_convert_oargs(struct nfs_args *args, struct onfs_args *oargs)
210 args->version = NFS_ARGSVERSION;
211 args->addr = oargs->addr;
212 args->addrlen = oargs->addrlen;
213 args->sotype = oargs->sotype;
214 args->proto = oargs->proto;
215 args->fh = oargs->fh;
216 args->fhsize = oargs->fhsize;
217 args->flags = oargs->flags;
218 args->wsize = oargs->wsize;
219 args->rsize = oargs->rsize;
220 args->readdirsize = oargs->readdirsize;
221 args->timeo = oargs->timeo;
222 args->retrans = oargs->retrans;
223 args->maxgrouplist = oargs->maxgrouplist;
224 args->readahead = oargs->readahead;
225 args->deadthresh = oargs->deadthresh;
226 args->hostname = oargs->hostname;
230 nfs_convert_diskless(void)
233 bcopy(&nfs_diskless.myif, &nfsv3_diskless.myif,
234 sizeof(struct ifaliasreq));
235 bcopy(&nfs_diskless.mygateway, &nfsv3_diskless.mygateway,
236 sizeof(struct sockaddr_in));
237 nfs_convert_oargs(&nfsv3_diskless.root_args,&nfs_diskless.root_args);
238 if (nfsv3_diskless.root_args.flags & NFSMNT_NFSV3) {
239 nfsv3_diskless.root_fhsize = NFSX_V3FH;
240 bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V3FH);
242 nfsv3_diskless.root_fhsize = NFSX_V2FH;
243 bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V2FH);
245 bcopy(&nfs_diskless.root_saddr,&nfsv3_diskless.root_saddr,
246 sizeof(struct sockaddr_in));
247 bcopy(nfs_diskless.root_hostnam, nfsv3_diskless.root_hostnam, MNAMELEN);
248 nfsv3_diskless.root_time = nfs_diskless.root_time;
249 bcopy(nfs_diskless.my_hostnam, nfsv3_diskless.my_hostnam,
251 nfs_diskless_valid = 3;
258 nfs_statfs(struct mount *mp, struct statfs *sbp)
262 struct nfs_statfs *sfp;
264 struct nfsmount *nmp = VFSTONFS(mp);
265 int error = 0, v3 = (nmp->nm_flag & NFSMNT_NFSV3), retattr;
266 struct mbuf *mreq, *mrep, *md, *mb;
274 error = vfs_busy(mp, MBF_NOWAIT);
277 error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
283 mtx_lock(&nmp->nm_mtx);
284 if (v3 && (nmp->nm_state & NFSSTA_GOTFSINFO) == 0) {
285 mtx_unlock(&nmp->nm_mtx);
286 (void)nfs_fsinfo(nmp, vp, td->td_ucred, td);
288 mtx_unlock(&nmp->nm_mtx);
289 nfsstats.rpccnt[NFSPROC_FSSTAT]++;
290 mreq = nfsm_reqhead(vp, NFSPROC_FSSTAT, NFSX_FH(v3));
292 bpos = mtod(mb, caddr_t);
294 nfsm_request(vp, NFSPROC_FSSTAT, td, td->td_ucred);
296 nfsm_postop_attr(vp, retattr);
302 sfp = nfsm_dissect(struct nfs_statfs *, NFSX_STATFS(v3));
303 mtx_lock(&nmp->nm_mtx);
304 sbp->f_iosize = nfs_iosize(nmp);
305 mtx_unlock(&nmp->nm_mtx);
307 sbp->f_bsize = NFS_FABLKSIZE;
308 tquad = fxdr_hyper(&sfp->sf_tbytes);
309 sbp->f_blocks = tquad / NFS_FABLKSIZE;
310 tquad = fxdr_hyper(&sfp->sf_fbytes);
311 sbp->f_bfree = tquad / NFS_FABLKSIZE;
312 tquad = fxdr_hyper(&sfp->sf_abytes);
313 sbp->f_bavail = tquad / NFS_FABLKSIZE;
314 sbp->f_files = (fxdr_unsigned(int32_t,
315 sfp->sf_tfiles.nfsuquad[1]) & 0x7fffffff);
316 sbp->f_ffree = (fxdr_unsigned(int32_t,
317 sfp->sf_ffiles.nfsuquad[1]) & 0x7fffffff);
319 sbp->f_bsize = fxdr_unsigned(int32_t, sfp->sf_bsize);
320 sbp->f_blocks = fxdr_unsigned(int32_t, sfp->sf_blocks);
321 sbp->f_bfree = fxdr_unsigned(int32_t, sfp->sf_bfree);
322 sbp->f_bavail = fxdr_unsigned(int32_t, sfp->sf_bavail);
334 * nfs version 3 fsinfo rpc call
337 nfs_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct ucred *cred,
340 struct nfsv3_fsinfo *fsp;
343 int error = 0, retattr;
344 struct mbuf *mreq, *mrep, *md, *mb;
347 nfsstats.rpccnt[NFSPROC_FSINFO]++;
348 mreq = nfsm_reqhead(vp, NFSPROC_FSINFO, NFSX_FH(1));
350 bpos = mtod(mb, caddr_t);
352 nfsm_request(vp, NFSPROC_FSINFO, td, cred);
353 nfsm_postop_attr(vp, retattr);
355 fsp = nfsm_dissect(struct nfsv3_fsinfo *, NFSX_V3FSINFO);
356 pref = fxdr_unsigned(u_int32_t, fsp->fs_wtpref);
357 mtx_lock(&nmp->nm_mtx);
358 if (pref < nmp->nm_wsize && pref >= NFS_FABLKSIZE)
359 nmp->nm_wsize = (pref + NFS_FABLKSIZE - 1) &
360 ~(NFS_FABLKSIZE - 1);
361 max = fxdr_unsigned(u_int32_t, fsp->fs_wtmax);
362 if (max < nmp->nm_wsize && max > 0) {
363 nmp->nm_wsize = max & ~(NFS_FABLKSIZE - 1);
364 if (nmp->nm_wsize == 0)
367 pref = fxdr_unsigned(u_int32_t, fsp->fs_rtpref);
368 if (pref < nmp->nm_rsize && pref >= NFS_FABLKSIZE)
369 nmp->nm_rsize = (pref + NFS_FABLKSIZE - 1) &
370 ~(NFS_FABLKSIZE - 1);
371 max = fxdr_unsigned(u_int32_t, fsp->fs_rtmax);
372 if (max < nmp->nm_rsize && max > 0) {
373 nmp->nm_rsize = max & ~(NFS_FABLKSIZE - 1);
374 if (nmp->nm_rsize == 0)
377 pref = fxdr_unsigned(u_int32_t, fsp->fs_dtpref);
378 if (pref < nmp->nm_readdirsize && pref >= NFS_DIRBLKSIZ)
379 nmp->nm_readdirsize = (pref + NFS_DIRBLKSIZ - 1) &
380 ~(NFS_DIRBLKSIZ - 1);
381 if (max < nmp->nm_readdirsize && max > 0) {
382 nmp->nm_readdirsize = max & ~(NFS_DIRBLKSIZ - 1);
383 if (nmp->nm_readdirsize == 0)
384 nmp->nm_readdirsize = max;
386 maxfsize = fxdr_hyper(&fsp->fs_maxfilesize);
387 if (maxfsize > 0 && maxfsize < nmp->nm_maxfilesize)
388 nmp->nm_maxfilesize = maxfsize;
389 nmp->nm_mountp->mnt_stat.f_iosize = nfs_iosize(nmp);
390 nmp->nm_state |= NFSSTA_GOTFSINFO;
391 mtx_unlock(&nmp->nm_mtx);
399 * Mount a remote root fs via. nfs. This depends on the info in the
400 * nfs_diskless structure that has been filled in properly by some primary
402 * It goes something like this:
403 * - do enough of "ifconfig" by calling ifioctl() so that the system
404 * can talk to the server
405 * - If nfs_diskless.mygateway is filled in, use that address as
407 * - build the rootfs mount point and call mountnfs() to do the rest.
409 * It is assumed to be safe to read, modify, and write the nfsv3_diskless
410 * structure, as well as other global NFS client variables here, as
411 * nfs_mountroot() will be called once in the boot before any other NFS
412 * client activity occurs.
415 nfs_mountroot(struct mount *mp)
417 struct thread *td = curthread;
418 struct nfsv3_diskless *nd = &nfsv3_diskless;
427 CURVNET_SET(TD_TO_VNET(td));
429 #if defined(BOOTP_NFSROOT) && defined(BOOTP)
430 bootpc_init(); /* use bootp to get nfs_diskless filled in */
431 #elif defined(NFS_ROOT)
432 nfs_setup_diskless();
435 if (nfs_diskless_valid == 0) {
439 if (nfs_diskless_valid == 1)
440 nfs_convert_diskless();
443 * XXX splnet, so networks will receive...
448 * Do enough of ifconfig(8) so that the critical net interface can
449 * talk to the server.
451 error = socreate(nd->myif.ifra_addr.sa_family, &so, nd->root_args.sotype, 0,
454 panic("nfs_mountroot: socreate(%04x): %d",
455 nd->myif.ifra_addr.sa_family, error);
457 #if 0 /* XXX Bad idea */
459 * We might not have been told the right interface, so we pass
460 * over the first ten interfaces of the same kind, until we get
461 * one of them configured.
464 for (i = strlen(nd->myif.ifra_name) - 1;
465 nd->myif.ifra_name[i] >= '0' &&
466 nd->myif.ifra_name[i] <= '9';
467 nd->myif.ifra_name[i] ++) {
468 error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
474 error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
476 panic("nfs_mountroot: SIOCAIFADDR: %d", error);
478 if ((cp = getenv("boot.netif.mtu")) != NULL) {
479 ir.ifr_mtu = strtol(cp, NULL, 10);
480 bcopy(nd->myif.ifra_name, ir.ifr_name, IFNAMSIZ);
482 error = ifioctl(so, SIOCSIFMTU, (caddr_t)&ir, td);
484 printf("nfs_mountroot: SIOCSIFMTU: %d", error);
489 * If the gateway field is filled in, set it as the default route.
490 * Note that pxeboot will set a default route of 0 if the route
491 * is not set by the DHCP server. Check also for a value of 0
492 * to avoid panicking inappropriately in that situation.
494 if (nd->mygateway.sin_len != 0 &&
495 nd->mygateway.sin_addr.s_addr != 0) {
496 struct sockaddr_in mask, sin;
498 bzero((caddr_t)&mask, sizeof(mask));
500 sin.sin_family = AF_INET;
501 sin.sin_len = sizeof(sin);
502 /* XXX MRT use table 0 for this sort of thing */
503 error = rtrequest(RTM_ADD, (struct sockaddr *)&sin,
504 (struct sockaddr *)&nd->mygateway,
505 (struct sockaddr *)&mask,
506 RTF_UP | RTF_GATEWAY, NULL);
508 panic("nfs_mountroot: RTM_ADD: %d", error);
512 * Create the rootfs mount point.
514 nd->root_args.fh = nd->root_fh;
515 nd->root_args.fhsize = nd->root_fhsize;
516 l = ntohl(nd->root_saddr.sin_addr.s_addr);
517 snprintf(buf, sizeof(buf), "%ld.%ld.%ld.%ld:%s",
518 (l >> 24) & 0xff, (l >> 16) & 0xff,
519 (l >> 8) & 0xff, (l >> 0) & 0xff, nd->root_hostnam);
520 printf("NFS ROOT: %s\n", buf);
521 nd->root_args.hostname = buf;
522 if ((error = nfs_mountdiskless(buf,
523 &nd->root_saddr, &nd->root_args, td, &vp, mp)) != 0) {
529 * This is not really an nfs issue, but it is much easier to
530 * set hostname here and then let the "/etc/rc.xxx" files
531 * mount the right /var based upon its preset value.
533 mtx_lock(&prison0.pr_mtx);
534 strlcpy(prison0.pr_hostname, nd->my_hostnam,
535 sizeof (prison0.pr_hostname));
536 mtx_unlock(&prison0.pr_mtx);
537 inittodr(ntohl(nd->root_time));
543 * Internal version of mount system call for diskless setup.
546 nfs_mountdiskless(char *path,
547 struct sockaddr_in *sin, struct nfs_args *args, struct thread *td,
548 struct vnode **vpp, struct mount *mp)
550 struct sockaddr *nam;
553 nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK);
554 if ((error = mountnfs(args, mp, nam, path, vpp,
555 td->td_ucred, NFS_DEFAULT_NEGNAMETIMEO)) != 0) {
556 printf("nfs_mountroot: mount %s on /: %d\n", path, error);
563 nfs_sec_name_to_num(char *sec)
565 if (!strcmp(sec, "krb5"))
566 return (RPCSEC_GSS_KRB5);
567 if (!strcmp(sec, "krb5i"))
568 return (RPCSEC_GSS_KRB5I);
569 if (!strcmp(sec, "krb5p"))
570 return (RPCSEC_GSS_KRB5P);
571 if (!strcmp(sec, "sys"))
574 * Userland should validate the string but we will try and
575 * cope with unexpected values.
581 nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
582 const char *hostname)
594 * Set read-only flag if requested; otherwise, clear it if this is
595 * an update. If this is not an update, then either the read-only
596 * flag is already clear, or this is a root mount and it was set
597 * intentionally at some previous point.
599 if (vfs_getopt(mp->mnt_optnew, "ro", NULL, NULL) == 0) {
601 mp->mnt_flag |= MNT_RDONLY;
603 } else if (mp->mnt_flag & MNT_UPDATE) {
605 mp->mnt_flag &= ~MNT_RDONLY;
610 * Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes
611 * no sense in that context. Also, set up appropriate retransmit
612 * and soft timeout behavior.
614 if (argp->sotype == SOCK_STREAM) {
615 nmp->nm_flag &= ~NFSMNT_NOCONN;
616 nmp->nm_flag |= NFSMNT_DUMBTIMR;
617 nmp->nm_timeo = NFS_MAXTIMEO;
618 nmp->nm_retry = NFS_RETRANS_TCP;
621 /* Also clear RDIRPLUS if not NFSv3, it crashes some servers */
622 if ((argp->flags & NFSMNT_NFSV3) == 0)
623 nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
625 /* Re-bind if rsrvd port requested and wasn't on one */
626 adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT)
627 && (argp->flags & NFSMNT_RESVPORT);
628 /* Also re-bind if we're switching to/from a connected UDP socket */
629 adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) !=
630 (argp->flags & NFSMNT_NOCONN));
632 /* Update flags atomically. Don't change the lock bits. */
633 nmp->nm_flag = argp->flags | nmp->nm_flag;
636 if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) {
637 nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10;
638 if (nmp->nm_timeo < NFS_MINTIMEO)
639 nmp->nm_timeo = NFS_MINTIMEO;
640 else if (nmp->nm_timeo > NFS_MAXTIMEO)
641 nmp->nm_timeo = NFS_MAXTIMEO;
644 if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) {
645 nmp->nm_retry = argp->retrans;
646 if (nmp->nm_retry > NFS_MAXREXMIT)
647 nmp->nm_retry = NFS_MAXREXMIT;
650 if (argp->flags & NFSMNT_NFSV3) {
651 if (argp->sotype == SOCK_DGRAM)
652 maxio = NFS_MAXDGRAMDATA;
656 maxio = NFS_V2MAXDATA;
658 if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) {
659 nmp->nm_wsize = argp->wsize;
660 /* Round down to multiple of blocksize */
661 nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1);
662 if (nmp->nm_wsize <= 0)
663 nmp->nm_wsize = NFS_FABLKSIZE;
665 if (nmp->nm_wsize > maxio)
666 nmp->nm_wsize = maxio;
667 if (nmp->nm_wsize > MAXBSIZE)
668 nmp->nm_wsize = MAXBSIZE;
670 if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) {
671 nmp->nm_rsize = argp->rsize;
672 /* Round down to multiple of blocksize */
673 nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1);
674 if (nmp->nm_rsize <= 0)
675 nmp->nm_rsize = NFS_FABLKSIZE;
677 if (nmp->nm_rsize > maxio)
678 nmp->nm_rsize = maxio;
679 if (nmp->nm_rsize > MAXBSIZE)
680 nmp->nm_rsize = MAXBSIZE;
682 if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) {
683 nmp->nm_readdirsize = argp->readdirsize;
685 if (nmp->nm_readdirsize > maxio)
686 nmp->nm_readdirsize = maxio;
687 if (nmp->nm_readdirsize > nmp->nm_rsize)
688 nmp->nm_readdirsize = nmp->nm_rsize;
690 if ((argp->flags & NFSMNT_ACREGMIN) && argp->acregmin >= 0)
691 nmp->nm_acregmin = argp->acregmin;
693 nmp->nm_acregmin = NFS_MINATTRTIMO;
694 if ((argp->flags & NFSMNT_ACREGMAX) && argp->acregmax >= 0)
695 nmp->nm_acregmax = argp->acregmax;
697 nmp->nm_acregmax = NFS_MAXATTRTIMO;
698 if ((argp->flags & NFSMNT_ACDIRMIN) && argp->acdirmin >= 0)
699 nmp->nm_acdirmin = argp->acdirmin;
701 nmp->nm_acdirmin = NFS_MINDIRATTRTIMO;
702 if ((argp->flags & NFSMNT_ACDIRMAX) && argp->acdirmax >= 0)
703 nmp->nm_acdirmax = argp->acdirmax;
705 nmp->nm_acdirmax = NFS_MAXDIRATTRTIMO;
706 if (nmp->nm_acdirmin > nmp->nm_acdirmax)
707 nmp->nm_acdirmin = nmp->nm_acdirmax;
708 if (nmp->nm_acregmin > nmp->nm_acregmax)
709 nmp->nm_acregmin = nmp->nm_acregmax;
711 if ((argp->flags & NFSMNT_MAXGRPS) && argp->maxgrouplist >= 0) {
712 if (argp->maxgrouplist <= NFS_MAXGRPS)
713 nmp->nm_numgrps = argp->maxgrouplist;
715 nmp->nm_numgrps = NFS_MAXGRPS;
717 if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0) {
718 if (argp->readahead <= NFS_MAXRAHEAD)
719 nmp->nm_readahead = argp->readahead;
721 nmp->nm_readahead = NFS_MAXRAHEAD;
723 if ((argp->flags & NFSMNT_WCOMMITSIZE) && argp->wcommitsize >= 0) {
724 if (argp->wcommitsize < nmp->nm_wsize)
725 nmp->nm_wcommitsize = nmp->nm_wsize;
727 nmp->nm_wcommitsize = argp->wcommitsize;
729 if ((argp->flags & NFSMNT_DEADTHRESH) && argp->deadthresh >= 0) {
730 if (argp->deadthresh <= NFS_MAXDEADTHRESH)
731 nmp->nm_deadthresh = argp->deadthresh;
733 nmp->nm_deadthresh = NFS_MAXDEADTHRESH;
736 adjsock |= ((nmp->nm_sotype != argp->sotype) ||
737 (nmp->nm_soproto != argp->proto));
738 nmp->nm_sotype = argp->sotype;
739 nmp->nm_soproto = argp->proto;
741 if (nmp->nm_client && adjsock) {
742 nfs_safedisconnect(nmp);
743 if (nmp->nm_sotype == SOCK_DGRAM)
744 while (nfs_connect(nmp)) {
745 printf("nfs_args: retrying connect\n");
746 (void) tsleep(&fake_wchan, PSOCK, "nfscon", hz);
751 strlcpy(nmp->nm_hostname, hostname,
752 sizeof(nmp->nm_hostname));
753 p = strchr(nmp->nm_hostname, ':');
758 if (vfs_getopt(mp->mnt_optnew, "sec",
759 (void **) &secname, NULL) == 0) {
760 nmp->nm_secflavor = nfs_sec_name_to_num(secname);
762 nmp->nm_secflavor = AUTH_SYS;
765 if (vfs_getopt(mp->mnt_optnew, "principal",
766 (void **) &principal, NULL) == 0) {
767 strlcpy(nmp->nm_principal, principal,
768 sizeof(nmp->nm_principal));
770 snprintf(nmp->nm_principal, sizeof(nmp->nm_principal),
771 "nfs@%s", nmp->nm_hostname);
775 static const char *nfs_opts[] = { "from", "nfs_args",
776 "noatime", "noexec", "suiddir", "nosuid", "nosymfollow", "union",
777 "noclusterr", "noclusterw", "multilabel", "acls", "force", "update",
778 "async", "dumbtimer", "noconn", "nolockd", "intr", "rdirplus", "resvport",
779 "readdirsize", "soft", "hard", "mntudp", "tcp", "udp", "wsize", "rsize",
780 "retrans", "acregmin", "acregmax", "acdirmin", "acdirmax",
781 "deadthresh", "hostname", "timeout", "addr", "fh", "nfsv3", "sec",
782 "maxgroups", "principal", "negnametimeo",
789 * It seems a bit dumb to copyinstr() the host and path here and then
790 * bcopy() them in mountnfs(), but I wanted to detect errors before
791 * doing the sockargs() call because sockargs() allocates an mbuf and
792 * an error after that means that I have to release the mbuf.
796 nfs_mount(struct mount *mp)
798 struct nfs_args args = {
799 .version = NFS_ARGSVERSION,
801 .addrlen = sizeof (struct sockaddr_in),
802 .sotype = SOCK_STREAM,
806 .flags = NFSMNT_RESVPORT,
809 .readdirsize = NFS_READDIRSIZE,
811 .retrans = NFS_RETRANS,
812 .maxgrouplist = NFS_MAXGRPS,
813 .readahead = NFS_DEFRAHEAD,
814 .wcommitsize = 0, /* was: NQ_DEFLEASE */
815 .deadthresh = NFS_MAXDEADTHRESH, /* was: NQ_DEADTHRESH */
818 .acregmin = NFS_MINATTRTIMO,
819 .acregmax = NFS_MAXATTRTIMO,
820 .acdirmin = NFS_MINDIRATTRTIMO,
821 .acdirmax = NFS_MAXDIRATTRTIMO,
823 int error, ret, has_nfs_args_opt;
824 int has_addr_opt, has_fh_opt, has_hostname_opt;
825 struct sockaddr *nam;
829 u_char nfh[NFSX_V3FHMAX];
831 int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO;
833 has_nfs_args_opt = 0;
836 has_hostname_opt = 0;
838 if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) {
843 if ((mp->mnt_flag & (MNT_ROOTFS | MNT_UPDATE)) == MNT_ROOTFS) {
844 error = nfs_mountroot(mp);
849 * The old mount_nfs program passed the struct nfs_args
850 * from userspace to kernel. The new mount_nfs program
851 * passes string options via nmount() from userspace to kernel
852 * and we populate the struct nfs_args in the kernel.
854 if (vfs_getopt(mp->mnt_optnew, "nfs_args", NULL, NULL) == 0) {
855 error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args,
860 if (args.version != NFS_ARGSVERSION) {
861 error = EPROGMISMATCH;
864 has_nfs_args_opt = 1;
867 if (vfs_getopt(mp->mnt_optnew, "dumbtimer", NULL, NULL) == 0)
868 args.flags |= NFSMNT_DUMBTIMR;
869 if (vfs_getopt(mp->mnt_optnew, "noconn", NULL, NULL) == 0)
870 args.flags |= NFSMNT_NOCONN;
871 if (vfs_getopt(mp->mnt_optnew, "conn", NULL, NULL) == 0)
872 args.flags |= NFSMNT_NOCONN;
873 if (vfs_getopt(mp->mnt_optnew, "nolockd", NULL, NULL) == 0)
874 args.flags |= NFSMNT_NOLOCKD;
875 if (vfs_getopt(mp->mnt_optnew, "lockd", NULL, NULL) == 0)
876 args.flags &= ~NFSMNT_NOLOCKD;
877 if (vfs_getopt(mp->mnt_optnew, "intr", NULL, NULL) == 0)
878 args.flags |= NFSMNT_INT;
879 if (vfs_getopt(mp->mnt_optnew, "rdirplus", NULL, NULL) == 0)
880 args.flags |= NFSMNT_RDIRPLUS;
881 if (vfs_getopt(mp->mnt_optnew, "resvport", NULL, NULL) == 0)
882 args.flags |= NFSMNT_RESVPORT;
883 if (vfs_getopt(mp->mnt_optnew, "noresvport", NULL, NULL) == 0)
884 args.flags &= ~NFSMNT_RESVPORT;
885 if (vfs_getopt(mp->mnt_optnew, "soft", NULL, NULL) == 0)
886 args.flags |= NFSMNT_SOFT;
887 if (vfs_getopt(mp->mnt_optnew, "hard", NULL, NULL) == 0)
888 args.flags &= ~NFSMNT_SOFT;
889 if (vfs_getopt(mp->mnt_optnew, "mntudp", NULL, NULL) == 0)
890 args.sotype = SOCK_DGRAM;
891 if (vfs_getopt(mp->mnt_optnew, "udp", NULL, NULL) == 0)
892 args.sotype = SOCK_DGRAM;
893 if (vfs_getopt(mp->mnt_optnew, "tcp", NULL, NULL) == 0)
894 args.sotype = SOCK_STREAM;
895 if (vfs_getopt(mp->mnt_optnew, "nfsv3", NULL, NULL) == 0)
896 args.flags |= NFSMNT_NFSV3;
897 if (vfs_getopt(mp->mnt_optnew, "readdirsize", (void **)&opt, NULL) == 0) {
899 vfs_mount_error(mp, "illegal readdirsize");
903 ret = sscanf(opt, "%d", &args.readdirsize);
904 if (ret != 1 || args.readdirsize <= 0) {
905 vfs_mount_error(mp, "illegal readdirsize: %s",
910 args.flags |= NFSMNT_READDIRSIZE;
912 if (vfs_getopt(mp->mnt_optnew, "readahead", (void **)&opt, NULL) == 0) {
914 vfs_mount_error(mp, "illegal readahead");
918 ret = sscanf(opt, "%d", &args.readahead);
919 if (ret != 1 || args.readahead <= 0) {
920 vfs_mount_error(mp, "illegal readahead: %s",
925 args.flags |= NFSMNT_READAHEAD;
927 if (vfs_getopt(mp->mnt_optnew, "wsize", (void **)&opt, NULL) == 0) {
929 vfs_mount_error(mp, "illegal wsize");
933 ret = sscanf(opt, "%d", &args.wsize);
934 if (ret != 1 || args.wsize <= 0) {
935 vfs_mount_error(mp, "illegal wsize: %s",
940 args.flags |= NFSMNT_WSIZE;
942 if (vfs_getopt(mp->mnt_optnew, "rsize", (void **)&opt, NULL) == 0) {
944 vfs_mount_error(mp, "illegal rsize");
948 ret = sscanf(opt, "%d", &args.rsize);
949 if (ret != 1 || args.rsize <= 0) {
950 vfs_mount_error(mp, "illegal wsize: %s",
955 args.flags |= NFSMNT_RSIZE;
957 if (vfs_getopt(mp->mnt_optnew, "retrans", (void **)&opt, NULL) == 0) {
959 vfs_mount_error(mp, "illegal retrans");
963 ret = sscanf(opt, "%d", &args.retrans);
964 if (ret != 1 || args.retrans <= 0) {
965 vfs_mount_error(mp, "illegal retrans: %s",
970 args.flags |= NFSMNT_RETRANS;
972 if (vfs_getopt(mp->mnt_optnew, "acregmin", (void **)&opt, NULL) == 0) {
973 ret = sscanf(opt, "%d", &args.acregmin);
974 if (ret != 1 || args.acregmin < 0) {
975 vfs_mount_error(mp, "illegal acregmin: %s",
980 args.flags |= NFSMNT_ACREGMIN;
982 if (vfs_getopt(mp->mnt_optnew, "acregmax", (void **)&opt, NULL) == 0) {
983 ret = sscanf(opt, "%d", &args.acregmax);
984 if (ret != 1 || args.acregmax < 0) {
985 vfs_mount_error(mp, "illegal acregmax: %s",
990 args.flags |= NFSMNT_ACREGMAX;
992 if (vfs_getopt(mp->mnt_optnew, "acdirmin", (void **)&opt, NULL) == 0) {
993 ret = sscanf(opt, "%d", &args.acdirmin);
994 if (ret != 1 || args.acdirmin < 0) {
995 vfs_mount_error(mp, "illegal acdirmin: %s",
1000 args.flags |= NFSMNT_ACDIRMIN;
1002 if (vfs_getopt(mp->mnt_optnew, "acdirmax", (void **)&opt, NULL) == 0) {
1003 ret = sscanf(opt, "%d", &args.acdirmax);
1004 if (ret != 1 || args.acdirmax < 0) {
1005 vfs_mount_error(mp, "illegal acdirmax: %s",
1010 args.flags |= NFSMNT_ACDIRMAX;
1012 if (vfs_getopt(mp->mnt_optnew, "deadthresh", (void **)&opt, NULL) == 0) {
1013 ret = sscanf(opt, "%d", &args.deadthresh);
1014 if (ret != 1 || args.deadthresh <= 0) {
1015 vfs_mount_error(mp, "illegal deadthresh: %s",
1020 args.flags |= NFSMNT_DEADTHRESH;
1022 if (vfs_getopt(mp->mnt_optnew, "timeout", (void **)&opt, NULL) == 0) {
1023 ret = sscanf(opt, "%d", &args.timeo);
1024 if (ret != 1 || args.timeo <= 0) {
1025 vfs_mount_error(mp, "illegal timeout: %s",
1030 args.flags |= NFSMNT_TIMEO;
1032 if (vfs_getopt(mp->mnt_optnew, "maxgroups", (void **)&opt, NULL) == 0) {
1033 ret = sscanf(opt, "%d", &args.maxgrouplist);
1034 if (ret != 1 || args.maxgrouplist <= 0) {
1035 vfs_mount_error(mp, "illegal maxgroups: %s",
1040 args.flags |= NFSMNT_MAXGRPS;
1042 if (vfs_getopt(mp->mnt_optnew, "negnametimeo", (void **)&opt, NULL)
1044 ret = sscanf(opt, "%d", &negnametimeo);
1045 if (ret != 1 || negnametimeo < 0) {
1046 vfs_mount_error(mp, "illegal negnametimeo: %s",
1052 if (vfs_getopt(mp->mnt_optnew, "addr", (void **)&args.addr,
1053 &args.addrlen) == 0) {
1055 if (args.addrlen > SOCK_MAXADDRLEN) {
1056 error = ENAMETOOLONG;
1059 nam = malloc(args.addrlen, M_SONAME,
1061 bcopy(args.addr, nam, args.addrlen);
1062 nam->sa_len = args.addrlen;
1064 if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh,
1065 &args.fhsize) == 0) {
1068 if (vfs_getopt(mp->mnt_optnew, "hostname", (void **)&args.hostname,
1070 has_hostname_opt = 1;
1072 if (args.hostname == NULL) {
1073 vfs_mount_error(mp, "Invalid hostname");
1077 if (args.fhsize < 0 || args.fhsize > NFSX_V3FHMAX) {
1078 vfs_mount_error(mp, "Bad file handle");
1083 if (mp->mnt_flag & MNT_UPDATE) {
1084 struct nfsmount *nmp = VFSTONFS(mp);
1091 * When doing an update, we can't change from or to
1092 * v3, switch lockd strategies or change cookie translation
1094 args.flags = (args.flags &
1095 ~(NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) |
1097 (NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
1098 nfs_decode_args(mp, nmp, &args, NULL);
1103 * Make the nfs_ip_paranoia sysctl serve as the default connection
1104 * or no-connection mode for those protocols that support
1105 * no-connection mode (the flag will be cleared later for protocols
1106 * that do not support no-connection mode). This will allow a client
1107 * to receive replies from a different IP then the request was
1108 * sent to. Note: default value for nfs_ip_paranoia is 1 (paranoid),
1111 if (nfs_ip_paranoia == 0)
1112 args.flags |= NFSMNT_NOCONN;
1114 if (has_nfs_args_opt) {
1116 * In the 'nfs_args' case, the pointers in the args
1117 * structure are in userland - we copy them in here.
1120 error = copyin((caddr_t)args.fh, (caddr_t)nfh,
1127 if (!has_hostname_opt) {
1128 error = copyinstr(args.hostname, hst, MNAMELEN-1, &len);
1132 bzero(&hst[len], MNAMELEN - len);
1133 args.hostname = hst;
1135 if (!has_addr_opt) {
1136 /* sockargs() call must be after above copyin() calls */
1137 error = getsockaddr(&nam, (caddr_t)args.addr,
1144 error = mountnfs(&args, mp, nam, args.hostname, &vp,
1145 curthread->td_ucred, negnametimeo);
1149 mp->mnt_kern_flag |= (MNTK_MPSAFE|MNTK_LOOKUP_SHARED);
1160 * It seems a bit dumb to copyinstr() the host and path here and then
1161 * bcopy() them in mountnfs(), but I wanted to detect errors before
1162 * doing the sockargs() call because sockargs() allocates an mbuf and
1163 * an error after that means that I have to release the mbuf.
1167 nfs_cmount(struct mntarg *ma, void *data, int flags)
1170 struct nfs_args args;
1172 error = copyin(data, &args, sizeof (struct nfs_args));
1176 ma = mount_arg(ma, "nfs_args", &args, sizeof args);
1178 error = kernel_mount(ma, flags);
1183 * Common code for mount and mountroot
1186 mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
1187 char *hst, struct vnode **vpp, struct ucred *cred, int negnametimeo)
1189 struct nfsmount *nmp;
1194 if (mp->mnt_flag & MNT_UPDATE) {
1196 printf("%s: MNT_UPDATE is no longer handled here\n", __func__);
1197 free(nam, M_SONAME);
1200 nmp = uma_zalloc(nfsmount_zone, M_WAITOK);
1201 bzero((caddr_t)nmp, sizeof (struct nfsmount));
1202 TAILQ_INIT(&nmp->nm_bufq);
1206 nmp->nm_mountp = mp;
1207 mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF);
1210 * V2 can only handle 32 bit filesizes. A 4GB-1 limit may be too
1211 * high, depending on whether we end up with negative offsets in
1212 * the client or server somewhere. 2GB-1 may be safer.
1214 * For V3, nfs_fsinfo will adjust this as necessary. Assume maximum
1215 * that we can handle until we find out otherwise.
1216 * XXX Our "safe" limit on the client is what we can store in our
1217 * buffer cache using signed(!) block numbers.
1219 if ((argp->flags & NFSMNT_NFSV3) == 0)
1220 nmp->nm_maxfilesize = 0xffffffffLL;
1222 nmp->nm_maxfilesize = (u_int64_t)0x80000000 * DEV_BSIZE - 1;
1224 nmp->nm_timeo = NFS_TIMEO;
1225 nmp->nm_retry = NFS_RETRANS;
1226 if ((argp->flags & NFSMNT_NFSV3) && argp->sotype == SOCK_STREAM) {
1227 nmp->nm_wsize = nmp->nm_rsize = NFS_MAXDATA;
1229 nmp->nm_wsize = NFS_WSIZE;
1230 nmp->nm_rsize = NFS_RSIZE;
1232 nmp->nm_wcommitsize = hibufspace / (desiredvnodes / 1000);
1233 nmp->nm_readdirsize = NFS_READDIRSIZE;
1234 nmp->nm_numgrps = NFS_MAXGRPS;
1235 nmp->nm_readahead = NFS_DEFRAHEAD;
1236 nmp->nm_deadthresh = NFS_MAXDEADTHRESH;
1237 nmp->nm_negnametimeo = negnametimeo;
1238 nmp->nm_tprintf_delay = nfs_tprintf_delay;
1239 if (nmp->nm_tprintf_delay < 0)
1240 nmp->nm_tprintf_delay = 0;
1241 nmp->nm_tprintf_initial_delay = nfs_tprintf_initial_delay;
1242 if (nmp->nm_tprintf_initial_delay < 0)
1243 nmp->nm_tprintf_initial_delay = 0;
1244 nmp->nm_fhsize = argp->fhsize;
1245 bcopy((caddr_t)argp->fh, (caddr_t)nmp->nm_fh, argp->fhsize);
1246 bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);
1248 /* Set up the sockets and per-host congestion */
1249 nmp->nm_sotype = argp->sotype;
1250 nmp->nm_soproto = argp->proto;
1251 nmp->nm_rpcops = &nfs_rpcops;
1253 nfs_decode_args(mp, nmp, argp, hst);
1256 * For Connection based sockets (TCP,...) defer the connect until
1257 * the first request, in case the server is not responding.
1259 if (nmp->nm_sotype == SOCK_DGRAM &&
1260 (error = nfs_connect(nmp)))
1264 * This is silly, but it has to be set so that vinifod() works.
1265 * We do not want to do an nfs_statfs() here since we can get
1266 * stuck on a dead server and we are holding a lock on the mount
1269 mtx_lock(&nmp->nm_mtx);
1270 mp->mnt_stat.f_iosize = nfs_iosize(nmp);
1271 mtx_unlock(&nmp->nm_mtx);
1273 * A reference count is needed on the nfsnode representing the
1274 * remote root. If this object is not persistent, then backward
1275 * traversals of the mount point (i.e. "..") will not work if
1276 * the nfsnode gets flushed out of the cache. Ufs does not have
1277 * this problem, because one can identify root inodes by their
1278 * number == ROOTINO (2).
1280 error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
1286 * Get file attributes and transfer parameters for the
1287 * mountpoint. This has the side effect of filling in
1288 * (*vpp)->v_type with the correct value.
1290 if (argp->flags & NFSMNT_NFSV3)
1291 nfs_fsinfo(nmp, *vpp, curthread->td_ucred, curthread);
1293 VOP_GETATTR(*vpp, &attrs, curthread->td_ucred);
1296 * Lose the lock but keep the ref.
1298 VOP_UNLOCK(*vpp, 0);
1302 nfs_disconnect(nmp);
1303 mtx_destroy(&nmp->nm_mtx);
1304 uma_zfree(nfsmount_zone, nmp);
1305 free(nam, M_SONAME);
1310 * unmount system call
1313 nfs_unmount(struct mount *mp, int mntflags)
1315 struct nfsmount *nmp;
1316 int error, flags = 0;
1318 if (mntflags & MNT_FORCE)
1319 flags |= FORCECLOSE;
1322 * Goes something like this..
1323 * - Call vflush() to clear out vnodes for this filesystem
1324 * - Close the socket
1325 * - Free up the data structures
1327 /* In the forced case, cancel any outstanding requests. */
1328 if (flags & FORCECLOSE) {
1329 error = nfs_nmcancelreqs(nmp);
1333 /* We hold 1 extra ref on the root vnode; see comment in mountnfs(). */
1334 error = vflush(mp, 1, flags, curthread);
1339 * We are now committed to the unmount.
1341 nfs_disconnect(nmp);
1342 free(nmp->nm_nam, M_SONAME);
1344 mtx_destroy(&nmp->nm_mtx);
1345 uma_zfree(nfsmount_zone, nmp);
1351 * Return root of a filesystem
1354 nfs_root(struct mount *mp, int flags, struct vnode **vpp)
1357 struct nfsmount *nmp;
1362 error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, flags);
1367 * Get transfer parameters and attributes for root vnode once.
1369 mtx_lock(&nmp->nm_mtx);
1370 if ((nmp->nm_state & NFSSTA_GOTFSINFO) == 0 &&
1371 (nmp->nm_flag & NFSMNT_NFSV3)) {
1372 mtx_unlock(&nmp->nm_mtx);
1373 nfs_fsinfo(nmp, vp, curthread->td_ucred, curthread);
1375 mtx_unlock(&nmp->nm_mtx);
1376 if (vp->v_type == VNON)
1378 vp->v_vflag |= VV_ROOT;
1384 * Flush out the buffer cache
1388 nfs_sync(struct mount *mp, int waitfor)
1390 struct vnode *vp, *mvp;
1392 int error, allerror = 0;
1397 * Force stale buffer cache information to be flushed.
1401 MNT_VNODE_FOREACH(vp, mp, mvp) {
1404 /* XXX Racy bv_cnt check. */
1405 if (VOP_ISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
1406 waitfor == MNT_LAZY) {
1411 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
1413 MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp);
1416 error = VOP_FSYNC(vp, waitfor, td);
1429 nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req)
1431 struct nfsmount *nmp = VFSTONFS(mp);
1435 bzero(&vq, sizeof(vq));
1438 case VFS_CTL_NOLOCKS:
1439 val = (nmp->nm_flag & NFSMNT_NOLOCKS) ? 1 : 0;
1440 if (req->oldptr != NULL) {
1441 error = SYSCTL_OUT(req, &val, sizeof(val));
1445 if (req->newptr != NULL) {
1446 error = SYSCTL_IN(req, &val, sizeof(val));
1450 nmp->nm_flag |= NFSMNT_NOLOCKS;
1452 nmp->nm_flag &= ~NFSMNT_NOLOCKS;
1457 mtx_lock(&nmp->nm_mtx);
1458 if (nmp->nm_state & NFSSTA_TIMEO)
1459 vq.vq_flags |= VQ_NOTRESP;
1460 mtx_unlock(&nmp->nm_mtx);
1462 if (!(nmp->nm_flag & NFSMNT_NOLOCKS) &&
1463 (nmp->nm_state & NFSSTA_LOCKTIMEO))
1464 vq.vq_flags |= VQ_NOTRESPLOCK;
1466 error = SYSCTL_OUT(req, &vq, sizeof(vq));
1469 if (req->oldptr != NULL) {
1470 error = SYSCTL_OUT(req, &nmp->nm_tprintf_initial_delay,
1471 sizeof(nmp->nm_tprintf_initial_delay));
1475 if (req->newptr != NULL) {
1476 error = vfs_suser(mp, req->td);
1479 error = SYSCTL_IN(req, &nmp->nm_tprintf_initial_delay,
1480 sizeof(nmp->nm_tprintf_initial_delay));
1483 if (nmp->nm_tprintf_initial_delay < 0)
1484 nmp->nm_tprintf_initial_delay = 0;