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 * from nfs_vfsops.c 8.12 (Berkeley) 5/20/95
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
39 #include "opt_bootp.h"
40 #include "opt_nfsroot.h"
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
47 #include <sys/clock.h>
49 #include <sys/limits.h>
51 #include <sys/malloc.h>
53 #include <sys/module.h>
54 #include <sys/mount.h>
56 #include <sys/socket.h>
57 #include <sys/socketvar.h>
58 #include <sys/sockio.h>
59 #include <sys/sysctl.h>
60 #include <sys/vnode.h>
61 #include <sys/signalvar.h>
64 #include <vm/vm_extern.h>
68 #include <net/route.h>
69 #include <netinet/in.h>
71 #include <fs/nfs/nfsport.h>
72 #include <fs/nfsclient/nfsnode.h>
73 #include <fs/nfsclient/nfsmount.h>
74 #include <fs/nfsclient/nfs.h>
75 #include <fs/nfsclient/nfsdiskless.h>
77 extern int nfscl_ticks;
78 extern struct timeval nfsboottime;
79 extern struct nfsstats newnfsstats;
81 MALLOC_DEFINE(M_NEWNFSREQ, "newnfsclient_req", "New NFS request header");
82 MALLOC_DEFINE(M_NEWNFSMNT, "newnfsmnt", "New NFS mount struct");
84 SYSCTL_DECL(_vfs_newnfs);
85 SYSCTL_STRUCT(_vfs_newnfs, NFS_NFSSTATS, nfsstats, CTLFLAG_RW,
86 &newnfsstats, nfsstats, "S,nfsstats");
87 static int nfs_ip_paranoia = 1;
88 SYSCTL_INT(_vfs_newnfs, OID_AUTO, nfs_ip_paranoia, CTLFLAG_RW,
89 &nfs_ip_paranoia, 0, "");
90 static int nfs_tprintf_initial_delay = NFS_TPRINTF_INITIAL_DELAY;
91 SYSCTL_INT(_vfs_newnfs, NFS_TPRINTF_INITIAL_DELAY,
92 downdelayinitial, CTLFLAG_RW, &nfs_tprintf_initial_delay, 0, "");
93 /* how long between console messages "nfs server foo not responding" */
94 static int nfs_tprintf_delay = NFS_TPRINTF_DELAY;
95 SYSCTL_INT(_vfs_newnfs, NFS_TPRINTF_DELAY,
96 downdelayinterval, CTLFLAG_RW, &nfs_tprintf_delay, 0, "");
98 static void nfs_sec_name(char *, int *);
99 static void nfs_decode_args(struct mount *mp, struct nfsmount *nmp,
100 struct nfs_args *argp, const char *, struct ucred *,
102 static int mountnfs(struct nfs_args *, struct mount *,
103 struct sockaddr *, char *, u_char *, u_char *, u_char *,
104 struct vnode **, struct ucred *, struct thread *, int);
105 static void nfs_getnlminfo(struct vnode *, uint8_t *, size_t *,
106 struct sockaddr_storage *, int *, off_t *,
108 static vfs_mount_t nfs_mount;
109 static vfs_cmount_t nfs_cmount;
110 static vfs_unmount_t nfs_unmount;
111 static vfs_root_t nfs_root;
112 static vfs_statfs_t nfs_statfs;
113 static vfs_sync_t nfs_sync;
114 static vfs_sysctl_t nfs_sysctl;
117 * nfs vfs operations.
119 static struct vfsops nfs_vfsops = {
120 .vfs_init = ncl_init,
121 .vfs_mount = nfs_mount,
122 .vfs_cmount = nfs_cmount,
123 .vfs_root = nfs_root,
124 .vfs_statfs = nfs_statfs,
125 .vfs_sync = nfs_sync,
126 .vfs_uninit = ncl_uninit,
127 .vfs_unmount = nfs_unmount,
128 .vfs_sysctl = nfs_sysctl,
130 VFS_SET(nfs_vfsops, newnfs, VFCF_NETWORK);
132 /* So that loader and kldload(2) can find us, wherever we are.. */
133 MODULE_VERSION(newnfs, 1);
136 * This structure must be filled in by a primary bootstrap or bootstrap
137 * server for a diskless/dataless machine. It is initialized below just
138 * to ensure that it is allocated to initialized data (.data not .bss).
140 struct nfs_diskless newnfs_diskless = { { { 0 } } };
141 struct nfsv3_diskless newnfsv3_diskless = { { { 0 } } };
142 int newnfs_diskless_valid = 0;
144 SYSCTL_INT(_vfs_newnfs, OID_AUTO, diskless_valid, CTLFLAG_RD,
145 &newnfs_diskless_valid, 0,
146 "Has the diskless struct been filled correctly");
148 SYSCTL_STRING(_vfs_newnfs, OID_AUTO, diskless_rootpath, CTLFLAG_RD,
149 newnfsv3_diskless.root_hostnam, 0, "Path to nfs root");
151 SYSCTL_OPAQUE(_vfs_newnfs, OID_AUTO, diskless_rootaddr, CTLFLAG_RD,
152 &newnfsv3_diskless.root_saddr, sizeof newnfsv3_diskless.root_saddr,
153 "%Ssockaddr_in", "Diskless root nfs address");
156 void newnfsargs_ntoh(struct nfs_args *);
157 static int nfs_mountdiskless(char *,
158 struct sockaddr_in *, struct nfs_args *,
159 struct thread *, struct vnode **, struct mount *);
160 static void nfs_convert_diskless(void);
161 static void nfs_convert_oargs(struct nfs_args *args,
162 struct onfs_args *oargs);
165 newnfs_iosize(struct nfsmount *nmp)
169 /* First, set the upper limit for iosize */
170 if (nmp->nm_flag & NFSMNT_NFSV4) {
171 maxio = NFS_MAXBSIZE;
172 } else if (nmp->nm_flag & NFSMNT_NFSV3) {
173 if (nmp->nm_sotype == SOCK_DGRAM)
174 maxio = NFS_MAXDGRAMDATA;
176 maxio = NFS_MAXBSIZE;
178 maxio = NFS_V2MAXDATA;
180 if (nmp->nm_rsize > maxio || nmp->nm_rsize == 0)
181 nmp->nm_rsize = maxio;
182 if (nmp->nm_rsize > MAXBSIZE)
183 nmp->nm_rsize = MAXBSIZE;
184 if (nmp->nm_readdirsize > maxio || nmp->nm_readdirsize == 0)
185 nmp->nm_readdirsize = maxio;
186 if (nmp->nm_readdirsize > nmp->nm_rsize)
187 nmp->nm_readdirsize = nmp->nm_rsize;
188 if (nmp->nm_wsize > maxio || nmp->nm_wsize == 0)
189 nmp->nm_wsize = maxio;
190 if (nmp->nm_wsize > MAXBSIZE)
191 nmp->nm_wsize = MAXBSIZE;
194 * Calculate the size used for io buffers. Use the larger
195 * of the two sizes to minimise nfs requests but make sure
196 * that it is at least one VM page to avoid wasting buffer
199 iosize = imax(nmp->nm_rsize, nmp->nm_wsize);
200 iosize = imax(iosize, PAGE_SIZE);
201 nmp->nm_mountp->mnt_stat.f_iosize = iosize;
206 nfs_convert_oargs(struct nfs_args *args, struct onfs_args *oargs)
209 args->version = NFS_ARGSVERSION;
210 args->addr = oargs->addr;
211 args->addrlen = oargs->addrlen;
212 args->sotype = oargs->sotype;
213 args->proto = oargs->proto;
214 args->fh = oargs->fh;
215 args->fhsize = oargs->fhsize;
216 args->flags = oargs->flags;
217 args->wsize = oargs->wsize;
218 args->rsize = oargs->rsize;
219 args->readdirsize = oargs->readdirsize;
220 args->timeo = oargs->timeo;
221 args->retrans = oargs->retrans;
222 args->readahead = oargs->readahead;
223 args->hostname = oargs->hostname;
227 nfs_convert_diskless(void)
230 bcopy(&newnfs_diskless.myif, &newnfsv3_diskless.myif,
231 sizeof (struct ifaliasreq));
232 bcopy(&newnfs_diskless.mygateway, &newnfsv3_diskless.mygateway,
233 sizeof (struct sockaddr_in));
234 nfs_convert_oargs(&newnfsv3_diskless.root_args,
235 &newnfs_diskless.root_args);
236 if (newnfsv3_diskless.root_args.flags & NFSMNT_NFSV3) {
237 newnfsv3_diskless.root_fhsize = NFSX_MYFH;
238 bcopy(newnfs_diskless.root_fh, newnfsv3_diskless.root_fh,
241 newnfsv3_diskless.root_fhsize = NFSX_V2FH;
242 bcopy(newnfs_diskless.root_fh, newnfsv3_diskless.root_fh,
245 bcopy(&newnfs_diskless.root_saddr,&newnfsv3_diskless.root_saddr,
246 sizeof(struct sockaddr_in));
247 bcopy(newnfs_diskless.root_hostnam, newnfsv3_diskless.root_hostnam,
249 newnfsv3_diskless.root_time = newnfs_diskless.root_time;
250 bcopy(newnfs_diskless.my_hostnam, newnfsv3_diskless.my_hostnam,
252 newnfs_diskless_valid = 3;
259 nfs_statfs(struct mount *mp, struct statfs *sbp)
263 struct nfsmount *nmp = VFSTONFS(mp);
264 struct nfsvattr nfsva;
267 int error = 0, attrflag, gotfsinfo = 0, ret;
272 error = vfs_busy(mp, MBF_NOWAIT);
275 error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
281 mtx_lock(&nmp->nm_mtx);
282 if (NFSHASNFSV3(nmp) && !NFSHASGOTFSINFO(nmp)) {
283 mtx_unlock(&nmp->nm_mtx);
284 error = nfsrpc_fsinfo(vp, &fs, td->td_ucred, td, &nfsva,
289 mtx_unlock(&nmp->nm_mtx);
291 error = nfsrpc_statfs(vp, &sb, &fs, td->td_ucred, td, &nfsva,
294 ret = nfsrpc_getattrnovp(nmp, nmp->nm_fh, nmp->nm_fhsize, 1,
295 td->td_ucred, td, &nfsva, NULL);
298 * Just set default values to get things going.
300 NFSBZERO((caddr_t)&nfsva, sizeof (struct nfsvattr));
301 nfsva.na_vattr.va_type = VDIR;
302 nfsva.na_vattr.va_mode = 0777;
303 nfsva.na_vattr.va_nlink = 100;
304 nfsva.na_vattr.va_uid = (uid_t)0;
305 nfsva.na_vattr.va_gid = (gid_t)0;
306 nfsva.na_vattr.va_fileid = 2;
307 nfsva.na_vattr.va_gen = 1;
308 nfsva.na_vattr.va_blocksize = NFS_FABLKSIZE;
309 nfsva.na_vattr.va_size = 512 * 1024;
312 (void) nfscl_loadattrcache(&vp, &nfsva, NULL, NULL, 0, 1);
314 mtx_lock(&nmp->nm_mtx);
315 if (gotfsinfo || (nmp->nm_flag & NFSMNT_NFSV4))
316 nfscl_loadfsinfo(nmp, &fs);
317 nfscl_loadsbinfo(nmp, &sb, sbp);
318 sbp->f_flags = nmp->nm_flag;
319 sbp->f_iosize = newnfs_iosize(nmp);
320 mtx_unlock(&nmp->nm_mtx);
321 if (sbp != &mp->mnt_stat) {
322 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
323 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
325 strncpy(&sbp->f_fstypename[0], mp->mnt_vfc->vfc_name, MFSNAMELEN);
326 } else if (NFS_ISV4(vp)) {
327 error = nfscl_maperr(td, error, (uid_t)0, (gid_t)0);
335 * nfs version 3 fsinfo rpc call
338 ncl_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct ucred *cred,
342 struct nfsvattr nfsva;
345 error = nfsrpc_fsinfo(vp, &fs, cred, td, &nfsva, &attrflag, NULL);
348 (void) nfscl_loadattrcache(&vp, &nfsva, NULL, NULL, 0,
350 mtx_lock(&nmp->nm_mtx);
351 nfscl_loadfsinfo(nmp, &fs);
352 mtx_unlock(&nmp->nm_mtx);
358 * Mount a remote root fs via. nfs. This depends on the info in the
359 * newnfs_diskless structure that has been filled in properly by some primary
361 * It goes something like this:
362 * - do enough of "ifconfig" by calling ifioctl() so that the system
363 * can talk to the server
364 * - If newnfs_diskless.mygateway is filled in, use that address as
366 * - build the rootfs mount point and call mountnfs() to do the rest.
368 * It is assumed to be safe to read, modify, and write the nfsv3_diskless
369 * structure, as well as other global NFS client variables here, as
370 * nfs_mountroot() will be called once in the boot before any other NFS
371 * client activity occurs.
374 ncl_mountroot(struct mount *mp)
376 struct thread *td = curthread;
377 struct nfsv3_diskless *nd = &newnfsv3_diskless;
386 #if defined(BOOTP_NFSROOT) && defined(BOOTP)
387 bootpc_init(); /* use bootp to get nfs_diskless filled in */
388 #elif defined(NFS_ROOT)
389 nfs_setup_diskless();
392 if (newnfs_diskless_valid == 0)
394 if (newnfs_diskless_valid == 1)
395 nfs_convert_diskless();
398 * XXX splnet, so networks will receive...
403 * Do enough of ifconfig(8) so that the critical net interface can
404 * talk to the server.
406 error = socreate(nd->myif.ifra_addr.sa_family, &so, nd->root_args.sotype, 0,
409 panic("nfs_mountroot: socreate(%04x): %d",
410 nd->myif.ifra_addr.sa_family, error);
412 #if 0 /* XXX Bad idea */
414 * We might not have been told the right interface, so we pass
415 * over the first ten interfaces of the same kind, until we get
416 * one of them configured.
419 for (i = strlen(nd->myif.ifra_name) - 1;
420 nd->myif.ifra_name[i] >= '0' &&
421 nd->myif.ifra_name[i] <= '9';
422 nd->myif.ifra_name[i] ++) {
423 error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
428 error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
430 panic("nfs_mountroot: SIOCAIFADDR: %d", error);
431 if ((cp = getenv("boot.netif.mtu")) != NULL) {
432 ir.ifr_mtu = strtol(cp, NULL, 10);
433 bcopy(nd->myif.ifra_name, ir.ifr_name, IFNAMSIZ);
435 error = ifioctl(so, SIOCSIFMTU, (caddr_t)&ir, td);
437 printf("nfs_mountroot: SIOCSIFMTU: %d", error);
442 * If the gateway field is filled in, set it as the default route.
443 * Note that pxeboot will set a default route of 0 if the route
444 * is not set by the DHCP server. Check also for a value of 0
445 * to avoid panicking inappropriately in that situation.
447 if (nd->mygateway.sin_len != 0 &&
448 nd->mygateway.sin_addr.s_addr != 0) {
449 struct sockaddr_in mask, sin;
451 bzero((caddr_t)&mask, sizeof(mask));
453 sin.sin_family = AF_INET;
454 sin.sin_len = sizeof(sin);
455 /* XXX MRT use table 0 for this sort of thing */
456 CURVNET_SET(TD_TO_VNET(td));
457 error = rtrequest(RTM_ADD, (struct sockaddr *)&sin,
458 (struct sockaddr *)&nd->mygateway,
459 (struct sockaddr *)&mask,
460 RTF_UP | RTF_GATEWAY, NULL);
463 panic("nfs_mountroot: RTM_ADD: %d", error);
467 * Create the rootfs mount point.
469 nd->root_args.fh = nd->root_fh;
470 nd->root_args.fhsize = nd->root_fhsize;
471 l = ntohl(nd->root_saddr.sin_addr.s_addr);
472 snprintf(buf, sizeof(buf), "%ld.%ld.%ld.%ld:%s",
473 (l >> 24) & 0xff, (l >> 16) & 0xff,
474 (l >> 8) & 0xff, (l >> 0) & 0xff, nd->root_hostnam);
475 printf("NFS ROOT: %s\n", buf);
476 nd->root_args.hostname = buf;
477 if ((error = nfs_mountdiskless(buf,
478 &nd->root_saddr, &nd->root_args, td, &vp, mp)) != 0) {
483 * This is not really an nfs issue, but it is much easier to
484 * set hostname here and then let the "/etc/rc.xxx" files
485 * mount the right /var based upon its preset value.
487 mtx_lock(&prison0.pr_mtx);
488 strlcpy(prison0.pr_hostname, nd->my_hostnam,
489 sizeof(prison0.pr_hostname));
490 mtx_unlock(&prison0.pr_mtx);
491 inittodr(ntohl(nd->root_time));
496 * Internal version of mount system call for diskless setup.
499 nfs_mountdiskless(char *path,
500 struct sockaddr_in *sin, struct nfs_args *args, struct thread *td,
501 struct vnode **vpp, struct mount *mp)
503 struct sockaddr *nam;
506 nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK);
507 if ((error = mountnfs(args, mp, nam, path, NULL, NULL, NULL, vpp,
508 td->td_ucred, td, NFS_DEFAULT_NEGNAMETIMEO)) != 0) {
509 printf("nfs_mountroot: mount %s on /: %d\n", path, error);
516 nfs_sec_name(char *sec, int *flagsp)
518 if (!strcmp(sec, "krb5"))
519 *flagsp |= NFSMNT_KERB;
520 else if (!strcmp(sec, "krb5i"))
521 *flagsp |= (NFSMNT_KERB | NFSMNT_INTEGRITY);
522 else if (!strcmp(sec, "krb5p"))
523 *flagsp |= (NFSMNT_KERB | NFSMNT_PRIVACY);
527 nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
528 const char *hostname, struct ucred *cred, struct thread *td)
537 * Set read-only flag if requested; otherwise, clear it if this is
538 * an update. If this is not an update, then either the read-only
539 * flag is already clear, or this is a root mount and it was set
540 * intentionally at some previous point.
542 if (vfs_getopt(mp->mnt_optnew, "ro", NULL, NULL) == 0) {
544 mp->mnt_flag |= MNT_RDONLY;
546 } else if (mp->mnt_flag & MNT_UPDATE) {
548 mp->mnt_flag &= ~MNT_RDONLY;
553 * Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes
554 * no sense in that context. Also, set up appropriate retransmit
555 * and soft timeout behavior.
557 if (argp->sotype == SOCK_STREAM) {
558 nmp->nm_flag &= ~NFSMNT_NOCONN;
559 nmp->nm_timeo = NFS_MAXTIMEO;
560 if ((argp->flags & NFSMNT_NFSV4) != 0)
561 nmp->nm_retry = INT_MAX;
563 nmp->nm_retry = NFS_RETRANS_TCP;
566 /* Also clear RDIRPLUS if NFSv2, it crashes some servers */
567 if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0) {
568 argp->flags &= ~NFSMNT_RDIRPLUS;
569 nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
572 /* Clear NFSMNT_RESVPORT for NFSv4, since it is not required. */
573 if ((argp->flags & NFSMNT_NFSV4) != 0) {
574 argp->flags &= ~NFSMNT_RESVPORT;
575 nmp->nm_flag &= ~NFSMNT_RESVPORT;
578 /* Re-bind if rsrvd port requested and wasn't on one */
579 adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT)
580 && (argp->flags & NFSMNT_RESVPORT);
581 /* Also re-bind if we're switching to/from a connected UDP socket */
582 adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) !=
583 (argp->flags & NFSMNT_NOCONN));
585 /* Update flags atomically. Don't change the lock bits. */
586 nmp->nm_flag = argp->flags | nmp->nm_flag;
589 if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) {
590 nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10;
591 if (nmp->nm_timeo < NFS_MINTIMEO)
592 nmp->nm_timeo = NFS_MINTIMEO;
593 else if (nmp->nm_timeo > NFS_MAXTIMEO)
594 nmp->nm_timeo = NFS_MAXTIMEO;
597 if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) {
598 nmp->nm_retry = argp->retrans;
599 if (nmp->nm_retry > NFS_MAXREXMIT)
600 nmp->nm_retry = NFS_MAXREXMIT;
603 if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) {
604 nmp->nm_wsize = argp->wsize;
605 /* Round down to multiple of blocksize */
606 nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1);
607 if (nmp->nm_wsize <= 0)
608 nmp->nm_wsize = NFS_FABLKSIZE;
611 if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) {
612 nmp->nm_rsize = argp->rsize;
613 /* Round down to multiple of blocksize */
614 nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1);
615 if (nmp->nm_rsize <= 0)
616 nmp->nm_rsize = NFS_FABLKSIZE;
619 if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) {
620 nmp->nm_readdirsize = argp->readdirsize;
623 if ((argp->flags & NFSMNT_ACREGMIN) && argp->acregmin >= 0)
624 nmp->nm_acregmin = argp->acregmin;
626 nmp->nm_acregmin = NFS_MINATTRTIMO;
627 if ((argp->flags & NFSMNT_ACREGMAX) && argp->acregmax >= 0)
628 nmp->nm_acregmax = argp->acregmax;
630 nmp->nm_acregmax = NFS_MAXATTRTIMO;
631 if ((argp->flags & NFSMNT_ACDIRMIN) && argp->acdirmin >= 0)
632 nmp->nm_acdirmin = argp->acdirmin;
634 nmp->nm_acdirmin = NFS_MINDIRATTRTIMO;
635 if ((argp->flags & NFSMNT_ACDIRMAX) && argp->acdirmax >= 0)
636 nmp->nm_acdirmax = argp->acdirmax;
638 nmp->nm_acdirmax = NFS_MAXDIRATTRTIMO;
639 if (nmp->nm_acdirmin > nmp->nm_acdirmax)
640 nmp->nm_acdirmin = nmp->nm_acdirmax;
641 if (nmp->nm_acregmin > nmp->nm_acregmax)
642 nmp->nm_acregmin = nmp->nm_acregmax;
644 if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0) {
645 if (argp->readahead <= NFS_MAXRAHEAD)
646 nmp->nm_readahead = argp->readahead;
648 nmp->nm_readahead = NFS_MAXRAHEAD;
650 if ((argp->flags & NFSMNT_WCOMMITSIZE) && argp->wcommitsize >= 0) {
651 if (argp->wcommitsize < nmp->nm_wsize)
652 nmp->nm_wcommitsize = nmp->nm_wsize;
654 nmp->nm_wcommitsize = argp->wcommitsize;
657 adjsock |= ((nmp->nm_sotype != argp->sotype) ||
658 (nmp->nm_soproto != argp->proto));
660 if (nmp->nm_client != NULL && adjsock) {
661 int haslock = 0, error = 0;
663 if (nmp->nm_sotype == SOCK_STREAM) {
664 error = newnfs_sndlock(&nmp->nm_sockreq.nr_lock);
669 newnfs_disconnect(&nmp->nm_sockreq);
671 newnfs_sndunlock(&nmp->nm_sockreq.nr_lock);
672 nmp->nm_sotype = argp->sotype;
673 nmp->nm_soproto = argp->proto;
674 if (nmp->nm_sotype == SOCK_DGRAM)
675 while (newnfs_connect(nmp, &nmp->nm_sockreq,
677 printf("newnfs_args: retrying connect\n");
678 (void) nfs_catnap(PSOCK, 0, "newnfscon");
682 nmp->nm_sotype = argp->sotype;
683 nmp->nm_soproto = argp->proto;
686 if (hostname != NULL) {
687 strlcpy(nmp->nm_hostname, hostname,
688 sizeof(nmp->nm_hostname));
689 p = strchr(nmp->nm_hostname, ':');
695 static const char *nfs_opts[] = { "from",
696 "noatime", "noexec", "suiddir", "nosuid", "nosymfollow", "union",
697 "noclusterr", "noclusterw", "multilabel", "acls", "force", "update",
698 "async", "noconn", "nolockd", "conn", "lockd", "intr", "rdirplus",
699 "readdirsize", "soft", "hard", "mntudp", "tcp", "udp", "wsize", "rsize",
700 "retrans", "acregmin", "acregmax", "acdirmin", "acdirmax", "resvport",
701 "readahead", "hostname", "timeout", "addr", "fh", "nfsv3", "sec",
702 "principal", "nfsv4", "gssname", "allgssname", "dirpath",
703 "negnametimeo", "nocto",
710 * It seems a bit dumb to copyinstr() the host and path here and then
711 * bcopy() them in mountnfs(), but I wanted to detect errors before
712 * doing the sockargs() call because sockargs() allocates an mbuf and
713 * an error after that means that I have to release the mbuf.
717 nfs_mount(struct mount *mp)
719 struct nfs_args args = {
720 .version = NFS_ARGSVERSION,
722 .addrlen = sizeof (struct sockaddr_in),
723 .sotype = SOCK_STREAM,
727 .flags = NFSMNT_RESVPORT,
730 .readdirsize = NFS_READDIRSIZE,
732 .retrans = NFS_RETRANS,
733 .readahead = NFS_DEFRAHEAD,
734 .wcommitsize = 0, /* was: NQ_DEFLEASE */
737 .acregmin = NFS_MINATTRTIMO,
738 .acregmax = NFS_MAXATTRTIMO,
739 .acdirmin = NFS_MINDIRATTRTIMO,
740 .acdirmax = NFS_MAXDIRATTRTIMO,
745 int error = 0, ret, len;
746 struct sockaddr *nam = NULL;
750 u_char nfh[NFSX_FHMAX], krbname[100], dirpath[100], srvkrbname[100];
751 char *opt, *name, *secname;
752 int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO;
754 if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) {
760 if ((mp->mnt_flag & (MNT_ROOTFS | MNT_UPDATE)) == MNT_ROOTFS) {
761 error = ncl_mountroot(mp);
767 /* Handle the new style options. */
768 if (vfs_getopt(mp->mnt_optnew, "noconn", NULL, NULL) == 0)
769 args.flags |= NFSMNT_NOCONN;
770 if (vfs_getopt(mp->mnt_optnew, "conn", NULL, NULL) == 0)
771 args.flags |= NFSMNT_NOCONN;
772 if (vfs_getopt(mp->mnt_optnew, "nolockd", NULL, NULL) == 0)
773 args.flags |= NFSMNT_NOLOCKD;
774 if (vfs_getopt(mp->mnt_optnew, "lockd", NULL, NULL) == 0)
775 args.flags &= ~NFSMNT_NOLOCKD;
776 if (vfs_getopt(mp->mnt_optnew, "intr", NULL, NULL) == 0)
777 args.flags |= NFSMNT_INT;
778 if (vfs_getopt(mp->mnt_optnew, "rdirplus", NULL, NULL) == 0)
779 args.flags |= NFSMNT_RDIRPLUS;
780 if (vfs_getopt(mp->mnt_optnew, "resvport", NULL, NULL) == 0)
781 args.flags |= NFSMNT_RESVPORT;
782 if (vfs_getopt(mp->mnt_optnew, "noresvport", NULL, NULL) == 0)
783 args.flags &= ~NFSMNT_RESVPORT;
784 if (vfs_getopt(mp->mnt_optnew, "soft", NULL, NULL) == 0)
785 args.flags |= NFSMNT_SOFT;
786 if (vfs_getopt(mp->mnt_optnew, "hard", NULL, NULL) == 0)
787 args.flags &= ~NFSMNT_SOFT;
788 if (vfs_getopt(mp->mnt_optnew, "mntudp", NULL, NULL) == 0)
789 args.sotype = SOCK_DGRAM;
790 if (vfs_getopt(mp->mnt_optnew, "udp", NULL, NULL) == 0)
791 args.sotype = SOCK_DGRAM;
792 if (vfs_getopt(mp->mnt_optnew, "tcp", NULL, NULL) == 0)
793 args.sotype = SOCK_STREAM;
794 if (vfs_getopt(mp->mnt_optnew, "nfsv3", NULL, NULL) == 0)
795 args.flags |= NFSMNT_NFSV3;
796 if (vfs_getopt(mp->mnt_optnew, "nfsv4", NULL, NULL) == 0) {
797 args.flags |= NFSMNT_NFSV4;
798 args.sotype = SOCK_STREAM;
800 if (vfs_getopt(mp->mnt_optnew, "allgssname", NULL, NULL) == 0)
801 args.flags |= NFSMNT_ALLGSSNAME;
802 if (vfs_getopt(mp->mnt_optnew, "nocto", NULL, NULL) == 0)
803 args.flags |= NFSMNT_NOCTO;
804 if (vfs_getopt(mp->mnt_optnew, "readdirsize", (void **)&opt, NULL) == 0) {
806 vfs_mount_error(mp, "illegal readdirsize");
810 ret = sscanf(opt, "%d", &args.readdirsize);
811 if (ret != 1 || args.readdirsize <= 0) {
812 vfs_mount_error(mp, "illegal readdirsize: %s",
817 args.flags |= NFSMNT_READDIRSIZE;
819 if (vfs_getopt(mp->mnt_optnew, "readahead", (void **)&opt, NULL) == 0) {
821 vfs_mount_error(mp, "illegal readahead");
825 ret = sscanf(opt, "%d", &args.readahead);
826 if (ret != 1 || args.readahead <= 0) {
827 vfs_mount_error(mp, "illegal readahead: %s",
832 args.flags |= NFSMNT_READAHEAD;
834 if (vfs_getopt(mp->mnt_optnew, "wsize", (void **)&opt, NULL) == 0) {
836 vfs_mount_error(mp, "illegal wsize");
840 ret = sscanf(opt, "%d", &args.wsize);
841 if (ret != 1 || args.wsize <= 0) {
842 vfs_mount_error(mp, "illegal wsize: %s",
847 args.flags |= NFSMNT_WSIZE;
849 if (vfs_getopt(mp->mnt_optnew, "rsize", (void **)&opt, NULL) == 0) {
851 vfs_mount_error(mp, "illegal rsize");
855 ret = sscanf(opt, "%d", &args.rsize);
856 if (ret != 1 || args.rsize <= 0) {
857 vfs_mount_error(mp, "illegal wsize: %s",
862 args.flags |= NFSMNT_RSIZE;
864 if (vfs_getopt(mp->mnt_optnew, "retrans", (void **)&opt, NULL) == 0) {
866 vfs_mount_error(mp, "illegal retrans");
870 ret = sscanf(opt, "%d", &args.retrans);
871 if (ret != 1 || args.retrans <= 0) {
872 vfs_mount_error(mp, "illegal retrans: %s",
877 args.flags |= NFSMNT_RETRANS;
879 if (vfs_getopt(mp->mnt_optnew, "acregmin", (void **)&opt, NULL) == 0) {
880 ret = sscanf(opt, "%d", &args.acregmin);
881 if (ret != 1 || args.acregmin < 0) {
882 vfs_mount_error(mp, "illegal acregmin: %s",
887 args.flags |= NFSMNT_ACREGMIN;
889 if (vfs_getopt(mp->mnt_optnew, "acregmax", (void **)&opt, NULL) == 0) {
890 ret = sscanf(opt, "%d", &args.acregmax);
891 if (ret != 1 || args.acregmax < 0) {
892 vfs_mount_error(mp, "illegal acregmax: %s",
897 args.flags |= NFSMNT_ACREGMAX;
899 if (vfs_getopt(mp->mnt_optnew, "acdirmin", (void **)&opt, NULL) == 0) {
900 ret = sscanf(opt, "%d", &args.acdirmin);
901 if (ret != 1 || args.acdirmin < 0) {
902 vfs_mount_error(mp, "illegal acdirmin: %s",
907 args.flags |= NFSMNT_ACDIRMIN;
909 if (vfs_getopt(mp->mnt_optnew, "acdirmax", (void **)&opt, NULL) == 0) {
910 ret = sscanf(opt, "%d", &args.acdirmax);
911 if (ret != 1 || args.acdirmax < 0) {
912 vfs_mount_error(mp, "illegal acdirmax: %s",
917 args.flags |= NFSMNT_ACDIRMAX;
919 if (vfs_getopt(mp->mnt_optnew, "timeout", (void **)&opt, NULL) == 0) {
920 ret = sscanf(opt, "%d", &args.timeo);
921 if (ret != 1 || args.timeo <= 0) {
922 vfs_mount_error(mp, "illegal timeout: %s",
927 args.flags |= NFSMNT_TIMEO;
929 if (vfs_getopt(mp->mnt_optnew, "negnametimeo", (void **)&opt, NULL)
931 ret = sscanf(opt, "%d", &negnametimeo);
932 if (ret != 1 || negnametimeo < 0) {
933 vfs_mount_error(mp, "illegal negnametimeo: %s",
939 if (vfs_getopt(mp->mnt_optnew, "sec",
940 (void **) &secname, NULL) == 0)
941 nfs_sec_name(secname, &args.flags);
943 if (mp->mnt_flag & MNT_UPDATE) {
944 struct nfsmount *nmp = VFSTONFS(mp);
951 * When doing an update, we can't change version,
952 * security, switch lockd strategies or change cookie
955 args.flags = (args.flags &
961 NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) |
968 NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
969 nfs_decode_args(mp, nmp, &args, NULL, td->td_ucred, td);
974 * Make the nfs_ip_paranoia sysctl serve as the default connection
975 * or no-connection mode for those protocols that support
976 * no-connection mode (the flag will be cleared later for protocols
977 * that do not support no-connection mode). This will allow a client
978 * to receive replies from a different IP then the request was
979 * sent to. Note: default value for nfs_ip_paranoia is 1 (paranoid),
982 if (nfs_ip_paranoia == 0)
983 args.flags |= NFSMNT_NOCONN;
985 if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh,
986 &args.fhsize) == 0) {
987 if (args.fhsize < 0 || args.fhsize > NFSX_FHMAX) {
988 vfs_mount_error(mp, "Bad file handle");
992 bcopy(args.fh, nfh, args.fhsize);
997 (void) vfs_getopt(mp->mnt_optnew, "hostname", (void **)&args.hostname,
999 if (args.hostname == NULL) {
1000 vfs_mount_error(mp, "Invalid hostname");
1004 bcopy(args.hostname, hst, MNAMELEN);
1005 hst[MNAMELEN - 1] = '\0';
1007 if (vfs_getopt(mp->mnt_optnew, "principal", (void **)&name, NULL) == 0)
1008 strlcpy(srvkrbname, name, sizeof (srvkrbname));
1010 snprintf(srvkrbname, sizeof (srvkrbname), "nfs@%s", hst);
1011 args.srvkrbnamelen = strlen(srvkrbname);
1013 if (vfs_getopt(mp->mnt_optnew, "gssname", (void **)&name, NULL) == 0)
1014 strlcpy(krbname, name, sizeof (krbname));
1017 args.krbnamelen = strlen(krbname);
1019 if (vfs_getopt(mp->mnt_optnew, "dirpath", (void **)&name, NULL) == 0)
1020 strlcpy(dirpath, name, sizeof (dirpath));
1023 args.dirlen = strlen(dirpath);
1025 if (vfs_getopt(mp->mnt_optnew, "addr", (void **)&args.addr,
1026 &args.addrlen) == 0) {
1027 if (args.addrlen > SOCK_MAXADDRLEN) {
1028 error = ENAMETOOLONG;
1031 nam = malloc(args.addrlen, M_SONAME, M_WAITOK);
1032 bcopy(args.addr, nam, args.addrlen);
1033 nam->sa_len = args.addrlen;
1037 error = mountnfs(&args, mp, nam, hst, krbname, dirpath, srvkrbname,
1038 &vp, td->td_ucred, td, negnametimeo);
1042 mp->mnt_kern_flag |= (MNTK_MPSAFE|MNTK_LOOKUP_SHARED);
1053 * It seems a bit dumb to copyinstr() the host and path here and then
1054 * bcopy() them in mountnfs(), but I wanted to detect errors before
1055 * doing the sockargs() call because sockargs() allocates an mbuf and
1056 * an error after that means that I have to release the mbuf.
1060 nfs_cmount(struct mntarg *ma, void *data, int flags)
1063 struct nfs_args args;
1065 error = copyin(data, &args, sizeof (struct nfs_args));
1069 ma = mount_arg(ma, "nfs_args", &args, sizeof args);
1071 error = kernel_mount(ma, flags);
1076 * Common code for mount and mountroot
1079 mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
1080 char *hst, u_char *krbname, u_char *dirpath, u_char *srvkrbname,
1081 struct vnode **vpp, struct ucred *cred, struct thread *td,
1084 struct nfsmount *nmp;
1086 int error, trycnt, ret;
1087 struct nfsvattr nfsva;
1088 static u_int64_t clval = 0;
1090 if (mp->mnt_flag & MNT_UPDATE) {
1092 printf("%s: MNT_UPDATE is no longer handled here\n", __func__);
1093 FREE(nam, M_SONAME);
1096 MALLOC(nmp, struct nfsmount *, sizeof (struct nfsmount) +
1097 argp->krbnamelen + argp->dirlen + argp->srvkrbnamelen + 2,
1098 M_NEWNFSMNT, M_WAITOK);
1099 bzero((caddr_t)nmp, sizeof (struct nfsmount) +
1100 argp->krbnamelen + argp->dirlen + argp->srvkrbnamelen + 2);
1101 TAILQ_INIT(&nmp->nm_bufq);
1103 clval = (u_int64_t)nfsboottime.tv_sec;
1104 nmp->nm_clval = clval++;
1105 nmp->nm_krbnamelen = argp->krbnamelen;
1106 nmp->nm_dirpathlen = argp->dirlen;
1107 nmp->nm_srvkrbnamelen = argp->srvkrbnamelen;
1108 if (td->td_ucred->cr_uid != (uid_t)0) {
1110 * nm_uid is used to get KerberosV credentials for
1111 * the nfsv4 state handling operations if there is
1112 * no host based principal set. Use the uid of
1113 * this user if not root, since they are doing the
1114 * mount. I don't think setting this for root will
1115 * work, since root normally does not have user
1116 * credentials in a credentials cache.
1118 nmp->nm_uid = td->td_ucred->cr_uid;
1121 * Just set to -1, so it won't be used.
1123 nmp->nm_uid = (uid_t)-1;
1126 /* Copy and null terminate all the names */
1127 if (nmp->nm_krbnamelen > 0) {
1128 bcopy(krbname, nmp->nm_krbname, nmp->nm_krbnamelen);
1129 nmp->nm_name[nmp->nm_krbnamelen] = '\0';
1131 if (nmp->nm_dirpathlen > 0) {
1132 bcopy(dirpath, NFSMNT_DIRPATH(nmp),
1133 nmp->nm_dirpathlen);
1134 nmp->nm_name[nmp->nm_krbnamelen + nmp->nm_dirpathlen
1137 if (nmp->nm_srvkrbnamelen > 0) {
1138 bcopy(srvkrbname, NFSMNT_SRVKRBNAME(nmp),
1139 nmp->nm_srvkrbnamelen);
1140 nmp->nm_name[nmp->nm_krbnamelen + nmp->nm_dirpathlen
1141 + nmp->nm_srvkrbnamelen + 2] = '\0';
1143 nmp->nm_sockreq.nr_cred = crhold(cred);
1144 mtx_init(&nmp->nm_sockreq.nr_mtx, "nfssock", NULL, MTX_DEF);
1146 nmp->nm_getinfo = nfs_getnlminfo;
1147 nmp->nm_vinvalbuf = ncl_vinvalbuf;
1150 nmp->nm_mountp = mp;
1151 mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF | MTX_DUPOK);
1152 nmp->nm_negnametimeo = negnametimeo;
1154 nfs_decode_args(mp, nmp, argp, hst, cred, td);
1157 * V2 can only handle 32 bit filesizes. A 4GB-1 limit may be too
1158 * high, depending on whether we end up with negative offsets in
1159 * the client or server somewhere. 2GB-1 may be safer.
1161 * For V3, ncl_fsinfo will adjust this as necessary. Assume maximum
1162 * that we can handle until we find out otherwise.
1163 * XXX Our "safe" limit on the client is what we can store in our
1164 * buffer cache using signed(!) block numbers.
1166 if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0)
1167 nmp->nm_maxfilesize = 0xffffffffLL;
1169 nmp->nm_maxfilesize = (u_int64_t)0x80000000 * DEV_BSIZE - 1;
1171 nmp->nm_timeo = NFS_TIMEO;
1172 nmp->nm_retry = NFS_RETRANS;
1173 if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0) {
1174 nmp->nm_wsize = NFS_WSIZE;
1175 nmp->nm_rsize = NFS_RSIZE;
1176 nmp->nm_readdirsize = NFS_READDIRSIZE;
1178 nmp->nm_wcommitsize = hibufspace / (desiredvnodes / 1000);
1179 nmp->nm_numgrps = NFS_MAXGRPS;
1180 nmp->nm_readahead = NFS_DEFRAHEAD;
1181 nmp->nm_tprintf_delay = nfs_tprintf_delay;
1182 if (nmp->nm_tprintf_delay < 0)
1183 nmp->nm_tprintf_delay = 0;
1184 nmp->nm_tprintf_initial_delay = nfs_tprintf_initial_delay;
1185 if (nmp->nm_tprintf_initial_delay < 0)
1186 nmp->nm_tprintf_initial_delay = 0;
1187 nmp->nm_fhsize = argp->fhsize;
1188 if (nmp->nm_fhsize > 0)
1189 bcopy((caddr_t)argp->fh, (caddr_t)nmp->nm_fh, argp->fhsize);
1190 bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);
1192 /* Set up the sockets and per-host congestion */
1193 nmp->nm_sotype = argp->sotype;
1194 nmp->nm_soproto = argp->proto;
1195 nmp->nm_sockreq.nr_prog = NFS_PROG;
1196 if ((argp->flags & NFSMNT_NFSV4))
1197 nmp->nm_sockreq.nr_vers = NFS_VER4;
1198 else if ((argp->flags & NFSMNT_NFSV3))
1199 nmp->nm_sockreq.nr_vers = NFS_VER3;
1201 nmp->nm_sockreq.nr_vers = NFS_VER2;
1204 if ((error = newnfs_connect(nmp, &nmp->nm_sockreq, cred, td, 0)))
1208 * A reference count is needed on the nfsnode representing the
1209 * remote root. If this object is not persistent, then backward
1210 * traversals of the mount point (i.e. "..") will not work if
1211 * the nfsnode gets flushed out of the cache. Ufs does not have
1212 * this problem, because one can identify root inodes by their
1213 * number == ROOTINO (2).
1215 if (nmp->nm_fhsize == 0 && (nmp->nm_flag & NFSMNT_NFSV4) &&
1216 nmp->nm_dirpathlen > 0) {
1218 * If the fhsize on the mount point == 0 for V4, the mount
1219 * path needs to be looked up.
1223 error = nfsrpc_getdirpath(nmp, NFSMNT_DIRPATH(nmp),
1226 (void) nfs_catnap(PZERO, error, "nfsgetdirp");
1227 } while (error && --trycnt > 0);
1229 error = nfscl_maperr(td, error, (uid_t)0, (gid_t)0);
1233 if (nmp->nm_fhsize > 0) {
1235 * Set f_iosize to NFS_DIRBLKSIZ so that bo_bsize gets set
1236 * non-zero for the root vnode. f_iosize will be set correctly
1237 * by nfs_statfs() before any I/O occurs.
1239 mp->mnt_stat.f_iosize = NFS_DIRBLKSIZ;
1240 error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np,
1247 * Get file attributes and transfer parameters for the
1248 * mountpoint. This has the side effect of filling in
1249 * (*vpp)->v_type with the correct value.
1251 ret = nfsrpc_getattrnovp(nmp, nmp->nm_fh, nmp->nm_fhsize, 1,
1252 cred, td, &nfsva, NULL);
1255 * Just set default values to get things going.
1257 NFSBZERO((caddr_t)&nfsva, sizeof (struct nfsvattr));
1258 nfsva.na_vattr.va_type = VDIR;
1259 nfsva.na_vattr.va_mode = 0777;
1260 nfsva.na_vattr.va_nlink = 100;
1261 nfsva.na_vattr.va_uid = (uid_t)0;
1262 nfsva.na_vattr.va_gid = (gid_t)0;
1263 nfsva.na_vattr.va_fileid = 2;
1264 nfsva.na_vattr.va_gen = 1;
1265 nfsva.na_vattr.va_blocksize = NFS_FABLKSIZE;
1266 nfsva.na_vattr.va_size = 512 * 1024;
1268 (void) nfscl_loadattrcache(vpp, &nfsva, NULL, NULL, 0, 1);
1269 if (argp->flags & NFSMNT_NFSV3)
1270 ncl_fsinfo(nmp, *vpp, cred, td);
1273 * Lose the lock but keep the ref.
1275 VOP_UNLOCK(*vpp, 0);
1281 newnfs_disconnect(&nmp->nm_sockreq);
1282 crfree(nmp->nm_sockreq.nr_cred);
1283 mtx_destroy(&nmp->nm_sockreq.nr_mtx);
1284 mtx_destroy(&nmp->nm_mtx);
1285 FREE(nmp, M_NEWNFSMNT);
1286 FREE(nam, M_SONAME);
1291 * unmount system call
1294 nfs_unmount(struct mount *mp, int mntflags)
1297 struct nfsmount *nmp;
1298 int error, flags = 0, trycnt = 0;
1302 if (mntflags & MNT_FORCE)
1303 flags |= FORCECLOSE;
1306 * Goes something like this..
1307 * - Call vflush() to clear out vnodes for this filesystem
1308 * - Close the socket
1309 * - Free up the data structures
1311 /* In the forced case, cancel any outstanding requests. */
1312 if (mntflags & MNT_FORCE) {
1313 error = newnfs_nmcancelreqs(nmp);
1316 /* For a forced close, get rid of the renew thread now */
1317 nfscl_umount(nmp, td);
1319 /* We hold 1 extra ref on the root vnode; see comment in mountnfs(). */
1321 error = vflush(mp, 1, flags, td);
1322 if ((mntflags & MNT_FORCE) && error != 0 && ++trycnt < 30)
1323 (void) nfs_catnap(PSOCK, error, "newndm");
1324 } while ((mntflags & MNT_FORCE) && error != 0 && trycnt < 30);
1329 * We are now committed to the unmount.
1331 if ((mntflags & MNT_FORCE) == 0)
1332 nfscl_umount(nmp, td);
1333 newnfs_disconnect(&nmp->nm_sockreq);
1334 crfree(nmp->nm_sockreq.nr_cred);
1335 FREE(nmp->nm_nam, M_SONAME);
1337 mtx_destroy(&nmp->nm_sockreq.nr_mtx);
1338 mtx_destroy(&nmp->nm_mtx);
1339 FREE(nmp, M_NEWNFSMNT);
1345 * Return root of a filesystem
1348 nfs_root(struct mount *mp, int flags, struct vnode **vpp)
1351 struct nfsmount *nmp;
1356 error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np, flags);
1361 * Get transfer parameters and attributes for root vnode once.
1363 mtx_lock(&nmp->nm_mtx);
1364 if (NFSHASNFSV3(nmp) && !NFSHASGOTFSINFO(nmp)) {
1365 mtx_unlock(&nmp->nm_mtx);
1366 ncl_fsinfo(nmp, vp, curthread->td_ucred, curthread);
1368 mtx_unlock(&nmp->nm_mtx);
1369 if (vp->v_type == VNON)
1371 vp->v_vflag |= VV_ROOT;
1377 * Flush out the buffer cache
1381 nfs_sync(struct mount *mp, int waitfor)
1383 struct vnode *vp, *mvp;
1385 int error, allerror = 0;
1390 * Force stale buffer cache information to be flushed.
1394 MNT_VNODE_FOREACH(vp, mp, mvp) {
1397 /* XXX Racy bv_cnt check. */
1398 if (VOP_ISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
1399 waitfor == MNT_LAZY) {
1404 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
1406 MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp);
1409 error = VOP_FSYNC(vp, waitfor, td);
1422 nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req)
1424 struct nfsmount *nmp = VFSTONFS(mp);
1428 bzero(&vq, sizeof(vq));
1431 case VFS_CTL_NOLOCKS:
1432 val = (nmp->nm_flag & NFSMNT_NOLOCKS) ? 1 : 0;
1433 if (req->oldptr != NULL) {
1434 error = SYSCTL_OUT(req, &val, sizeof(val));
1438 if (req->newptr != NULL) {
1439 error = SYSCTL_IN(req, &val, sizeof(val));
1443 nmp->nm_flag |= NFSMNT_NOLOCKS;
1445 nmp->nm_flag &= ~NFSMNT_NOLOCKS;
1450 mtx_lock(&nmp->nm_mtx);
1451 if (nmp->nm_state & NFSSTA_TIMEO)
1452 vq.vq_flags |= VQ_NOTRESP;
1453 mtx_unlock(&nmp->nm_mtx);
1455 if (!(nmp->nm_flag & NFSMNT_NOLOCKS) &&
1456 (nmp->nm_state & NFSSTA_LOCKTIMEO))
1457 vq.vq_flags |= VQ_NOTRESPLOCK;
1459 error = SYSCTL_OUT(req, &vq, sizeof(vq));
1462 if (req->oldptr != NULL) {
1463 error = SYSCTL_OUT(req, &nmp->nm_tprintf_initial_delay,
1464 sizeof(nmp->nm_tprintf_initial_delay));
1468 if (req->newptr != NULL) {
1469 error = vfs_suser(mp, req->td);
1472 error = SYSCTL_IN(req, &nmp->nm_tprintf_initial_delay,
1473 sizeof(nmp->nm_tprintf_initial_delay));
1476 if (nmp->nm_tprintf_initial_delay < 0)
1477 nmp->nm_tprintf_initial_delay = 0;
1487 * Extract the information needed by the nlm from the nfs vnode.
1490 nfs_getnlminfo(struct vnode *vp, uint8_t *fhp, size_t *fhlenp,
1491 struct sockaddr_storage *sp, int *is_v3p, off_t *sizep,
1492 struct timeval *timeop)
1494 struct nfsmount *nmp;
1495 struct nfsnode *np = VTONFS(vp);
1497 nmp = VFSTONFS(vp->v_mount);
1499 *fhlenp = (size_t)np->n_fhp->nfh_len;
1501 bcopy(np->n_fhp->nfh_fh, fhp, np->n_fhp->nfh_len);
1503 bcopy(nmp->nm_nam, sp, min(nmp->nm_nam->sa_len, sizeof(*sp)));
1505 *is_v3p = NFS_ISV3(vp);
1507 *sizep = np->n_size;
1508 if (timeop != NULL) {
1509 timeop->tv_sec = nmp->nm_timeo / NFS_HZ;
1510 timeop->tv_usec = (nmp->nm_timeo % NFS_HZ) * (1000000 / NFS_HZ);