]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/fs/nfsclient/nfs_clvfsops.c
Add flags to enable NFS over TLS to the NFS client and server.
[FreeBSD/FreeBSD.git] / sys / fs / nfsclient / nfs_clvfsops.c
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright (c) 1989, 1993, 1995
5  *      The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Rick Macklem at The University of Guelph.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  *      from nfs_vfsops.c       8.12 (Berkeley) 5/20/95
35  */
36
37 #include <sys/cdefs.h>
38 __FBSDID("$FreeBSD$");
39
40
41 #include "opt_bootp.h"
42 #include "opt_nfsroot.h"
43 #include "opt_kern_tls.h"
44
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/kernel.h>
48 #include <sys/bio.h>
49 #include <sys/buf.h>
50 #include <sys/clock.h>
51 #include <sys/jail.h>
52 #include <sys/limits.h>
53 #include <sys/lock.h>
54 #include <sys/malloc.h>
55 #include <sys/mbuf.h>
56 #include <sys/module.h>
57 #include <sys/mount.h>
58 #include <sys/proc.h>
59 #include <sys/socket.h>
60 #include <sys/socketvar.h>
61 #include <sys/sockio.h>
62 #include <sys/sysctl.h>
63 #include <sys/vnode.h>
64 #include <sys/signalvar.h>
65
66 #include <vm/vm.h>
67 #include <vm/vm_extern.h>
68 #include <vm/uma.h>
69
70 #include <net/if.h>
71 #include <net/route.h>
72 #include <net/route/route_ctl.h>
73 #include <netinet/in.h>
74
75 #include <fs/nfs/nfsport.h>
76 #include <fs/nfsclient/nfsnode.h>
77 #include <fs/nfsclient/nfsmount.h>
78 #include <fs/nfsclient/nfs.h>
79 #include <nfs/nfsdiskless.h>
80
81 #include <rpc/rpcsec_tls.h>
82
83 FEATURE(nfscl, "NFSv4 client");
84
85 extern int nfscl_ticks;
86 extern struct timeval nfsboottime;
87 extern int nfsrv_useacl;
88 extern int nfscl_debuglevel;
89 extern enum nfsiod_state ncl_iodwant[NFS_MAXASYNCDAEMON];
90 extern struct nfsmount *ncl_iodmount[NFS_MAXASYNCDAEMON];
91 extern struct mtx ncl_iod_mutex;
92 NFSCLSTATEMUTEX;
93 extern struct mtx nfsrv_dslock_mtx;
94
95 MALLOC_DEFINE(M_NEWNFSREQ, "newnfsclient_req", "NFS request header");
96 MALLOC_DEFINE(M_NEWNFSMNT, "newnfsmnt", "NFS mount struct");
97
98 SYSCTL_DECL(_vfs_nfs);
99 static int nfs_ip_paranoia = 1;
100 SYSCTL_INT(_vfs_nfs, OID_AUTO, nfs_ip_paranoia, CTLFLAG_RW,
101     &nfs_ip_paranoia, 0, "");
102 static int nfs_tprintf_initial_delay = NFS_TPRINTF_INITIAL_DELAY;
103 SYSCTL_INT(_vfs_nfs, NFS_TPRINTF_INITIAL_DELAY,
104         downdelayinitial, CTLFLAG_RW, &nfs_tprintf_initial_delay, 0, "");
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 #ifdef NFS_DEBUG
110 int nfs_debug;
111 SYSCTL_INT(_vfs_nfs, OID_AUTO, debug, CTLFLAG_RW, &nfs_debug, 0,
112     "Toggle debug flag");
113 #endif
114
115 static int      nfs_mountroot(struct mount *);
116 static void     nfs_sec_name(char *, int *);
117 static void     nfs_decode_args(struct mount *mp, struct nfsmount *nmp,
118                     struct nfs_args *argp, const char *, struct ucred *,
119                     struct thread *);
120 static int      mountnfs(struct nfs_args *, struct mount *,
121                     struct sockaddr *, char *, u_char *, int, u_char *, int,
122                     u_char *, int, struct vnode **, struct ucred *,
123                     struct thread *, int, int, int, uint32_t);
124 static void     nfs_getnlminfo(struct vnode *, uint8_t *, size_t *,
125                     struct sockaddr_storage *, int *, off_t *,
126                     struct timeval *);
127 static vfs_mount_t nfs_mount;
128 static vfs_cmount_t nfs_cmount;
129 static vfs_unmount_t nfs_unmount;
130 static vfs_root_t nfs_root;
131 static vfs_statfs_t nfs_statfs;
132 static vfs_sync_t nfs_sync;
133 static vfs_sysctl_t nfs_sysctl;
134 static vfs_purge_t nfs_purge;
135
136 /*
137  * nfs vfs operations.
138  */
139 static struct vfsops nfs_vfsops = {
140         .vfs_init =             ncl_init,
141         .vfs_mount =            nfs_mount,
142         .vfs_cmount =           nfs_cmount,
143         .vfs_root =             vfs_cache_root,
144         .vfs_cachedroot =       nfs_root,
145         .vfs_statfs =           nfs_statfs,
146         .vfs_sync =             nfs_sync,
147         .vfs_uninit =           ncl_uninit,
148         .vfs_unmount =          nfs_unmount,
149         .vfs_sysctl =           nfs_sysctl,
150         .vfs_purge =            nfs_purge,
151 };
152 VFS_SET(nfs_vfsops, nfs, VFCF_NETWORK | VFCF_SBDRY);
153
154 /* So that loader and kldload(2) can find us, wherever we are.. */
155 MODULE_VERSION(nfs, 1);
156 MODULE_DEPEND(nfs, nfscommon, 1, 1, 1);
157 MODULE_DEPEND(nfs, krpc, 1, 1, 1);
158 MODULE_DEPEND(nfs, nfssvc, 1, 1, 1);
159
160 /*
161  * This structure is now defined in sys/nfs/nfs_diskless.c so that it
162  * can be shared by both NFS clients. It is declared here so that it
163  * will be defined for kernels built without NFS_ROOT, although it
164  * isn't used in that case.
165  */
166 #if !defined(NFS_ROOT)
167 struct nfs_diskless     nfs_diskless = { { { 0 } } };
168 struct nfsv3_diskless   nfsv3_diskless = { { { 0 } } };
169 int                     nfs_diskless_valid = 0;
170 #endif
171
172 SYSCTL_INT(_vfs_nfs, OID_AUTO, diskless_valid, CTLFLAG_RD,
173     &nfs_diskless_valid, 0,
174     "Has the diskless struct been filled correctly");
175
176 SYSCTL_STRING(_vfs_nfs, OID_AUTO, diskless_rootpath, CTLFLAG_RD,
177     nfsv3_diskless.root_hostnam, 0, "Path to nfs root");
178
179 SYSCTL_OPAQUE(_vfs_nfs, OID_AUTO, diskless_rootaddr, CTLFLAG_RD,
180     &nfsv3_diskless.root_saddr, sizeof(nfsv3_diskless.root_saddr),
181     "%Ssockaddr_in", "Diskless root nfs address");
182
183
184 void            newnfsargs_ntoh(struct nfs_args *);
185 static int      nfs_mountdiskless(char *,
186                     struct sockaddr_in *, struct nfs_args *,
187                     struct thread *, struct vnode **, struct mount *);
188 static void     nfs_convert_diskless(void);
189 static void     nfs_convert_oargs(struct nfs_args *args,
190                     struct onfs_args *oargs);
191
192 int
193 newnfs_iosize(struct nfsmount *nmp)
194 {
195         int iosize, maxio;
196
197         /* First, set the upper limit for iosize */
198         if (nmp->nm_flag & NFSMNT_NFSV4) {
199                 maxio = NFS_MAXBSIZE;
200         } else if (nmp->nm_flag & NFSMNT_NFSV3) {
201                 if (nmp->nm_sotype == SOCK_DGRAM)
202                         maxio = NFS_MAXDGRAMDATA;
203                 else
204                         maxio = NFS_MAXBSIZE;
205         } else {
206                 maxio = NFS_V2MAXDATA;
207         }
208         if (nmp->nm_rsize > maxio || nmp->nm_rsize == 0)
209                 nmp->nm_rsize = maxio;
210         if (nmp->nm_rsize > NFS_MAXBSIZE)
211                 nmp->nm_rsize = NFS_MAXBSIZE;
212         if (nmp->nm_readdirsize > maxio || nmp->nm_readdirsize == 0)
213                 nmp->nm_readdirsize = maxio;
214         if (nmp->nm_readdirsize > nmp->nm_rsize)
215                 nmp->nm_readdirsize = nmp->nm_rsize;
216         if (nmp->nm_wsize > maxio || nmp->nm_wsize == 0)
217                 nmp->nm_wsize = maxio;
218         if (nmp->nm_wsize > NFS_MAXBSIZE)
219                 nmp->nm_wsize = NFS_MAXBSIZE;
220
221         /*
222          * Calculate the size used for io buffers.  Use the larger
223          * of the two sizes to minimise nfs requests but make sure
224          * that it is at least one VM page to avoid wasting buffer
225          * space.  It must also be at least NFS_DIRBLKSIZ, since
226          * that is the buffer size used for directories.
227          */
228         iosize = imax(nmp->nm_rsize, nmp->nm_wsize);
229         iosize = imax(iosize, PAGE_SIZE);
230         iosize = imax(iosize, NFS_DIRBLKSIZ);
231         nmp->nm_mountp->mnt_stat.f_iosize = iosize;
232         return (iosize);
233 }
234
235 static void
236 nfs_convert_oargs(struct nfs_args *args, struct onfs_args *oargs)
237 {
238
239         args->version = NFS_ARGSVERSION;
240         args->addr = oargs->addr;
241         args->addrlen = oargs->addrlen;
242         args->sotype = oargs->sotype;
243         args->proto = oargs->proto;
244         args->fh = oargs->fh;
245         args->fhsize = oargs->fhsize;
246         args->flags = oargs->flags;
247         args->wsize = oargs->wsize;
248         args->rsize = oargs->rsize;
249         args->readdirsize = oargs->readdirsize;
250         args->timeo = oargs->timeo;
251         args->retrans = oargs->retrans;
252         args->readahead = oargs->readahead;
253         args->hostname = oargs->hostname;
254 }
255
256 static void
257 nfs_convert_diskless(void)
258 {
259
260         bcopy(&nfs_diskless.myif, &nfsv3_diskless.myif,
261                 sizeof(struct ifaliasreq));
262         bcopy(&nfs_diskless.mygateway, &nfsv3_diskless.mygateway,
263                 sizeof(struct sockaddr_in));
264         nfs_convert_oargs(&nfsv3_diskless.root_args,&nfs_diskless.root_args);
265         if (nfsv3_diskless.root_args.flags & NFSMNT_NFSV3) {
266                 nfsv3_diskless.root_fhsize = NFSX_MYFH;
267                 bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_MYFH);
268         } else {
269                 nfsv3_diskless.root_fhsize = NFSX_V2FH;
270                 bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V2FH);
271         }
272         bcopy(&nfs_diskless.root_saddr,&nfsv3_diskless.root_saddr,
273                 sizeof(struct sockaddr_in));
274         bcopy(nfs_diskless.root_hostnam, nfsv3_diskless.root_hostnam, MNAMELEN);
275         nfsv3_diskless.root_time = nfs_diskless.root_time;
276         bcopy(nfs_diskless.my_hostnam, nfsv3_diskless.my_hostnam,
277                 MAXHOSTNAMELEN);
278         nfs_diskless_valid = 3;
279 }
280
281 /*
282  * nfs statfs call
283  */
284 static int
285 nfs_statfs(struct mount *mp, struct statfs *sbp)
286 {
287         struct vnode *vp;
288         struct thread *td;
289         struct nfsmount *nmp = VFSTONFS(mp);
290         struct nfsvattr nfsva;
291         struct nfsfsinfo fs;
292         struct nfsstatfs sb;
293         int error = 0, attrflag, gotfsinfo = 0, ret;
294         struct nfsnode *np;
295
296         td = curthread;
297
298         error = vfs_busy(mp, MBF_NOWAIT);
299         if (error)
300                 return (error);
301         error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
302         if (error) {
303                 vfs_unbusy(mp);
304                 return (error);
305         }
306         vp = NFSTOV(np);
307         mtx_lock(&nmp->nm_mtx);
308         if (NFSHASNFSV3(nmp) && !NFSHASGOTFSINFO(nmp)) {
309                 mtx_unlock(&nmp->nm_mtx);
310                 error = nfsrpc_fsinfo(vp, &fs, td->td_ucred, td, &nfsva,
311                     &attrflag, NULL);
312                 if (!error)
313                         gotfsinfo = 1;
314         } else
315                 mtx_unlock(&nmp->nm_mtx);
316         if (!error)
317                 error = nfsrpc_statfs(vp, &sb, &fs, td->td_ucred, td, &nfsva,
318                     &attrflag, NULL);
319         if (error != 0)
320                 NFSCL_DEBUG(2, "statfs=%d\n", error);
321         if (attrflag == 0) {
322                 ret = nfsrpc_getattrnovp(nmp, nmp->nm_fh, nmp->nm_fhsize, 1,
323                     td->td_ucred, td, &nfsva, NULL, NULL);
324                 if (ret) {
325                         /*
326                          * Just set default values to get things going.
327                          */
328                         NFSBZERO((caddr_t)&nfsva, sizeof (struct nfsvattr));
329                         nfsva.na_vattr.va_type = VDIR;
330                         nfsva.na_vattr.va_mode = 0777;
331                         nfsva.na_vattr.va_nlink = 100;
332                         nfsva.na_vattr.va_uid = (uid_t)0;
333                         nfsva.na_vattr.va_gid = (gid_t)0;
334                         nfsva.na_vattr.va_fileid = 2;
335                         nfsva.na_vattr.va_gen = 1;
336                         nfsva.na_vattr.va_blocksize = NFS_FABLKSIZE;
337                         nfsva.na_vattr.va_size = 512 * 1024;
338                 }
339         }
340         (void) nfscl_loadattrcache(&vp, &nfsva, NULL, NULL, 0, 1);
341         if (!error) {
342             mtx_lock(&nmp->nm_mtx);
343             if (gotfsinfo || (nmp->nm_flag & NFSMNT_NFSV4))
344                 nfscl_loadfsinfo(nmp, &fs);
345             nfscl_loadsbinfo(nmp, &sb, sbp);
346             sbp->f_iosize = newnfs_iosize(nmp);
347             mtx_unlock(&nmp->nm_mtx);
348             if (sbp != &mp->mnt_stat) {
349                 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
350                 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
351             }
352             strncpy(&sbp->f_fstypename[0], mp->mnt_vfc->vfc_name, MFSNAMELEN);
353         } else if (NFS_ISV4(vp)) {
354                 error = nfscl_maperr(td, error, (uid_t)0, (gid_t)0);
355         }
356         vput(vp);
357         vfs_unbusy(mp);
358         return (error);
359 }
360
361 /*
362  * nfs version 3 fsinfo rpc call
363  */
364 int
365 ncl_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct ucred *cred,
366     struct thread *td)
367 {
368         struct nfsfsinfo fs;
369         struct nfsvattr nfsva;
370         int error, attrflag;
371         
372         error = nfsrpc_fsinfo(vp, &fs, cred, td, &nfsva, &attrflag, NULL);
373         if (!error) {
374                 if (attrflag)
375                         (void) nfscl_loadattrcache(&vp, &nfsva, NULL, NULL, 0,
376                             1);
377                 mtx_lock(&nmp->nm_mtx);
378                 nfscl_loadfsinfo(nmp, &fs);
379                 mtx_unlock(&nmp->nm_mtx);
380         }
381         return (error);
382 }
383
384 /*
385  * Mount a remote root fs via. nfs. This depends on the info in the
386  * nfs_diskless structure that has been filled in properly by some primary
387  * bootstrap.
388  * It goes something like this:
389  * - do enough of "ifconfig" by calling ifioctl() so that the system
390  *   can talk to the server
391  * - If nfs_diskless.mygateway is filled in, use that address as
392  *   a default gateway.
393  * - build the rootfs mount point and call mountnfs() to do the rest.
394  *
395  * It is assumed to be safe to read, modify, and write the nfsv3_diskless
396  * structure, as well as other global NFS client variables here, as
397  * nfs_mountroot() will be called once in the boot before any other NFS
398  * client activity occurs.
399  */
400 static int
401 nfs_mountroot(struct mount *mp)
402 {
403         struct thread *td = curthread;
404         struct nfsv3_diskless *nd = &nfsv3_diskless;
405         struct socket *so;
406         struct vnode *vp;
407         struct ifreq ir;
408         int error;
409         u_long l;
410         char buf[128];
411         char *cp;
412
413 #if defined(BOOTP_NFSROOT) && defined(BOOTP)
414         bootpc_init();          /* use bootp to get nfs_diskless filled in */
415 #elif defined(NFS_ROOT)
416         nfs_setup_diskless();
417 #endif
418
419         if (nfs_diskless_valid == 0)
420                 return (-1);
421         if (nfs_diskless_valid == 1)
422                 nfs_convert_diskless();
423
424         /*
425          * Do enough of ifconfig(8) so that the critical net interface can
426          * talk to the server.
427          */
428         error = socreate(nd->myif.ifra_addr.sa_family, &so, nd->root_args.sotype, 0,
429             td->td_ucred, td);
430         if (error)
431                 panic("nfs_mountroot: socreate(%04x): %d",
432                         nd->myif.ifra_addr.sa_family, error);
433
434 #if 0 /* XXX Bad idea */
435         /*
436          * We might not have been told the right interface, so we pass
437          * over the first ten interfaces of the same kind, until we get
438          * one of them configured.
439          */
440
441         for (i = strlen(nd->myif.ifra_name) - 1;
442                 nd->myif.ifra_name[i] >= '0' &&
443                 nd->myif.ifra_name[i] <= '9';
444                 nd->myif.ifra_name[i] ++) {
445                 error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
446                 if(!error)
447                         break;
448         }
449 #endif
450         error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
451         if (error)
452                 panic("nfs_mountroot: SIOCAIFADDR: %d", error);
453         if ((cp = kern_getenv("boot.netif.mtu")) != NULL) {
454                 ir.ifr_mtu = strtol(cp, NULL, 10);
455                 bcopy(nd->myif.ifra_name, ir.ifr_name, IFNAMSIZ);
456                 freeenv(cp);
457                 error = ifioctl(so, SIOCSIFMTU, (caddr_t)&ir, td);
458                 if (error)
459                         printf("nfs_mountroot: SIOCSIFMTU: %d", error);
460         }
461         soclose(so);
462
463         /*
464          * If the gateway field is filled in, set it as the default route.
465          * Note that pxeboot will set a default route of 0 if the route
466          * is not set by the DHCP server.  Check also for a value of 0
467          * to avoid panicking inappropriately in that situation.
468          */
469         if (nd->mygateway.sin_len != 0 &&
470             nd->mygateway.sin_addr.s_addr != 0) {
471                 struct sockaddr_in mask, sin;
472                 struct epoch_tracker et;
473                 struct rt_addrinfo info;
474                 struct rib_cmd_info rc;
475
476                 bzero((caddr_t)&mask, sizeof(mask));
477                 sin = mask;
478                 sin.sin_family = AF_INET;
479                 sin.sin_len = sizeof(sin);
480                 /* XXX MRT use table 0 for this sort of thing */
481                 NET_EPOCH_ENTER(et);
482                 CURVNET_SET(TD_TO_VNET(td));
483
484                 bzero((caddr_t)&info, sizeof(info));
485                 info.rti_flags = RTF_UP | RTF_GATEWAY;
486                 info.rti_info[RTAX_DST] = (struct sockaddr *)&sin;
487                 info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&nd->mygateway;
488                 info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&mask;
489
490                 error = rib_action(RT_DEFAULT_FIB, RTM_ADD, &info, &rc);
491                 CURVNET_RESTORE();
492                 NET_EPOCH_EXIT(et);
493                 if (error)
494                         panic("nfs_mountroot: RTM_ADD: %d", error);
495         }
496
497         /*
498          * Create the rootfs mount point.
499          */
500         nd->root_args.fh = nd->root_fh;
501         nd->root_args.fhsize = nd->root_fhsize;
502         l = ntohl(nd->root_saddr.sin_addr.s_addr);
503         snprintf(buf, sizeof(buf), "%ld.%ld.%ld.%ld:%s",
504                 (l >> 24) & 0xff, (l >> 16) & 0xff,
505                 (l >>  8) & 0xff, (l >>  0) & 0xff, nd->root_hostnam);
506         printf("NFS ROOT: %s\n", buf);
507         nd->root_args.hostname = buf;
508         if ((error = nfs_mountdiskless(buf,
509             &nd->root_saddr, &nd->root_args, td, &vp, mp)) != 0) {
510                 return (error);
511         }
512
513         /*
514          * This is not really an nfs issue, but it is much easier to
515          * set hostname here and then let the "/etc/rc.xxx" files
516          * mount the right /var based upon its preset value.
517          */
518         mtx_lock(&prison0.pr_mtx);
519         strlcpy(prison0.pr_hostname, nd->my_hostnam,
520             sizeof(prison0.pr_hostname));
521         mtx_unlock(&prison0.pr_mtx);
522         inittodr(ntohl(nd->root_time));
523         return (0);
524 }
525
526 /*
527  * Internal version of mount system call for diskless setup.
528  */
529 static int
530 nfs_mountdiskless(char *path,
531     struct sockaddr_in *sin, struct nfs_args *args, struct thread *td,
532     struct vnode **vpp, struct mount *mp)
533 {
534         struct sockaddr *nam;
535         int dirlen, error;
536         char *dirpath;
537
538         /*
539          * Find the directory path in "path", which also has the server's
540          * name/ip address in it.
541          */
542         dirpath = strchr(path, ':');
543         if (dirpath != NULL)
544                 dirlen = strlen(++dirpath);
545         else
546                 dirlen = 0;
547         nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK);
548         if ((error = mountnfs(args, mp, nam, path, NULL, 0, dirpath, dirlen,
549             NULL, 0, vpp, td->td_ucred, td, NFS_DEFAULT_NAMETIMEO, 
550             NFS_DEFAULT_NEGNAMETIMEO, 0, 0)) != 0) {
551                 printf("nfs_mountroot: mount %s on /: %d\n", path, error);
552                 return (error);
553         }
554         return (0);
555 }
556
557 static void
558 nfs_sec_name(char *sec, int *flagsp)
559 {
560         if (!strcmp(sec, "krb5"))
561                 *flagsp |= NFSMNT_KERB;
562         else if (!strcmp(sec, "krb5i"))
563                 *flagsp |= (NFSMNT_KERB | NFSMNT_INTEGRITY);
564         else if (!strcmp(sec, "krb5p"))
565                 *flagsp |= (NFSMNT_KERB | NFSMNT_PRIVACY);
566 }
567
568 static void
569 nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
570     const char *hostname, struct ucred *cred, struct thread *td)
571 {
572         int adjsock;
573         char *p;
574
575         /*
576          * Set read-only flag if requested; otherwise, clear it if this is
577          * an update.  If this is not an update, then either the read-only
578          * flag is already clear, or this is a root mount and it was set
579          * intentionally at some previous point.
580          */
581         if (vfs_getopt(mp->mnt_optnew, "ro", NULL, NULL) == 0) {
582                 MNT_ILOCK(mp);
583                 mp->mnt_flag |= MNT_RDONLY;
584                 MNT_IUNLOCK(mp);
585         } else if (mp->mnt_flag & MNT_UPDATE) {
586                 MNT_ILOCK(mp);
587                 mp->mnt_flag &= ~MNT_RDONLY;
588                 MNT_IUNLOCK(mp);
589         }
590
591         /*
592          * Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes
593          * no sense in that context.  Also, set up appropriate retransmit
594          * and soft timeout behavior.
595          */
596         if (argp->sotype == SOCK_STREAM) {
597                 nmp->nm_flag &= ~NFSMNT_NOCONN;
598                 nmp->nm_timeo = NFS_MAXTIMEO;
599                 if ((argp->flags & NFSMNT_NFSV4) != 0)
600                         nmp->nm_retry = INT_MAX;
601                 else
602                         nmp->nm_retry = NFS_RETRANS_TCP;
603         }
604
605         /* Also clear RDIRPLUS if NFSv2, it crashes some servers */
606         if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0) {
607                 argp->flags &= ~NFSMNT_RDIRPLUS;
608                 nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
609         }
610
611         /* Clear ONEOPENOWN for NFSv2, 3 and 4.0. */
612         if (nmp->nm_minorvers == 0) {
613                 argp->flags &= ~NFSMNT_ONEOPENOWN;
614                 nmp->nm_flag &= ~NFSMNT_ONEOPENOWN;
615         }
616
617         /* Re-bind if rsrvd port requested and wasn't on one */
618         adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT)
619                   && (argp->flags & NFSMNT_RESVPORT);
620         /* Also re-bind if we're switching to/from a connected UDP socket */
621         adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) !=
622                     (argp->flags & NFSMNT_NOCONN));
623
624         /* Update flags atomically.  Don't change the lock bits. */
625         nmp->nm_flag = argp->flags | nmp->nm_flag;
626
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;
633         }
634
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;
639         }
640
641         if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) {
642                 nmp->nm_wsize = argp->wsize;
643                 /*
644                  * Clip at the power of 2 below the size. There is an
645                  * issue (not isolated) that causes intermittent page
646                  * faults if this is not done.
647                  */
648                 if (nmp->nm_wsize > NFS_FABLKSIZE)
649                         nmp->nm_wsize = 1 << (fls(nmp->nm_wsize) - 1);
650                 else
651                         nmp->nm_wsize = NFS_FABLKSIZE;
652         }
653
654         if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) {
655                 nmp->nm_rsize = argp->rsize;
656                 /*
657                  * Clip at the power of 2 below the size. There is an
658                  * issue (not isolated) that causes intermittent page
659                  * faults if this is not done.
660                  */
661                 if (nmp->nm_rsize > NFS_FABLKSIZE)
662                         nmp->nm_rsize = 1 << (fls(nmp->nm_rsize) - 1);
663                 else
664                         nmp->nm_rsize = NFS_FABLKSIZE;
665         }
666
667         if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) {
668                 nmp->nm_readdirsize = argp->readdirsize;
669         }
670
671         if ((argp->flags & NFSMNT_ACREGMIN) && argp->acregmin >= 0)
672                 nmp->nm_acregmin = argp->acregmin;
673         else
674                 nmp->nm_acregmin = NFS_MINATTRTIMO;
675         if ((argp->flags & NFSMNT_ACREGMAX) && argp->acregmax >= 0)
676                 nmp->nm_acregmax = argp->acregmax;
677         else
678                 nmp->nm_acregmax = NFS_MAXATTRTIMO;
679         if ((argp->flags & NFSMNT_ACDIRMIN) && argp->acdirmin >= 0)
680                 nmp->nm_acdirmin = argp->acdirmin;
681         else
682                 nmp->nm_acdirmin = NFS_MINDIRATTRTIMO;
683         if ((argp->flags & NFSMNT_ACDIRMAX) && argp->acdirmax >= 0)
684                 nmp->nm_acdirmax = argp->acdirmax;
685         else
686                 nmp->nm_acdirmax = NFS_MAXDIRATTRTIMO;
687         if (nmp->nm_acdirmin > nmp->nm_acdirmax)
688                 nmp->nm_acdirmin = nmp->nm_acdirmax;
689         if (nmp->nm_acregmin > nmp->nm_acregmax)
690                 nmp->nm_acregmin = nmp->nm_acregmax;
691
692         if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0) {
693                 if (argp->readahead <= NFS_MAXRAHEAD)
694                         nmp->nm_readahead = argp->readahead;
695                 else
696                         nmp->nm_readahead = NFS_MAXRAHEAD;
697         }
698         if ((argp->flags & NFSMNT_WCOMMITSIZE) && argp->wcommitsize >= 0) {
699                 if (argp->wcommitsize < nmp->nm_wsize)
700                         nmp->nm_wcommitsize = nmp->nm_wsize;
701                 else
702                         nmp->nm_wcommitsize = argp->wcommitsize;
703         }
704
705         adjsock |= ((nmp->nm_sotype != argp->sotype) ||
706                     (nmp->nm_soproto != argp->proto));
707
708         if (nmp->nm_client != NULL && adjsock) {
709                 int haslock = 0, error = 0;
710
711                 if (nmp->nm_sotype == SOCK_STREAM) {
712                         error = newnfs_sndlock(&nmp->nm_sockreq.nr_lock);
713                         if (!error)
714                                 haslock = 1;
715                 }
716                 if (!error) {
717                     newnfs_disconnect(&nmp->nm_sockreq);
718                     if (haslock)
719                         newnfs_sndunlock(&nmp->nm_sockreq.nr_lock);
720                     nmp->nm_sotype = argp->sotype;
721                     nmp->nm_soproto = argp->proto;
722                     if (nmp->nm_sotype == SOCK_DGRAM)
723                         while (newnfs_connect(nmp, &nmp->nm_sockreq,
724                             cred, td, 0, false)) {
725                                 printf("newnfs_args: retrying connect\n");
726                                 (void) nfs_catnap(PSOCK, 0, "nfscon");
727                         }
728                 }
729         } else {
730                 nmp->nm_sotype = argp->sotype;
731                 nmp->nm_soproto = argp->proto;
732         }
733
734         if (hostname != NULL) {
735                 strlcpy(nmp->nm_hostname, hostname,
736                     sizeof(nmp->nm_hostname));
737                 p = strchr(nmp->nm_hostname, ':');
738                 if (p != NULL)
739                         *p = '\0';
740         }
741 }
742
743 static const char *nfs_opts[] = { "from", "nfs_args",
744     "noac", "noatime", "noexec", "suiddir", "nosuid", "nosymfollow", "union",
745     "noclusterr", "noclusterw", "multilabel", "acls", "force", "update",
746     "async", "noconn", "nolockd", "conn", "lockd", "intr", "rdirplus",
747     "readdirsize", "soft", "hard", "mntudp", "tcp", "udp", "wsize", "rsize",
748     "retrans", "actimeo", "acregmin", "acregmax", "acdirmin", "acdirmax",
749     "resvport", "readahead", "hostname", "timeo", "timeout", "addr", "fh",
750     "nfsv3", "sec", "principal", "nfsv4", "gssname", "allgssname", "dirpath",
751     "minorversion", "nametimeo", "negnametimeo", "nocto", "noncontigwr",
752     "pnfs", "wcommitsize", "oneopenown", "tls",
753     NULL };
754
755 /*
756  * Parse the "from" mountarg, passed by the generic mount(8) program
757  * or the mountroot code.  This is used when rerooting into NFS.
758  *
759  * Note that the "hostname" is actually a "hostname:/share/path" string.
760  */
761 static int
762 nfs_mount_parse_from(struct vfsoptlist *opts, char **hostnamep,
763     struct sockaddr_in **sinp, char *dirpath, size_t dirpathsize, int *dirlenp)
764 {
765         char *nam, *delimp, *hostp, *spec;
766         int error, have_bracket = 0, offset, rv, speclen;
767         struct sockaddr_in *sin;
768         size_t len;
769
770         error = vfs_getopt(opts, "from", (void **)&spec, &speclen);
771         if (error != 0)
772                 return (error);
773         nam = malloc(MNAMELEN + 1, M_TEMP, M_WAITOK);
774
775         /*
776          * This part comes from sbin/mount_nfs/mount_nfs.c:getnfsargs().
777          */
778         if (*spec == '[' && (delimp = strchr(spec + 1, ']')) != NULL &&
779             *(delimp + 1) == ':') {
780                 hostp = spec + 1;
781                 spec = delimp + 2;
782                 have_bracket = 1;
783         } else if ((delimp = strrchr(spec, ':')) != NULL) {
784                 hostp = spec;
785                 spec = delimp + 1;
786         } else if ((delimp = strrchr(spec, '@')) != NULL) {
787                 printf("%s: path@server syntax is deprecated, "
788                     "use server:path\n", __func__);
789                 hostp = delimp + 1;
790         } else {
791                 printf("%s: no <host>:<dirpath> nfs-name\n", __func__);
792                 free(nam, M_TEMP);
793                 return (EINVAL);
794         }
795         *delimp = '\0';
796
797         /*
798          * If there has been a trailing slash at mounttime it seems
799          * that some mountd implementations fail to remove the mount
800          * entries from their mountlist while unmounting.
801          */
802         for (speclen = strlen(spec);
803             speclen > 1 && spec[speclen - 1] == '/';
804             speclen--)
805                 spec[speclen - 1] = '\0';
806         if (strlen(hostp) + strlen(spec) + 1 > MNAMELEN) {
807                 printf("%s: %s:%s: name too long", __func__, hostp, spec);
808                 free(nam, M_TEMP);
809                 return (EINVAL);
810         }
811         /* Make both '@' and ':' notations equal */
812         if (*hostp != '\0') {
813                 len = strlen(hostp);
814                 offset = 0;
815                 if (have_bracket)
816                         nam[offset++] = '[';
817                 memmove(nam + offset, hostp, len);
818                 if (have_bracket)
819                         nam[len + offset++] = ']';
820                 nam[len + offset++] = ':';
821                 memmove(nam + len + offset, spec, speclen);
822                 nam[len + speclen + offset] = '\0';
823         } else
824                 nam[0] = '\0';
825
826         /*
827          * XXX: IPv6
828          */
829         sin = malloc(sizeof(*sin), M_SONAME, M_WAITOK);
830         rv = inet_pton(AF_INET, hostp, &sin->sin_addr);
831         if (rv != 1) {
832                 printf("%s: cannot parse '%s', inet_pton() returned %d\n",
833                     __func__, hostp, rv);
834                 free(nam, M_TEMP);
835                 free(sin, M_SONAME);
836                 return (EINVAL);
837         }
838
839         sin->sin_len = sizeof(*sin);
840         sin->sin_family = AF_INET;
841         /*
842          * XXX: hardcoded port number.
843          */
844         sin->sin_port = htons(2049);
845
846         *hostnamep = strdup(nam, M_NEWNFSMNT);
847         *sinp = sin;
848         strlcpy(dirpath, spec, dirpathsize);
849         *dirlenp = strlen(dirpath);
850
851         free(nam, M_TEMP);
852         return (0);
853 }
854
855 /*
856  * VFS Operations.
857  *
858  * mount system call
859  * It seems a bit dumb to copyinstr() the host and path here and then
860  * bcopy() them in mountnfs(), but I wanted to detect errors before
861  * doing the getsockaddr() call because getsockaddr() allocates an mbuf and
862  * an error after that means that I have to release the mbuf.
863  */
864 /* ARGSUSED */
865 static int
866 nfs_mount(struct mount *mp)
867 {
868         struct nfs_args args = {
869             .version = NFS_ARGSVERSION,
870             .addr = NULL,
871             .addrlen = sizeof (struct sockaddr_in),
872             .sotype = SOCK_STREAM,
873             .proto = 0,
874             .fh = NULL,
875             .fhsize = 0,
876             .flags = NFSMNT_RESVPORT,
877             .wsize = NFS_WSIZE,
878             .rsize = NFS_RSIZE,
879             .readdirsize = NFS_READDIRSIZE,
880             .timeo = 10,
881             .retrans = NFS_RETRANS,
882             .readahead = NFS_DEFRAHEAD,
883             .wcommitsize = 0,                   /* was: NQ_DEFLEASE */
884             .hostname = NULL,
885             .acregmin = NFS_MINATTRTIMO,
886             .acregmax = NFS_MAXATTRTIMO,
887             .acdirmin = NFS_MINDIRATTRTIMO,
888             .acdirmax = NFS_MAXDIRATTRTIMO,
889         };
890         int error = 0, ret, len;
891         struct sockaddr *nam = NULL;
892         struct vnode *vp;
893         struct thread *td;
894         char *hst;
895         u_char nfh[NFSX_FHMAX], krbname[100], dirpath[100], srvkrbname[100];
896         char *cp, *opt, *name, *secname;
897         int nametimeo = NFS_DEFAULT_NAMETIMEO;
898         int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO;
899         int minvers = 0;
900         int dirlen, has_nfs_args_opt, has_nfs_from_opt,
901             krbnamelen, srvkrbnamelen;
902         size_t hstlen;
903         uint32_t newflag;
904
905         has_nfs_args_opt = 0;
906         has_nfs_from_opt = 0;
907         newflag = 0;
908         hst = malloc(MNAMELEN, M_TEMP, M_WAITOK);
909         if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) {
910                 error = EINVAL;
911                 goto out;
912         }
913
914         td = curthread;
915         if ((mp->mnt_flag & (MNT_ROOTFS | MNT_UPDATE)) == MNT_ROOTFS &&
916             nfs_diskless_valid != 0) {
917                 error = nfs_mountroot(mp);
918                 goto out;
919         }
920
921         nfscl_init();
922
923         /*
924          * The old mount_nfs program passed the struct nfs_args
925          * from userspace to kernel.  The new mount_nfs program
926          * passes string options via nmount() from userspace to kernel
927          * and we populate the struct nfs_args in the kernel.
928          */
929         if (vfs_getopt(mp->mnt_optnew, "nfs_args", NULL, NULL) == 0) {
930                 error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args,
931                     sizeof(args));
932                 if (error != 0)
933                         goto out;
934
935                 if (args.version != NFS_ARGSVERSION) {
936                         error = EPROGMISMATCH;
937                         goto out;
938                 }
939                 has_nfs_args_opt = 1;
940         }
941
942         /* Handle the new style options. */
943         if (vfs_getopt(mp->mnt_optnew, "noac", NULL, NULL) == 0) {
944                 args.acdirmin = args.acdirmax =
945                     args.acregmin = args.acregmax = 0;
946                 args.flags |= NFSMNT_ACDIRMIN | NFSMNT_ACDIRMAX |
947                     NFSMNT_ACREGMIN | NFSMNT_ACREGMAX;
948         }
949         if (vfs_getopt(mp->mnt_optnew, "noconn", NULL, NULL) == 0)
950                 args.flags |= NFSMNT_NOCONN;
951         if (vfs_getopt(mp->mnt_optnew, "conn", NULL, NULL) == 0)
952                 args.flags &= ~NFSMNT_NOCONN;
953         if (vfs_getopt(mp->mnt_optnew, "nolockd", NULL, NULL) == 0)
954                 args.flags |= NFSMNT_NOLOCKD;
955         if (vfs_getopt(mp->mnt_optnew, "lockd", NULL, NULL) == 0)
956                 args.flags &= ~NFSMNT_NOLOCKD;
957         if (vfs_getopt(mp->mnt_optnew, "intr", NULL, NULL) == 0)
958                 args.flags |= NFSMNT_INT;
959         if (vfs_getopt(mp->mnt_optnew, "rdirplus", NULL, NULL) == 0)
960                 args.flags |= NFSMNT_RDIRPLUS;
961         if (vfs_getopt(mp->mnt_optnew, "resvport", NULL, NULL) == 0)
962                 args.flags |= NFSMNT_RESVPORT;
963         if (vfs_getopt(mp->mnt_optnew, "noresvport", NULL, NULL) == 0)
964                 args.flags &= ~NFSMNT_RESVPORT;
965         if (vfs_getopt(mp->mnt_optnew, "soft", NULL, NULL) == 0)
966                 args.flags |= NFSMNT_SOFT;
967         if (vfs_getopt(mp->mnt_optnew, "hard", NULL, NULL) == 0)
968                 args.flags &= ~NFSMNT_SOFT;
969         if (vfs_getopt(mp->mnt_optnew, "mntudp", NULL, NULL) == 0)
970                 args.sotype = SOCK_DGRAM;
971         if (vfs_getopt(mp->mnt_optnew, "udp", NULL, NULL) == 0)
972                 args.sotype = SOCK_DGRAM;
973         if (vfs_getopt(mp->mnt_optnew, "tcp", NULL, NULL) == 0)
974                 args.sotype = SOCK_STREAM;
975         if (vfs_getopt(mp->mnt_optnew, "nfsv3", NULL, NULL) == 0)
976                 args.flags |= NFSMNT_NFSV3;
977         if (vfs_getopt(mp->mnt_optnew, "nfsv4", NULL, NULL) == 0) {
978                 args.flags |= NFSMNT_NFSV4;
979                 args.sotype = SOCK_STREAM;
980         }
981         if (vfs_getopt(mp->mnt_optnew, "allgssname", NULL, NULL) == 0)
982                 args.flags |= NFSMNT_ALLGSSNAME;
983         if (vfs_getopt(mp->mnt_optnew, "nocto", NULL, NULL) == 0)
984                 args.flags |= NFSMNT_NOCTO;
985         if (vfs_getopt(mp->mnt_optnew, "noncontigwr", NULL, NULL) == 0)
986                 args.flags |= NFSMNT_NONCONTIGWR;
987         if (vfs_getopt(mp->mnt_optnew, "pnfs", NULL, NULL) == 0)
988                 args.flags |= NFSMNT_PNFS;
989         if (vfs_getopt(mp->mnt_optnew, "oneopenown", NULL, NULL) == 0)
990                 args.flags |= NFSMNT_ONEOPENOWN;
991         if (vfs_getopt(mp->mnt_optnew, "tls", NULL, NULL) == 0)
992                 newflag |= NFSMNT_TLS;
993         if (vfs_getopt(mp->mnt_optnew, "readdirsize", (void **)&opt, NULL) == 0) {
994                 if (opt == NULL) { 
995                         vfs_mount_error(mp, "illegal readdirsize");
996                         error = EINVAL;
997                         goto out;
998                 }
999                 ret = sscanf(opt, "%d", &args.readdirsize);
1000                 if (ret != 1 || args.readdirsize <= 0) {
1001                         vfs_mount_error(mp, "illegal readdirsize: %s",
1002                             opt);
1003                         error = EINVAL;
1004                         goto out;
1005                 }
1006                 args.flags |= NFSMNT_READDIRSIZE;
1007         }
1008         if (vfs_getopt(mp->mnt_optnew, "readahead", (void **)&opt, NULL) == 0) {
1009                 if (opt == NULL) { 
1010                         vfs_mount_error(mp, "illegal readahead");
1011                         error = EINVAL;
1012                         goto out;
1013                 }
1014                 ret = sscanf(opt, "%d", &args.readahead);
1015                 if (ret != 1 || args.readahead <= 0) {
1016                         vfs_mount_error(mp, "illegal readahead: %s",
1017                             opt);
1018                         error = EINVAL;
1019                         goto out;
1020                 }
1021                 args.flags |= NFSMNT_READAHEAD;
1022         }
1023         if (vfs_getopt(mp->mnt_optnew, "wsize", (void **)&opt, NULL) == 0) {
1024                 if (opt == NULL) { 
1025                         vfs_mount_error(mp, "illegal wsize");
1026                         error = EINVAL;
1027                         goto out;
1028                 }
1029                 ret = sscanf(opt, "%d", &args.wsize);
1030                 if (ret != 1 || args.wsize <= 0) {
1031                         vfs_mount_error(mp, "illegal wsize: %s",
1032                             opt);
1033                         error = EINVAL;
1034                         goto out;
1035                 }
1036                 args.flags |= NFSMNT_WSIZE;
1037         }
1038         if (vfs_getopt(mp->mnt_optnew, "rsize", (void **)&opt, NULL) == 0) {
1039                 if (opt == NULL) { 
1040                         vfs_mount_error(mp, "illegal rsize");
1041                         error = EINVAL;
1042                         goto out;
1043                 }
1044                 ret = sscanf(opt, "%d", &args.rsize);
1045                 if (ret != 1 || args.rsize <= 0) {
1046                         vfs_mount_error(mp, "illegal wsize: %s",
1047                             opt);
1048                         error = EINVAL;
1049                         goto out;
1050                 }
1051                 args.flags |= NFSMNT_RSIZE;
1052         }
1053         if (vfs_getopt(mp->mnt_optnew, "retrans", (void **)&opt, NULL) == 0) {
1054                 if (opt == NULL) { 
1055                         vfs_mount_error(mp, "illegal retrans");
1056                         error = EINVAL;
1057                         goto out;
1058                 }
1059                 ret = sscanf(opt, "%d", &args.retrans);
1060                 if (ret != 1 || args.retrans <= 0) {
1061                         vfs_mount_error(mp, "illegal retrans: %s",
1062                             opt);
1063                         error = EINVAL;
1064                         goto out;
1065                 }
1066                 args.flags |= NFSMNT_RETRANS;
1067         }
1068         if (vfs_getopt(mp->mnt_optnew, "actimeo", (void **)&opt, NULL) == 0) {
1069                 ret = sscanf(opt, "%d", &args.acregmin);
1070                 if (ret != 1 || args.acregmin < 0) {
1071                         vfs_mount_error(mp, "illegal actimeo: %s",
1072                             opt);
1073                         error = EINVAL;
1074                         goto out;
1075                 }
1076                 args.acdirmin = args.acdirmax = args.acregmax = args.acregmin;
1077                 args.flags |= NFSMNT_ACDIRMIN | NFSMNT_ACDIRMAX |
1078                     NFSMNT_ACREGMIN | NFSMNT_ACREGMAX;
1079         }
1080         if (vfs_getopt(mp->mnt_optnew, "acregmin", (void **)&opt, NULL) == 0) {
1081                 ret = sscanf(opt, "%d", &args.acregmin);
1082                 if (ret != 1 || args.acregmin < 0) {
1083                         vfs_mount_error(mp, "illegal acregmin: %s",
1084                             opt);
1085                         error = EINVAL;
1086                         goto out;
1087                 }
1088                 args.flags |= NFSMNT_ACREGMIN;
1089         }
1090         if (vfs_getopt(mp->mnt_optnew, "acregmax", (void **)&opt, NULL) == 0) {
1091                 ret = sscanf(opt, "%d", &args.acregmax);
1092                 if (ret != 1 || args.acregmax < 0) {
1093                         vfs_mount_error(mp, "illegal acregmax: %s",
1094                             opt);
1095                         error = EINVAL;
1096                         goto out;
1097                 }
1098                 args.flags |= NFSMNT_ACREGMAX;
1099         }
1100         if (vfs_getopt(mp->mnt_optnew, "acdirmin", (void **)&opt, NULL) == 0) {
1101                 ret = sscanf(opt, "%d", &args.acdirmin);
1102                 if (ret != 1 || args.acdirmin < 0) {
1103                         vfs_mount_error(mp, "illegal acdirmin: %s",
1104                             opt);
1105                         error = EINVAL;
1106                         goto out;
1107                 }
1108                 args.flags |= NFSMNT_ACDIRMIN;
1109         }
1110         if (vfs_getopt(mp->mnt_optnew, "acdirmax", (void **)&opt, NULL) == 0) {
1111                 ret = sscanf(opt, "%d", &args.acdirmax);
1112                 if (ret != 1 || args.acdirmax < 0) {
1113                         vfs_mount_error(mp, "illegal acdirmax: %s",
1114                             opt);
1115                         error = EINVAL;
1116                         goto out;
1117                 }
1118                 args.flags |= NFSMNT_ACDIRMAX;
1119         }
1120         if (vfs_getopt(mp->mnt_optnew, "wcommitsize", (void **)&opt, NULL) == 0) {
1121                 ret = sscanf(opt, "%d", &args.wcommitsize);
1122                 if (ret != 1 || args.wcommitsize < 0) {
1123                         vfs_mount_error(mp, "illegal wcommitsize: %s", opt);
1124                         error = EINVAL;
1125                         goto out;
1126                 }
1127                 args.flags |= NFSMNT_WCOMMITSIZE;
1128         }
1129         if (vfs_getopt(mp->mnt_optnew, "timeo", (void **)&opt, NULL) == 0) {
1130                 ret = sscanf(opt, "%d", &args.timeo);
1131                 if (ret != 1 || args.timeo <= 0) {
1132                         vfs_mount_error(mp, "illegal timeo: %s",
1133                             opt);
1134                         error = EINVAL;
1135                         goto out;
1136                 }
1137                 args.flags |= NFSMNT_TIMEO;
1138         }
1139         if (vfs_getopt(mp->mnt_optnew, "timeout", (void **)&opt, NULL) == 0) {
1140                 ret = sscanf(opt, "%d", &args.timeo);
1141                 if (ret != 1 || args.timeo <= 0) {
1142                         vfs_mount_error(mp, "illegal timeout: %s",
1143                             opt);
1144                         error = EINVAL;
1145                         goto out;
1146                 }
1147                 args.flags |= NFSMNT_TIMEO;
1148         }
1149         if (vfs_getopt(mp->mnt_optnew, "nametimeo", (void **)&opt, NULL) == 0) {
1150                 ret = sscanf(opt, "%d", &nametimeo);
1151                 if (ret != 1 || nametimeo < 0) {
1152                         vfs_mount_error(mp, "illegal nametimeo: %s", opt);
1153                         error = EINVAL;
1154                         goto out;
1155                 }
1156         }
1157         if (vfs_getopt(mp->mnt_optnew, "negnametimeo", (void **)&opt, NULL)
1158             == 0) {
1159                 ret = sscanf(opt, "%d", &negnametimeo);
1160                 if (ret != 1 || negnametimeo < 0) {
1161                         vfs_mount_error(mp, "illegal negnametimeo: %s",
1162                             opt);
1163                         error = EINVAL;
1164                         goto out;
1165                 }
1166         }
1167         if (vfs_getopt(mp->mnt_optnew, "minorversion", (void **)&opt, NULL) ==
1168             0) {
1169                 ret = sscanf(opt, "%d", &minvers);
1170                 if (ret != 1 || minvers < 0 || minvers > 2 ||
1171                     (args.flags & NFSMNT_NFSV4) == 0) {
1172                         vfs_mount_error(mp, "illegal minorversion: %s", opt);
1173                         error = EINVAL;
1174                         goto out;
1175                 }
1176         }
1177         if (vfs_getopt(mp->mnt_optnew, "sec",
1178                 (void **) &secname, NULL) == 0)
1179                 nfs_sec_name(secname, &args.flags);
1180
1181         if (mp->mnt_flag & MNT_UPDATE) {
1182                 struct nfsmount *nmp = VFSTONFS(mp);
1183
1184                 if (nmp == NULL) {
1185                         error = EIO;
1186                         goto out;
1187                 }
1188
1189                 /*
1190                  * If a change from TCP->UDP is done and there are thread(s)
1191                  * that have I/O RPC(s) in progress with a transfer size
1192                  * greater than NFS_MAXDGRAMDATA, those thread(s) will be
1193                  * hung, retrying the RPC(s) forever. Usually these threads
1194                  * will be seen doing an uninterruptible sleep on wait channel
1195                  * "nfsreq".
1196                  */
1197                 if (args.sotype == SOCK_DGRAM && nmp->nm_sotype == SOCK_STREAM)
1198                         tprintf(td->td_proc, LOG_WARNING,
1199         "Warning: mount -u that changes TCP->UDP can result in hung threads\n");
1200
1201                 /*
1202                  * When doing an update, we can't change version,
1203                  * security, switch lockd strategies, change cookie
1204                  * translation or switch oneopenown.
1205                  */
1206                 args.flags = (args.flags &
1207                     ~(NFSMNT_NFSV3 |
1208                       NFSMNT_NFSV4 |
1209                       NFSMNT_KERB |
1210                       NFSMNT_INTEGRITY |
1211                       NFSMNT_PRIVACY |
1212                       NFSMNT_ONEOPENOWN |
1213                       NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) |
1214                     (nmp->nm_flag &
1215                         (NFSMNT_NFSV3 |
1216                          NFSMNT_NFSV4 |
1217                          NFSMNT_KERB |
1218                          NFSMNT_INTEGRITY |
1219                          NFSMNT_PRIVACY |
1220                          NFSMNT_ONEOPENOWN |
1221                          NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
1222                 nfs_decode_args(mp, nmp, &args, NULL, td->td_ucred, td);
1223                 goto out;
1224         }
1225
1226         /*
1227          * Make the nfs_ip_paranoia sysctl serve as the default connection
1228          * or no-connection mode for those protocols that support 
1229          * no-connection mode (the flag will be cleared later for protocols
1230          * that do not support no-connection mode).  This will allow a client
1231          * to receive replies from a different IP then the request was
1232          * sent to.  Note: default value for nfs_ip_paranoia is 1 (paranoid),
1233          * not 0.
1234          */
1235         if (nfs_ip_paranoia == 0)
1236                 args.flags |= NFSMNT_NOCONN;
1237
1238         if (has_nfs_args_opt != 0) {
1239                 /*
1240                  * In the 'nfs_args' case, the pointers in the args
1241                  * structure are in userland - we copy them in here.
1242                  */
1243                 if (args.fhsize < 0 || args.fhsize > NFSX_V3FHMAX) {
1244                         vfs_mount_error(mp, "Bad file handle");
1245                         error = EINVAL;
1246                         goto out;
1247                 }
1248                 error = copyin((caddr_t)args.fh, (caddr_t)nfh,
1249                     args.fhsize);
1250                 if (error != 0)
1251                         goto out;
1252                 error = copyinstr(args.hostname, hst, MNAMELEN - 1, &hstlen);
1253                 if (error != 0)
1254                         goto out;
1255                 bzero(&hst[hstlen], MNAMELEN - hstlen);
1256                 args.hostname = hst;
1257                 /* getsockaddr() call must be after above copyin() calls */
1258                 error = getsockaddr(&nam, args.addr, args.addrlen);
1259                 if (error != 0)
1260                         goto out;
1261         } else if (nfs_mount_parse_from(mp->mnt_optnew,
1262             &args.hostname, (struct sockaddr_in **)&nam, dirpath,
1263             sizeof(dirpath), &dirlen) == 0) {
1264                 has_nfs_from_opt = 1;
1265                 bcopy(args.hostname, hst, MNAMELEN);
1266                 hst[MNAMELEN - 1] = '\0';
1267
1268                 /*
1269                  * This only works with NFSv4 for now.
1270                  */
1271                 args.fhsize = 0;
1272                 args.flags |= NFSMNT_NFSV4;
1273                 args.sotype = SOCK_STREAM;
1274         } else {
1275                 if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh,
1276                     &args.fhsize) == 0) {
1277                         if (args.fhsize < 0 || args.fhsize > NFSX_FHMAX) {
1278                                 vfs_mount_error(mp, "Bad file handle");
1279                                 error = EINVAL;
1280                                 goto out;
1281                         }
1282                         bcopy(args.fh, nfh, args.fhsize);
1283                 } else {
1284                         args.fhsize = 0;
1285                 }
1286                 (void) vfs_getopt(mp->mnt_optnew, "hostname",
1287                     (void **)&args.hostname, &len);
1288                 if (args.hostname == NULL) {
1289                         vfs_mount_error(mp, "Invalid hostname");
1290                         error = EINVAL;
1291                         goto out;
1292                 }
1293                 if (len >= MNAMELEN) {
1294                         vfs_mount_error(mp, "Hostname too long");
1295                         error = EINVAL;
1296                         goto out;
1297                 }
1298                 bcopy(args.hostname, hst, len);
1299                 hst[len] = '\0';
1300         }
1301
1302         if (vfs_getopt(mp->mnt_optnew, "principal", (void **)&name, NULL) == 0)
1303                 strlcpy(srvkrbname, name, sizeof (srvkrbname));
1304         else {
1305                 snprintf(srvkrbname, sizeof (srvkrbname), "nfs@%s", hst);
1306                 cp = strchr(srvkrbname, ':');
1307                 if (cp != NULL)
1308                         *cp = '\0';
1309         }
1310         srvkrbnamelen = strlen(srvkrbname);
1311
1312         if (vfs_getopt(mp->mnt_optnew, "gssname", (void **)&name, NULL) == 0)
1313                 strlcpy(krbname, name, sizeof (krbname));
1314         else
1315                 krbname[0] = '\0';
1316         krbnamelen = strlen(krbname);
1317
1318         if (has_nfs_from_opt == 0) {
1319                 if (vfs_getopt(mp->mnt_optnew,
1320                     "dirpath", (void **)&name, NULL) == 0)
1321                         strlcpy(dirpath, name, sizeof (dirpath));
1322                 else
1323                         dirpath[0] = '\0';
1324                 dirlen = strlen(dirpath);
1325         }
1326
1327         if (has_nfs_args_opt == 0 && has_nfs_from_opt == 0) {
1328                 if (vfs_getopt(mp->mnt_optnew, "addr",
1329                     (void **)&args.addr, &args.addrlen) == 0) {
1330                         if (args.addrlen > SOCK_MAXADDRLEN) {
1331                                 error = ENAMETOOLONG;
1332                                 goto out;
1333                         }
1334                         nam = malloc(args.addrlen, M_SONAME, M_WAITOK);
1335                         bcopy(args.addr, nam, args.addrlen);
1336                         nam->sa_len = args.addrlen;
1337                 } else {
1338                         vfs_mount_error(mp, "No server address");
1339                         error = EINVAL;
1340                         goto out;
1341                 }
1342         }
1343
1344         args.fh = nfh;
1345         error = mountnfs(&args, mp, nam, hst, krbname, krbnamelen, dirpath,
1346             dirlen, srvkrbname, srvkrbnamelen, &vp, td->td_ucred, td,
1347             nametimeo, negnametimeo, minvers, newflag);
1348 out:
1349         if (!error) {
1350                 MNT_ILOCK(mp);
1351                 mp->mnt_kern_flag |= MNTK_LOOKUP_SHARED | MNTK_NO_IOPF |
1352                     MNTK_USES_BCACHE;
1353                 if ((VFSTONFS(mp)->nm_flag & NFSMNT_NFSV4) != 0)
1354                         mp->mnt_kern_flag |= MNTK_NULL_NOCACHE;
1355                 MNT_IUNLOCK(mp);
1356         }
1357         free(hst, M_TEMP);
1358         return (error);
1359 }
1360
1361
1362 /*
1363  * VFS Operations.
1364  *
1365  * mount system call
1366  * It seems a bit dumb to copyinstr() the host and path here and then
1367  * bcopy() them in mountnfs(), but I wanted to detect errors before
1368  * doing the getsockaddr() call because getsockaddr() allocates an mbuf and
1369  * an error after that means that I have to release the mbuf.
1370  */
1371 /* ARGSUSED */
1372 static int
1373 nfs_cmount(struct mntarg *ma, void *data, uint64_t flags)
1374 {
1375         int error;
1376         struct nfs_args args;
1377
1378         error = copyin(data, &args, sizeof (struct nfs_args));
1379         if (error)
1380                 return error;
1381
1382         ma = mount_arg(ma, "nfs_args", &args, sizeof args);
1383
1384         error = kernel_mount(ma, flags);
1385         return (error);
1386 }
1387
1388 /*
1389  * Common code for mount and mountroot
1390  */
1391 static int
1392 mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
1393     char *hst, u_char *krbname, int krbnamelen, u_char *dirpath, int dirlen,
1394     u_char *srvkrbname, int srvkrbnamelen, struct vnode **vpp,
1395     struct ucred *cred, struct thread *td, int nametimeo, int negnametimeo,
1396     int minvers, uint32_t newflag)
1397 {
1398         struct nfsmount *nmp;
1399         struct nfsnode *np;
1400         int error, trycnt, ret;
1401         struct nfsvattr nfsva;
1402         struct nfsclclient *clp;
1403         struct nfsclds *dsp, *tdsp;
1404         uint32_t lease;
1405         static u_int64_t clval = 0;
1406 #ifdef KERN_TLS
1407         u_int maxlen;
1408 #endif
1409
1410         NFSCL_DEBUG(3, "in mnt\n");
1411         clp = NULL;
1412         if (mp->mnt_flag & MNT_UPDATE) {
1413                 nmp = VFSTONFS(mp);
1414                 printf("%s: MNT_UPDATE is no longer handled here\n", __func__);
1415                 free(nam, M_SONAME);
1416                 return (0);
1417         } else {
1418                 /* NFS-over-TLS requires that rpctls be functioning. */
1419                 if ((newflag & NFSMNT_TLS) != 0) {
1420                         error = EINVAL;
1421 #ifdef KERN_TLS
1422                         if (rpctls_getinfo(&maxlen, true, false))
1423                                 error = 0;
1424 #endif
1425                         if (error != 0) {
1426                                 free(nam, M_SONAME);
1427                                 return (error);
1428                         }
1429                 }
1430                 nmp = malloc(sizeof (struct nfsmount) +
1431                     krbnamelen + dirlen + srvkrbnamelen + 2,
1432                     M_NEWNFSMNT, M_WAITOK | M_ZERO);
1433                 nmp->nm_newflag = newflag;
1434                 TAILQ_INIT(&nmp->nm_bufq);
1435                 TAILQ_INIT(&nmp->nm_sess);
1436                 if (clval == 0)
1437                         clval = (u_int64_t)nfsboottime.tv_sec;
1438                 nmp->nm_clval = clval++;
1439                 nmp->nm_krbnamelen = krbnamelen;
1440                 nmp->nm_dirpathlen = dirlen;
1441                 nmp->nm_srvkrbnamelen = srvkrbnamelen;
1442                 if (td->td_ucred->cr_uid != (uid_t)0) {
1443                         /*
1444                          * nm_uid is used to get KerberosV credentials for
1445                          * the nfsv4 state handling operations if there is
1446                          * no host based principal set. Use the uid of
1447                          * this user if not root, since they are doing the
1448                          * mount. I don't think setting this for root will
1449                          * work, since root normally does not have user
1450                          * credentials in a credentials cache.
1451                          */
1452                         nmp->nm_uid = td->td_ucred->cr_uid;
1453                 } else {
1454                         /*
1455                          * Just set to -1, so it won't be used.
1456                          */
1457                         nmp->nm_uid = (uid_t)-1;
1458                 }
1459
1460                 /* Copy and null terminate all the names */
1461                 if (nmp->nm_krbnamelen > 0) {
1462                         bcopy(krbname, nmp->nm_krbname, nmp->nm_krbnamelen);
1463                         nmp->nm_name[nmp->nm_krbnamelen] = '\0';
1464                 }
1465                 if (nmp->nm_dirpathlen > 0) {
1466                         bcopy(dirpath, NFSMNT_DIRPATH(nmp),
1467                             nmp->nm_dirpathlen);
1468                         nmp->nm_name[nmp->nm_krbnamelen + nmp->nm_dirpathlen
1469                             + 1] = '\0';
1470                 }
1471                 if (nmp->nm_srvkrbnamelen > 0) {
1472                         bcopy(srvkrbname, NFSMNT_SRVKRBNAME(nmp),
1473                             nmp->nm_srvkrbnamelen);
1474                         nmp->nm_name[nmp->nm_krbnamelen + nmp->nm_dirpathlen
1475                             + nmp->nm_srvkrbnamelen + 2] = '\0';
1476                 }
1477                 nmp->nm_sockreq.nr_cred = crhold(cred);
1478                 mtx_init(&nmp->nm_sockreq.nr_mtx, "nfssock", NULL, MTX_DEF);
1479                 mp->mnt_data = nmp;
1480                 nmp->nm_getinfo = nfs_getnlminfo;
1481                 nmp->nm_vinvalbuf = ncl_vinvalbuf;
1482         }
1483         vfs_getnewfsid(mp);
1484         nmp->nm_mountp = mp;
1485         mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF | MTX_DUPOK);
1486
1487         /*
1488          * Since nfs_decode_args() might optionally set them, these
1489          * need to be set to defaults before the call, so that the
1490          * optional settings aren't overwritten.
1491          */
1492         nmp->nm_nametimeo = nametimeo;
1493         nmp->nm_negnametimeo = negnametimeo;
1494         nmp->nm_timeo = NFS_TIMEO;
1495         nmp->nm_retry = NFS_RETRANS;
1496         nmp->nm_readahead = NFS_DEFRAHEAD;
1497
1498         /* This is empirical approximation of sqrt(hibufspace) * 256. */
1499         nmp->nm_wcommitsize = NFS_MAXBSIZE / 256;
1500         while ((long)nmp->nm_wcommitsize * nmp->nm_wcommitsize < hibufspace)
1501                 nmp->nm_wcommitsize *= 2;
1502         nmp->nm_wcommitsize *= 256;
1503
1504         if ((argp->flags & NFSMNT_NFSV4) != 0)
1505                 nmp->nm_minorvers = minvers;
1506         else
1507                 nmp->nm_minorvers = 0;
1508
1509         nfs_decode_args(mp, nmp, argp, hst, cred, td);
1510
1511         /*
1512          * V2 can only handle 32 bit filesizes.  A 4GB-1 limit may be too
1513          * high, depending on whether we end up with negative offsets in
1514          * the client or server somewhere.  2GB-1 may be safer.
1515          *
1516          * For V3, ncl_fsinfo will adjust this as necessary.  Assume maximum
1517          * that we can handle until we find out otherwise.
1518          */
1519         if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0)
1520                 nmp->nm_maxfilesize = 0xffffffffLL;
1521         else
1522                 nmp->nm_maxfilesize = OFF_MAX;
1523
1524         if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0) {
1525                 nmp->nm_wsize = NFS_WSIZE;
1526                 nmp->nm_rsize = NFS_RSIZE;
1527                 nmp->nm_readdirsize = NFS_READDIRSIZE;
1528         }
1529         nmp->nm_numgrps = NFS_MAXGRPS;
1530         nmp->nm_tprintf_delay = nfs_tprintf_delay;
1531         if (nmp->nm_tprintf_delay < 0)
1532                 nmp->nm_tprintf_delay = 0;
1533         nmp->nm_tprintf_initial_delay = nfs_tprintf_initial_delay;
1534         if (nmp->nm_tprintf_initial_delay < 0)
1535                 nmp->nm_tprintf_initial_delay = 0;
1536         nmp->nm_fhsize = argp->fhsize;
1537         if (nmp->nm_fhsize > 0)
1538                 bcopy((caddr_t)argp->fh, (caddr_t)nmp->nm_fh, argp->fhsize);
1539         bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);
1540         nmp->nm_nam = nam;
1541         /* Set up the sockets and per-host congestion */
1542         nmp->nm_sotype = argp->sotype;
1543         nmp->nm_soproto = argp->proto;
1544         nmp->nm_sockreq.nr_prog = NFS_PROG;
1545         if ((argp->flags & NFSMNT_NFSV4))
1546                 nmp->nm_sockreq.nr_vers = NFS_VER4;
1547         else if ((argp->flags & NFSMNT_NFSV3))
1548                 nmp->nm_sockreq.nr_vers = NFS_VER3;
1549         else
1550                 nmp->nm_sockreq.nr_vers = NFS_VER2;
1551
1552
1553         if ((error = newnfs_connect(nmp, &nmp->nm_sockreq, cred, td, 0, false)))
1554                 goto bad;
1555         /* For NFSv4.1, get the clientid now. */
1556         if (nmp->nm_minorvers > 0) {
1557                 NFSCL_DEBUG(3, "at getcl\n");
1558                 error = nfscl_getcl(mp, cred, td, 0, &clp);
1559                 NFSCL_DEBUG(3, "aft getcl=%d\n", error);
1560                 if (error != 0)
1561                         goto bad;
1562         }
1563
1564         if (nmp->nm_fhsize == 0 && (nmp->nm_flag & NFSMNT_NFSV4) &&
1565             nmp->nm_dirpathlen > 0) {
1566                 NFSCL_DEBUG(3, "in dirp\n");
1567                 /*
1568                  * If the fhsize on the mount point == 0 for V4, the mount
1569                  * path needs to be looked up.
1570                  */
1571                 trycnt = 3;
1572                 do {
1573                         error = nfsrpc_getdirpath(nmp, NFSMNT_DIRPATH(nmp),
1574                             cred, td);
1575                         NFSCL_DEBUG(3, "aft dirp=%d\n", error);
1576                         if (error)
1577                                 (void) nfs_catnap(PZERO, error, "nfsgetdirp");
1578                 } while (error && --trycnt > 0);
1579                 if (error)
1580                         goto bad;
1581         }
1582
1583         /*
1584          * A reference count is needed on the nfsnode representing the
1585          * remote root.  If this object is not persistent, then backward
1586          * traversals of the mount point (i.e. "..") will not work if
1587          * the nfsnode gets flushed out of the cache. Ufs does not have
1588          * this problem, because one can identify root inodes by their
1589          * number == UFS_ROOTINO (2).
1590          */
1591         if (nmp->nm_fhsize > 0) {
1592                 /*
1593                  * Set f_iosize to NFS_DIRBLKSIZ so that bo_bsize gets set
1594                  * non-zero for the root vnode. f_iosize will be set correctly
1595                  * by nfs_statfs() before any I/O occurs.
1596                  */
1597                 mp->mnt_stat.f_iosize = NFS_DIRBLKSIZ;
1598                 error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np,
1599                     LK_EXCLUSIVE);
1600                 if (error)
1601                         goto bad;
1602                 *vpp = NFSTOV(np);
1603         
1604                 /*
1605                  * Get file attributes and transfer parameters for the
1606                  * mountpoint.  This has the side effect of filling in
1607                  * (*vpp)->v_type with the correct value.
1608                  */
1609                 ret = nfsrpc_getattrnovp(nmp, nmp->nm_fh, nmp->nm_fhsize, 1,
1610                     cred, td, &nfsva, NULL, &lease);
1611                 if (ret) {
1612                         /*
1613                          * Just set default values to get things going.
1614                          */
1615                         NFSBZERO((caddr_t)&nfsva, sizeof (struct nfsvattr));
1616                         nfsva.na_vattr.va_type = VDIR;
1617                         nfsva.na_vattr.va_mode = 0777;
1618                         nfsva.na_vattr.va_nlink = 100;
1619                         nfsva.na_vattr.va_uid = (uid_t)0;
1620                         nfsva.na_vattr.va_gid = (gid_t)0;
1621                         nfsva.na_vattr.va_fileid = 2;
1622                         nfsva.na_vattr.va_gen = 1;
1623                         nfsva.na_vattr.va_blocksize = NFS_FABLKSIZE;
1624                         nfsva.na_vattr.va_size = 512 * 1024;
1625                         lease = 60;
1626                 }
1627                 (void) nfscl_loadattrcache(vpp, &nfsva, NULL, NULL, 0, 1);
1628                 if (nmp->nm_minorvers > 0) {
1629                         NFSCL_DEBUG(3, "lease=%d\n", (int)lease);
1630                         NFSLOCKCLSTATE();
1631                         clp->nfsc_renew = NFSCL_RENEW(lease);
1632                         clp->nfsc_expire = NFSD_MONOSEC + clp->nfsc_renew;
1633                         clp->nfsc_clientidrev++;
1634                         if (clp->nfsc_clientidrev == 0)
1635                                 clp->nfsc_clientidrev++;
1636                         NFSUNLOCKCLSTATE();
1637                         /*
1638                          * Mount will succeed, so the renew thread can be
1639                          * started now.
1640                          */
1641                         nfscl_start_renewthread(clp);
1642                         nfscl_clientrelease(clp);
1643                 }
1644                 if (argp->flags & NFSMNT_NFSV3)
1645                         ncl_fsinfo(nmp, *vpp, cred, td);
1646         
1647                 /* Mark if the mount point supports NFSv4 ACLs. */
1648                 if ((argp->flags & NFSMNT_NFSV4) != 0 && nfsrv_useacl != 0 &&
1649                     ret == 0 &&
1650                     NFSISSET_ATTRBIT(&nfsva.na_suppattr, NFSATTRBIT_ACL)) {
1651                         MNT_ILOCK(mp);
1652                         mp->mnt_flag |= MNT_NFS4ACLS;
1653                         MNT_IUNLOCK(mp);
1654                 }
1655         
1656                 /*
1657                  * Lose the lock but keep the ref.
1658                  */
1659                 NFSVOPUNLOCK(*vpp);
1660                 vfs_cache_root_set(mp, *vpp);
1661                 return (0);
1662         }
1663         error = EIO;
1664
1665 bad:
1666         if (clp != NULL)
1667                 nfscl_clientrelease(clp);
1668         newnfs_disconnect(&nmp->nm_sockreq);
1669         crfree(nmp->nm_sockreq.nr_cred);
1670         if (nmp->nm_sockreq.nr_auth != NULL)
1671                 AUTH_DESTROY(nmp->nm_sockreq.nr_auth);
1672         mtx_destroy(&nmp->nm_sockreq.nr_mtx);
1673         mtx_destroy(&nmp->nm_mtx);
1674         if (nmp->nm_clp != NULL) {
1675                 NFSLOCKCLSTATE();
1676                 LIST_REMOVE(nmp->nm_clp, nfsc_list);
1677                 NFSUNLOCKCLSTATE();
1678                 free(nmp->nm_clp, M_NFSCLCLIENT);
1679         }
1680         TAILQ_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp) {
1681                 if (dsp != TAILQ_FIRST(&nmp->nm_sess) &&
1682                     dsp->nfsclds_sockp != NULL)
1683                         newnfs_disconnect(dsp->nfsclds_sockp);
1684                 nfscl_freenfsclds(dsp);
1685         }
1686         free(nmp, M_NEWNFSMNT);
1687         free(nam, M_SONAME);
1688         return (error);
1689 }
1690
1691 /*
1692  * unmount system call
1693  */
1694 static int
1695 nfs_unmount(struct mount *mp, int mntflags)
1696 {
1697         struct thread *td;
1698         struct nfsmount *nmp;
1699         int error, flags = 0, i, trycnt = 0;
1700         struct nfsclds *dsp, *tdsp;
1701
1702         td = curthread;
1703
1704         if (mntflags & MNT_FORCE)
1705                 flags |= FORCECLOSE;
1706         nmp = VFSTONFS(mp);
1707         error = 0;
1708         /*
1709          * Goes something like this..
1710          * - Call vflush() to clear out vnodes for this filesystem
1711          * - Close the socket
1712          * - Free up the data structures
1713          */
1714         /* In the forced case, cancel any outstanding requests. */
1715         if (mntflags & MNT_FORCE) {
1716                 NFSDDSLOCK();
1717                 if (nfsv4_findmirror(nmp) != NULL)
1718                         error = ENXIO;
1719                 NFSDDSUNLOCK();
1720                 if (error)
1721                         goto out;
1722                 error = newnfs_nmcancelreqs(nmp);
1723                 if (error)
1724                         goto out;
1725                 /* For a forced close, get rid of the renew thread now */
1726                 nfscl_umount(nmp, td);
1727         }
1728         /* We hold 1 extra ref on the root vnode; see comment in mountnfs(). */
1729         do {
1730                 error = vflush(mp, 1, flags, td);
1731                 if ((mntflags & MNT_FORCE) && error != 0 && ++trycnt < 30)
1732                         (void) nfs_catnap(PSOCK, error, "newndm");
1733         } while ((mntflags & MNT_FORCE) && error != 0 && trycnt < 30);
1734         if (error)
1735                 goto out;
1736
1737         /*
1738          * We are now committed to the unmount.
1739          */
1740         if ((mntflags & MNT_FORCE) == 0)
1741                 nfscl_umount(nmp, td);
1742         else {
1743                 mtx_lock(&nmp->nm_mtx);
1744                 nmp->nm_privflag |= NFSMNTP_FORCEDISM;
1745                 mtx_unlock(&nmp->nm_mtx);
1746         }
1747         /* Make sure no nfsiods are assigned to this mount. */
1748         NFSLOCKIOD();
1749         for (i = 0; i < NFS_MAXASYNCDAEMON; i++)
1750                 if (ncl_iodmount[i] == nmp) {
1751                         ncl_iodwant[i] = NFSIOD_AVAILABLE;
1752                         ncl_iodmount[i] = NULL;
1753                 }
1754         NFSUNLOCKIOD();
1755
1756         /*
1757          * We can now set mnt_data to NULL and wait for
1758          * nfssvc(NFSSVC_FORCEDISM) to complete.
1759          */
1760         mtx_lock(&mountlist_mtx);
1761         mtx_lock(&nmp->nm_mtx);
1762         mp->mnt_data = NULL;
1763         mtx_unlock(&mountlist_mtx);
1764         while ((nmp->nm_privflag & NFSMNTP_CANCELRPCS) != 0)
1765                 msleep(nmp, &nmp->nm_mtx, PVFS, "nfsfdism", 0);
1766         mtx_unlock(&nmp->nm_mtx);
1767
1768         newnfs_disconnect(&nmp->nm_sockreq);
1769         crfree(nmp->nm_sockreq.nr_cred);
1770         free(nmp->nm_nam, M_SONAME);
1771         if (nmp->nm_sockreq.nr_auth != NULL)
1772                 AUTH_DESTROY(nmp->nm_sockreq.nr_auth);
1773         mtx_destroy(&nmp->nm_sockreq.nr_mtx);
1774         mtx_destroy(&nmp->nm_mtx);
1775         TAILQ_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp) {
1776                 if (dsp != TAILQ_FIRST(&nmp->nm_sess) &&
1777                     dsp->nfsclds_sockp != NULL)
1778                         newnfs_disconnect(dsp->nfsclds_sockp);
1779                 nfscl_freenfsclds(dsp);
1780         }
1781         free(nmp, M_NEWNFSMNT);
1782 out:
1783         return (error);
1784 }
1785
1786 /*
1787  * Return root of a filesystem
1788  */
1789 static int
1790 nfs_root(struct mount *mp, int flags, struct vnode **vpp)
1791 {
1792         struct vnode *vp;
1793         struct nfsmount *nmp;
1794         struct nfsnode *np;
1795         int error;
1796
1797         nmp = VFSTONFS(mp);
1798         error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np, flags);
1799         if (error)
1800                 return error;
1801         vp = NFSTOV(np);
1802         /*
1803          * Get transfer parameters and attributes for root vnode once.
1804          */
1805         mtx_lock(&nmp->nm_mtx);
1806         if (NFSHASNFSV3(nmp) && !NFSHASGOTFSINFO(nmp)) {
1807                 mtx_unlock(&nmp->nm_mtx);
1808                 ncl_fsinfo(nmp, vp, curthread->td_ucred, curthread);
1809         } else 
1810                 mtx_unlock(&nmp->nm_mtx);
1811         if (vp->v_type == VNON)
1812             vp->v_type = VDIR;
1813         vp->v_vflag |= VV_ROOT;
1814         *vpp = vp;
1815         return (0);
1816 }
1817
1818 /*
1819  * Flush out the buffer cache
1820  */
1821 /* ARGSUSED */
1822 static int
1823 nfs_sync(struct mount *mp, int waitfor)
1824 {
1825         struct vnode *vp, *mvp;
1826         struct thread *td;
1827         int error, allerror = 0;
1828
1829         td = curthread;
1830
1831         MNT_ILOCK(mp);
1832         /*
1833          * If a forced dismount is in progress, return from here so that
1834          * the umount(2) syscall doesn't get stuck in VFS_SYNC() before
1835          * calling VFS_UNMOUNT().
1836          */
1837         if (NFSCL_FORCEDISM(mp)) {
1838                 MNT_IUNLOCK(mp);
1839                 return (EBADF);
1840         }
1841         MNT_IUNLOCK(mp);
1842
1843         /*
1844          * Force stale buffer cache information to be flushed.
1845          */
1846 loop:
1847         MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
1848                 /* XXX Racy bv_cnt check. */
1849                 if (NFSVOPISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
1850                     waitfor == MNT_LAZY) {
1851                         VI_UNLOCK(vp);
1852                         continue;
1853                 }
1854                 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK)) {
1855                         MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
1856                         goto loop;
1857                 }
1858                 error = VOP_FSYNC(vp, waitfor, td);
1859                 if (error)
1860                         allerror = error;
1861                 NFSVOPUNLOCK(vp);
1862                 vrele(vp);
1863         }
1864         return (allerror);
1865 }
1866
1867 static int
1868 nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req)
1869 {
1870         struct nfsmount *nmp = VFSTONFS(mp);
1871         struct vfsquery vq;
1872         int error;
1873
1874         bzero(&vq, sizeof(vq));
1875         switch (op) {
1876 #if 0
1877         case VFS_CTL_NOLOCKS:
1878                 val = (nmp->nm_flag & NFSMNT_NOLOCKS) ? 1 : 0;
1879                 if (req->oldptr != NULL) {
1880                         error = SYSCTL_OUT(req, &val, sizeof(val));
1881                         if (error)
1882                                 return (error);
1883                 }
1884                 if (req->newptr != NULL) {
1885                         error = SYSCTL_IN(req, &val, sizeof(val));
1886                         if (error)
1887                                 return (error);
1888                         if (val)
1889                                 nmp->nm_flag |= NFSMNT_NOLOCKS;
1890                         else
1891                                 nmp->nm_flag &= ~NFSMNT_NOLOCKS;
1892                 }
1893                 break;
1894 #endif
1895         case VFS_CTL_QUERY:
1896                 mtx_lock(&nmp->nm_mtx);
1897                 if (nmp->nm_state & NFSSTA_TIMEO)
1898                         vq.vq_flags |= VQ_NOTRESP;
1899                 mtx_unlock(&nmp->nm_mtx);
1900 #if 0
1901                 if (!(nmp->nm_flag & NFSMNT_NOLOCKS) &&
1902                     (nmp->nm_state & NFSSTA_LOCKTIMEO))
1903                         vq.vq_flags |= VQ_NOTRESPLOCK;
1904 #endif
1905                 error = SYSCTL_OUT(req, &vq, sizeof(vq));
1906                 break;
1907         case VFS_CTL_TIMEO:
1908                 if (req->oldptr != NULL) {
1909                         error = SYSCTL_OUT(req, &nmp->nm_tprintf_initial_delay,
1910                             sizeof(nmp->nm_tprintf_initial_delay));
1911                         if (error)
1912                                 return (error);
1913                 }
1914                 if (req->newptr != NULL) {
1915                         error = vfs_suser(mp, req->td);
1916                         if (error)
1917                                 return (error);
1918                         error = SYSCTL_IN(req, &nmp->nm_tprintf_initial_delay,
1919                             sizeof(nmp->nm_tprintf_initial_delay));
1920                         if (error)
1921                                 return (error);
1922                         if (nmp->nm_tprintf_initial_delay < 0)
1923                                 nmp->nm_tprintf_initial_delay = 0;
1924                 }
1925                 break;
1926         default:
1927                 return (ENOTSUP);
1928         }
1929         return (0);
1930 }
1931
1932 /*
1933  * Purge any RPCs in progress, so that they will all return errors.
1934  * This allows dounmount() to continue as far as VFS_UNMOUNT() for a
1935  * forced dismount.
1936  */
1937 static void
1938 nfs_purge(struct mount *mp)
1939 {
1940         struct nfsmount *nmp = VFSTONFS(mp);
1941
1942         newnfs_nmcancelreqs(nmp);
1943 }
1944
1945 /*
1946  * Extract the information needed by the nlm from the nfs vnode.
1947  */
1948 static void
1949 nfs_getnlminfo(struct vnode *vp, uint8_t *fhp, size_t *fhlenp,
1950     struct sockaddr_storage *sp, int *is_v3p, off_t *sizep,
1951     struct timeval *timeop)
1952 {
1953         struct nfsmount *nmp;
1954         struct nfsnode *np = VTONFS(vp);
1955
1956         nmp = VFSTONFS(vp->v_mount);
1957         if (fhlenp != NULL)
1958                 *fhlenp = (size_t)np->n_fhp->nfh_len;
1959         if (fhp != NULL)
1960                 bcopy(np->n_fhp->nfh_fh, fhp, np->n_fhp->nfh_len);
1961         if (sp != NULL)
1962                 bcopy(nmp->nm_nam, sp, min(nmp->nm_nam->sa_len, sizeof(*sp)));
1963         if (is_v3p != NULL)
1964                 *is_v3p = NFS_ISV3(vp);
1965         if (sizep != NULL)
1966                 *sizep = np->n_size;
1967         if (timeop != NULL) {
1968                 timeop->tv_sec = nmp->nm_timeo / NFS_HZ;
1969                 timeop->tv_usec = (nmp->nm_timeo % NFS_HZ) * (1000000 / NFS_HZ);
1970         }
1971 }
1972
1973 /*
1974  * This function prints out an option name, based on the conditional
1975  * argument.
1976  */
1977 static __inline void nfscl_printopt(struct nfsmount *nmp, int testval,
1978     char *opt, char **buf, size_t *blen)
1979 {
1980         int len;
1981
1982         if (testval != 0 && *blen > strlen(opt)) {
1983                 len = snprintf(*buf, *blen, "%s", opt);
1984                 if (len != strlen(opt))
1985                         printf("EEK!!\n");
1986                 *buf += len;
1987                 *blen -= len;
1988         }
1989 }
1990
1991 /*
1992  * This function printf out an options integer value.
1993  */
1994 static __inline void nfscl_printoptval(struct nfsmount *nmp, int optval,
1995     char *opt, char **buf, size_t *blen)
1996 {
1997         int len;
1998
1999         if (*blen > strlen(opt) + 1) {
2000                 /* Could result in truncated output string. */
2001                 len = snprintf(*buf, *blen, "%s=%d", opt, optval);
2002                 if (len < *blen) {
2003                         *buf += len;
2004                         *blen -= len;
2005                 }
2006         }
2007 }
2008
2009 /*
2010  * Load the option flags and values into the buffer.
2011  */
2012 void nfscl_retopts(struct nfsmount *nmp, char *buffer, size_t buflen)
2013 {
2014         char *buf;
2015         size_t blen;
2016
2017         buf = buffer;
2018         blen = buflen;
2019         nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NFSV4) != 0, "nfsv4", &buf,
2020             &blen);
2021         if ((nmp->nm_flag & NFSMNT_NFSV4) != 0) {
2022                 nfscl_printoptval(nmp, nmp->nm_minorvers, ",minorversion", &buf,
2023                     &blen);
2024                 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_PNFS) != 0, ",pnfs",
2025                     &buf, &blen);
2026                 nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_ONEOPENOWN) != 0 &&
2027                     nmp->nm_minorvers > 0, ",oneopenown", &buf, &blen);
2028         }
2029         nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NFSV3) != 0, "nfsv3", &buf,
2030             &blen);
2031         nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0,
2032             "nfsv2", &buf, &blen);
2033         nfscl_printopt(nmp, nmp->nm_sotype == SOCK_STREAM, ",tcp", &buf, &blen);
2034         nfscl_printopt(nmp, nmp->nm_sotype != SOCK_STREAM, ",udp", &buf, &blen);
2035         nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_RESVPORT) != 0, ",resvport",
2036             &buf, &blen);
2037         nfscl_printopt(nmp, (nmp->nm_newflag & NFSMNT_TLS) != 0, ",tls", &buf,
2038             &blen);
2039         nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCONN) != 0, ",noconn",
2040             &buf, &blen);
2041         nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) == 0, ",hard", &buf,
2042             &blen);
2043         nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) != 0, ",soft", &buf,
2044             &blen);
2045         nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_INT) != 0, ",intr", &buf,
2046             &blen);
2047         nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCTO) == 0, ",cto", &buf,
2048             &blen);
2049         nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCTO) != 0, ",nocto", &buf,
2050             &blen);
2051         nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NONCONTIGWR) != 0,
2052             ",noncontigwr", &buf, &blen);
2053         nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NOLOCKD | NFSMNT_NFSV4)) ==
2054             0, ",lockd", &buf, &blen);
2055         nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NOLOCKD | NFSMNT_NFSV4)) ==
2056             NFSMNT_NOLOCKD, ",nolockd", &buf, &blen);
2057         nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_RDIRPLUS) != 0, ",rdirplus",
2058             &buf, &blen);
2059         nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_KERB) == 0, ",sec=sys",
2060             &buf, &blen);
2061         nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
2062             NFSMNT_PRIVACY)) == NFSMNT_KERB, ",sec=krb5", &buf, &blen);
2063         nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
2064             NFSMNT_PRIVACY)) == (NFSMNT_KERB | NFSMNT_INTEGRITY), ",sec=krb5i",
2065             &buf, &blen);
2066         nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
2067             NFSMNT_PRIVACY)) == (NFSMNT_KERB | NFSMNT_PRIVACY), ",sec=krb5p",
2068             &buf, &blen);
2069         nfscl_printoptval(nmp, nmp->nm_acdirmin, ",acdirmin", &buf, &blen);
2070         nfscl_printoptval(nmp, nmp->nm_acdirmax, ",acdirmax", &buf, &blen);
2071         nfscl_printoptval(nmp, nmp->nm_acregmin, ",acregmin", &buf, &blen);
2072         nfscl_printoptval(nmp, nmp->nm_acregmax, ",acregmax", &buf, &blen);
2073         nfscl_printoptval(nmp, nmp->nm_nametimeo, ",nametimeo", &buf, &blen);
2074         nfscl_printoptval(nmp, nmp->nm_negnametimeo, ",negnametimeo", &buf,
2075             &blen);
2076         nfscl_printoptval(nmp, nmp->nm_rsize, ",rsize", &buf, &blen);
2077         nfscl_printoptval(nmp, nmp->nm_wsize, ",wsize", &buf, &blen);
2078         nfscl_printoptval(nmp, nmp->nm_readdirsize, ",readdirsize", &buf,
2079             &blen);
2080         nfscl_printoptval(nmp, nmp->nm_readahead, ",readahead", &buf, &blen);
2081         nfscl_printoptval(nmp, nmp->nm_wcommitsize, ",wcommitsize", &buf,
2082             &blen);
2083         nfscl_printoptval(nmp, nmp->nm_timeo, ",timeout", &buf, &blen);
2084         nfscl_printoptval(nmp, nmp->nm_retry, ",retrans", &buf, &blen);
2085 }
2086