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