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