]> CyberLeo.Net >> Repos - FreeBSD/stable/8.git/blob - sys/nfsclient/nfs_vfsops.c
Copy head to stable/8 as part of 8.0 Release cycle.
[FreeBSD/stable/8.git] / sys / nfsclient / nfs_vfsops.c
1 /*-
2  * Copyright (c) 1989, 1993, 1995
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Rick Macklem at The University of Guelph.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 4. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  *      @(#)nfs_vfsops.c        8.12 (Berkeley) 5/20/95
33  */
34
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
37
38
39 #include "opt_bootp.h"
40 #include "opt_nfsroot.h"
41
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
45 #include <sys/bio.h>
46 #include <sys/buf.h>
47 #include <sys/jail.h>
48 #include <sys/lock.h>
49 #include <sys/malloc.h>
50 #include <sys/mbuf.h>
51 #include <sys/module.h>
52 #include <sys/mount.h>
53 #include <sys/proc.h>
54 #include <sys/socket.h>
55 #include <sys/socketvar.h>
56 #include <sys/sockio.h>
57 #include <sys/sysctl.h>
58 #include <sys/vnode.h>
59 #include <sys/signalvar.h>
60
61 #include <vm/vm.h>
62 #include <vm/vm_extern.h>
63 #include <vm/uma.h>
64
65 #include <net/if.h>
66 #include <net/route.h>
67 #include <netinet/in.h>
68
69 #include <rpc/rpc.h>
70
71 #include <nfs/nfsproto.h>
72 #include <nfsclient/nfs.h>
73 #include <nfsclient/nfsnode.h>
74 #include <nfsclient/nfsmount.h>
75 #include <nfs/xdr_subs.h>
76 #include <nfsclient/nfsm_subs.h>
77 #include <nfsclient/nfsdiskless.h>
78
79 MALLOC_DEFINE(M_NFSREQ, "nfsclient_req", "NFS request header");
80 MALLOC_DEFINE(M_NFSBIGFH, "nfsclient_bigfh", "NFS version 3 file handle");
81 MALLOC_DEFINE(M_NFSDIROFF, "nfsclient_diroff", "NFS directory offset data");
82 MALLOC_DEFINE(M_NFSHASH, "nfsclient_hash", "NFS hash tables");
83 MALLOC_DEFINE(M_NFSDIRECTIO, "nfsclient_directio", "NFS Direct IO async write state");
84
85 uma_zone_t nfsmount_zone;
86
87 struct nfsstats nfsstats;
88
89 SYSCTL_NODE(_vfs, OID_AUTO, nfs, CTLFLAG_RW, 0, "NFS filesystem");
90 SYSCTL_STRUCT(_vfs_nfs, NFS_NFSSTATS, nfsstats, CTLFLAG_RW,
91         &nfsstats, nfsstats, "S,nfsstats");
92 static int nfs_ip_paranoia = 1;
93 SYSCTL_INT(_vfs_nfs, OID_AUTO, nfs_ip_paranoia, CTLFLAG_RW,
94     &nfs_ip_paranoia, 0,
95     "Disallow accepting replies from IPs which differ from those sent");
96 #ifdef NFS_DEBUG
97 int nfs_debug;
98 SYSCTL_INT(_vfs_nfs, OID_AUTO, debug, CTLFLAG_RW, &nfs_debug, 0,
99     "Toggle debug flag");
100 #endif
101 static int nfs_tprintf_initial_delay = NFS_TPRINTF_INITIAL_DELAY;
102 SYSCTL_INT(_vfs_nfs, NFS_TPRINTF_INITIAL_DELAY,
103     downdelayinitial, CTLFLAG_RW, &nfs_tprintf_initial_delay, 0,
104     "Delay before printing \"nfs server not responding\" messages");
105 /* how long between console messages "nfs server foo not responding" */
106 static int nfs_tprintf_delay = NFS_TPRINTF_DELAY;
107 SYSCTL_INT(_vfs_nfs, NFS_TPRINTF_DELAY,
108     downdelayinterval, CTLFLAG_RW, &nfs_tprintf_delay, 0,
109     "Delay between printing \"nfs server not responding\" messages");
110
111 static void     nfs_decode_args(struct mount *mp, struct nfsmount *nmp,
112                     struct nfs_args *argp, const char *hostname);
113 static int      mountnfs(struct nfs_args *, struct mount *,
114                     struct sockaddr *, char *, struct vnode **,
115                     struct ucred *cred);
116 static vfs_mount_t nfs_mount;
117 static vfs_cmount_t nfs_cmount;
118 static vfs_unmount_t nfs_unmount;
119 static vfs_root_t nfs_root;
120 static vfs_statfs_t nfs_statfs;
121 static vfs_sync_t nfs_sync;
122 static vfs_sysctl_t nfs_sysctl;
123
124 static int      fake_wchan;
125
126 /*
127  * nfs vfs operations.
128  */
129 static struct vfsops nfs_vfsops = {
130         .vfs_init =             nfs_init,
131         .vfs_mount =            nfs_mount,
132         .vfs_cmount =           nfs_cmount,
133         .vfs_root =             nfs_root,
134         .vfs_statfs =           nfs_statfs,
135         .vfs_sync =             nfs_sync,
136         .vfs_uninit =           nfs_uninit,
137         .vfs_unmount =          nfs_unmount,
138         .vfs_sysctl =           nfs_sysctl,
139 };
140 VFS_SET(nfs_vfsops, nfs, VFCF_NETWORK);
141
142 /* So that loader and kldload(2) can find us, wherever we are.. */
143 MODULE_VERSION(nfs, 1);
144 MODULE_DEPEND(nfs, krpc, 1, 1, 1);
145 #ifdef KGSSAPI
146 MODULE_DEPEND(nfs, kgssapi, 1, 1, 1);
147 #endif
148
149 static struct nfs_rpcops nfs_rpcops = {
150         nfs_readrpc,
151         nfs_writerpc,
152         nfs_writebp,
153         nfs_readlinkrpc,
154         nfs_invaldir,
155         nfs_commit,
156 };
157
158 /*
159  * This structure must be filled in by a primary bootstrap or bootstrap
160  * server for a diskless/dataless machine. It is initialized below just
161  * to ensure that it is allocated to initialized data (.data not .bss).
162  */
163 struct nfs_diskless nfs_diskless = { { { 0 } } };
164 struct nfsv3_diskless nfsv3_diskless = { { { 0 } } };
165 int nfs_diskless_valid = 0;
166
167 SYSCTL_INT(_vfs_nfs, OID_AUTO, diskless_valid, CTLFLAG_RD,
168     &nfs_diskless_valid, 0,
169     "Has the diskless struct been filled correctly");
170
171 SYSCTL_STRING(_vfs_nfs, OID_AUTO, diskless_rootpath, CTLFLAG_RD,
172     nfsv3_diskless.root_hostnam, 0, "Path to nfs root");
173
174 SYSCTL_OPAQUE(_vfs_nfs, OID_AUTO, diskless_rootaddr, CTLFLAG_RD,
175     &nfsv3_diskless.root_saddr, sizeof nfsv3_diskless.root_saddr,
176     "%Ssockaddr_in", "Diskless root nfs address");
177
178
179 void            nfsargs_ntoh(struct nfs_args *);
180 static int      nfs_mountdiskless(char *,
181                     struct sockaddr_in *, struct nfs_args *,
182                     struct thread *, struct vnode **, struct mount *);
183 static void     nfs_convert_diskless(void);
184 static void     nfs_convert_oargs(struct nfs_args *args,
185                     struct onfs_args *oargs);
186
187 int
188 nfs_iosize(struct nfsmount *nmp)
189 {
190         int iosize;
191
192         /*
193          * Calculate the size used for io buffers.  Use the larger
194          * of the two sizes to minimise nfs requests but make sure
195          * that it is at least one VM page to avoid wasting buffer
196          * space.
197          */
198         iosize = imax(nmp->nm_rsize, nmp->nm_wsize);
199         iosize = imax(iosize, PAGE_SIZE);
200         return (iosize);
201 }
202
203 static void
204 nfs_convert_oargs(struct nfs_args *args, struct onfs_args *oargs)
205 {
206
207         args->version = NFS_ARGSVERSION;
208         args->addr = oargs->addr;
209         args->addrlen = oargs->addrlen;
210         args->sotype = oargs->sotype;
211         args->proto = oargs->proto;
212         args->fh = oargs->fh;
213         args->fhsize = oargs->fhsize;
214         args->flags = oargs->flags;
215         args->wsize = oargs->wsize;
216         args->rsize = oargs->rsize;
217         args->readdirsize = oargs->readdirsize;
218         args->timeo = oargs->timeo;
219         args->retrans = oargs->retrans;
220         args->maxgrouplist = oargs->maxgrouplist;
221         args->readahead = oargs->readahead;
222         args->deadthresh = oargs->deadthresh;
223         args->hostname = oargs->hostname;
224 }
225
226 static void
227 nfs_convert_diskless(void)
228 {
229
230         bcopy(&nfs_diskless.myif, &nfsv3_diskless.myif,
231                 sizeof(struct ifaliasreq));
232         bcopy(&nfs_diskless.mygateway, &nfsv3_diskless.mygateway,
233                 sizeof(struct sockaddr_in));
234         nfs_convert_oargs(&nfsv3_diskless.root_args,&nfs_diskless.root_args);
235         if (nfsv3_diskless.root_args.flags & NFSMNT_NFSV3) {
236                 nfsv3_diskless.root_fhsize = NFSX_V3FH;
237                 bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V3FH);
238         } else {
239                 nfsv3_diskless.root_fhsize = NFSX_V2FH;
240                 bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V2FH);
241         }
242         bcopy(&nfs_diskless.root_saddr,&nfsv3_diskless.root_saddr,
243                 sizeof(struct sockaddr_in));
244         bcopy(nfs_diskless.root_hostnam, nfsv3_diskless.root_hostnam, MNAMELEN);
245         nfsv3_diskless.root_time = nfs_diskless.root_time;
246         bcopy(nfs_diskless.my_hostnam, nfsv3_diskless.my_hostnam,
247                 MAXHOSTNAMELEN);
248         nfs_diskless_valid = 3;
249 }
250
251 /*
252  * nfs statfs call
253  */
254 static int
255 nfs_statfs(struct mount *mp, struct statfs *sbp)
256 {
257         struct vnode *vp;
258         struct thread *td;
259         struct nfs_statfs *sfp;
260         caddr_t bpos, dpos;
261         struct nfsmount *nmp = VFSTONFS(mp);
262         int error = 0, v3 = (nmp->nm_flag & NFSMNT_NFSV3), retattr;
263         struct mbuf *mreq, *mrep, *md, *mb;
264         struct nfsnode *np;
265         u_quad_t tquad;
266
267         td = curthread;
268 #ifndef nolint
269         sfp = NULL;
270 #endif
271         error = vfs_busy(mp, MBF_NOWAIT);
272         if (error)
273                 return (error);
274         error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
275         if (error) {
276                 vfs_unbusy(mp);
277                 return (error);
278         }
279         vp = NFSTOV(np);
280         mtx_lock(&nmp->nm_mtx);
281         if (v3 && (nmp->nm_state & NFSSTA_GOTFSINFO) == 0) {
282                 mtx_unlock(&nmp->nm_mtx);               
283                 (void)nfs_fsinfo(nmp, vp, td->td_ucred, td);
284         } else
285                 mtx_unlock(&nmp->nm_mtx);
286         nfsstats.rpccnt[NFSPROC_FSSTAT]++;
287         mreq = nfsm_reqhead(vp, NFSPROC_FSSTAT, NFSX_FH(v3));
288         mb = mreq;
289         bpos = mtod(mb, caddr_t);
290         nfsm_fhtom(vp, v3);
291         nfsm_request(vp, NFSPROC_FSSTAT, td, td->td_ucred);
292         if (v3)
293                 nfsm_postop_attr(vp, retattr);
294         if (error) {
295                 if (mrep != NULL)
296                         m_freem(mrep);
297                 goto nfsmout;
298         }
299         sfp = nfsm_dissect(struct nfs_statfs *, NFSX_STATFS(v3));
300         mtx_lock(&nmp->nm_mtx);
301         sbp->f_iosize = nfs_iosize(nmp);
302         mtx_unlock(&nmp->nm_mtx);
303         if (v3) {
304                 sbp->f_bsize = NFS_FABLKSIZE;
305                 tquad = fxdr_hyper(&sfp->sf_tbytes);
306                 sbp->f_blocks = tquad / NFS_FABLKSIZE;
307                 tquad = fxdr_hyper(&sfp->sf_fbytes);
308                 sbp->f_bfree = tquad / NFS_FABLKSIZE;
309                 tquad = fxdr_hyper(&sfp->sf_abytes);
310                 sbp->f_bavail = tquad / NFS_FABLKSIZE;
311                 sbp->f_files = (fxdr_unsigned(int32_t,
312                     sfp->sf_tfiles.nfsuquad[1]) & 0x7fffffff);
313                 sbp->f_ffree = (fxdr_unsigned(int32_t,
314                     sfp->sf_ffiles.nfsuquad[1]) & 0x7fffffff);
315         } else {
316                 sbp->f_bsize = fxdr_unsigned(int32_t, sfp->sf_bsize);
317                 sbp->f_blocks = fxdr_unsigned(int32_t, sfp->sf_blocks);
318                 sbp->f_bfree = fxdr_unsigned(int32_t, sfp->sf_bfree);
319                 sbp->f_bavail = fxdr_unsigned(int32_t, sfp->sf_bavail);
320                 sbp->f_files = 0;
321                 sbp->f_ffree = 0;
322         }
323         m_freem(mrep);
324 nfsmout:
325         vput(vp);
326         vfs_unbusy(mp);
327         return (error);
328 }
329
330 /*
331  * nfs version 3 fsinfo rpc call
332  */
333 int
334 nfs_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct ucred *cred,
335     struct thread *td)
336 {
337         struct nfsv3_fsinfo *fsp;
338         u_int32_t pref, max;
339         caddr_t bpos, dpos;
340         int error = 0, retattr;
341         struct mbuf *mreq, *mrep, *md, *mb;
342         u_int64_t maxfsize;
343         
344         nfsstats.rpccnt[NFSPROC_FSINFO]++;
345         mreq = nfsm_reqhead(vp, NFSPROC_FSINFO, NFSX_FH(1));
346         mb = mreq;
347         bpos = mtod(mb, caddr_t);
348         nfsm_fhtom(vp, 1);
349         nfsm_request(vp, NFSPROC_FSINFO, td, cred);
350         nfsm_postop_attr(vp, retattr);
351         if (!error) {
352                 fsp = nfsm_dissect(struct nfsv3_fsinfo *, NFSX_V3FSINFO);
353                 pref = fxdr_unsigned(u_int32_t, fsp->fs_wtpref);
354                 mtx_lock(&nmp->nm_mtx);
355                 if (pref < nmp->nm_wsize && pref >= NFS_FABLKSIZE)
356                         nmp->nm_wsize = (pref + NFS_FABLKSIZE - 1) &
357                                 ~(NFS_FABLKSIZE - 1);
358                 max = fxdr_unsigned(u_int32_t, fsp->fs_wtmax);
359                 if (max < nmp->nm_wsize && max > 0) {
360                         nmp->nm_wsize = max & ~(NFS_FABLKSIZE - 1);
361                         if (nmp->nm_wsize == 0)
362                                 nmp->nm_wsize = max;
363                 }
364                 pref = fxdr_unsigned(u_int32_t, fsp->fs_rtpref);
365                 if (pref < nmp->nm_rsize && pref >= NFS_FABLKSIZE)
366                         nmp->nm_rsize = (pref + NFS_FABLKSIZE - 1) &
367                                 ~(NFS_FABLKSIZE - 1);
368                 max = fxdr_unsigned(u_int32_t, fsp->fs_rtmax);
369                 if (max < nmp->nm_rsize && max > 0) {
370                         nmp->nm_rsize = max & ~(NFS_FABLKSIZE - 1);
371                         if (nmp->nm_rsize == 0)
372                                 nmp->nm_rsize = max;
373                 }
374                 pref = fxdr_unsigned(u_int32_t, fsp->fs_dtpref);
375                 if (pref < nmp->nm_readdirsize && pref >= NFS_DIRBLKSIZ)
376                         nmp->nm_readdirsize = (pref + NFS_DIRBLKSIZ - 1) &
377                                 ~(NFS_DIRBLKSIZ - 1);
378                 if (max < nmp->nm_readdirsize && max > 0) {
379                         nmp->nm_readdirsize = max & ~(NFS_DIRBLKSIZ - 1);
380                         if (nmp->nm_readdirsize == 0)
381                                 nmp->nm_readdirsize = max;
382                 }
383                 maxfsize = fxdr_hyper(&fsp->fs_maxfilesize);
384                 if (maxfsize > 0 && maxfsize < nmp->nm_maxfilesize)
385                         nmp->nm_maxfilesize = maxfsize;
386                 nmp->nm_mountp->mnt_stat.f_iosize = nfs_iosize(nmp);
387                 nmp->nm_state |= NFSSTA_GOTFSINFO;
388                 mtx_unlock(&nmp->nm_mtx);
389         }
390         m_freem(mrep);
391 nfsmout:
392         return (error);
393 }
394
395 /*
396  * Mount a remote root fs via. nfs. This depends on the info in the
397  * nfs_diskless structure that has been filled in properly by some primary
398  * bootstrap.
399  * It goes something like this:
400  * - do enough of "ifconfig" by calling ifioctl() so that the system
401  *   can talk to the server
402  * - If nfs_diskless.mygateway is filled in, use that address as
403  *   a default gateway.
404  * - build the rootfs mount point and call mountnfs() to do the rest.
405  *
406  * It is assumed to be safe to read, modify, and write the nfsv3_diskless
407  * structure, as well as other global NFS client variables here, as
408  * nfs_mountroot() will be called once in the boot before any other NFS
409  * client activity occurs.
410  */
411 int
412 nfs_mountroot(struct mount *mp)
413 {
414         struct thread *td = curthread;
415         struct nfsv3_diskless *nd = &nfsv3_diskless;
416         struct socket *so;
417         struct vnode *vp;
418         struct ifreq ir;
419         int error;
420         u_long l;
421         char buf[128];
422         char *cp;
423
424 #if defined(BOOTP_NFSROOT) && defined(BOOTP)
425         bootpc_init();          /* use bootp to get nfs_diskless filled in */
426 #elif defined(NFS_ROOT)
427         nfs_setup_diskless();
428 #endif
429
430         if (nfs_diskless_valid == 0)
431                 return (-1);
432         if (nfs_diskless_valid == 1)
433                 nfs_convert_diskless();
434
435         /*
436          * XXX splnet, so networks will receive...
437          */
438         splnet();
439
440         /*
441          * Do enough of ifconfig(8) so that the critical net interface can
442          * talk to the server.
443          */
444         error = socreate(nd->myif.ifra_addr.sa_family, &so, nd->root_args.sotype, 0,
445             td->td_ucred, td);
446         if (error)
447                 panic("nfs_mountroot: socreate(%04x): %d",
448                         nd->myif.ifra_addr.sa_family, error);
449
450 #if 0 /* XXX Bad idea */
451         /*
452          * We might not have been told the right interface, so we pass
453          * over the first ten interfaces of the same kind, until we get
454          * one of them configured.
455          */
456
457         for (i = strlen(nd->myif.ifra_name) - 1;
458                 nd->myif.ifra_name[i] >= '0' &&
459                 nd->myif.ifra_name[i] <= '9';
460                 nd->myif.ifra_name[i] ++) {
461                 error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
462                 if(!error)
463                         break;
464         }
465 #endif
466         error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
467         if (error)
468                 panic("nfs_mountroot: SIOCAIFADDR: %d", error);
469         if ((cp = getenv("boot.netif.mtu")) != NULL) {
470                 ir.ifr_mtu = strtol(cp, NULL, 10);
471                 bcopy(nd->myif.ifra_name, ir.ifr_name, IFNAMSIZ);
472                 freeenv(cp);
473                 error = ifioctl(so, SIOCSIFMTU, (caddr_t)&ir, td);
474                 if (error)
475                         printf("nfs_mountroot: SIOCSIFMTU: %d", error);
476         }
477         soclose(so);
478
479         /*
480          * If the gateway field is filled in, set it as the default route.
481          * Note that pxeboot will set a default route of 0 if the route
482          * is not set by the DHCP server.  Check also for a value of 0
483          * to avoid panicking inappropriately in that situation.
484          */
485         if (nd->mygateway.sin_len != 0 &&
486             nd->mygateway.sin_addr.s_addr != 0) {
487                 struct sockaddr_in mask, sin;
488
489                 bzero((caddr_t)&mask, sizeof(mask));
490                 sin = mask;
491                 sin.sin_family = AF_INET;
492                 sin.sin_len = sizeof(sin);
493                 /* XXX MRT use table 0 for this sort of thing */
494                 error = rtrequest(RTM_ADD, (struct sockaddr *)&sin,
495                     (struct sockaddr *)&nd->mygateway,
496                     (struct sockaddr *)&mask,
497                     RTF_UP | RTF_GATEWAY, NULL);
498                 if (error)
499                         panic("nfs_mountroot: RTM_ADD: %d", error);
500         }
501
502         /*
503          * Create the rootfs mount point.
504          */
505         nd->root_args.fh = nd->root_fh;
506         nd->root_args.fhsize = nd->root_fhsize;
507         l = ntohl(nd->root_saddr.sin_addr.s_addr);
508         snprintf(buf, sizeof(buf), "%ld.%ld.%ld.%ld:%s",
509                 (l >> 24) & 0xff, (l >> 16) & 0xff,
510                 (l >>  8) & 0xff, (l >>  0) & 0xff, nd->root_hostnam);
511         printf("NFS ROOT: %s\n", buf);
512         nd->root_args.hostname = buf;
513         if ((error = nfs_mountdiskless(buf,
514             &nd->root_saddr, &nd->root_args, td, &vp, mp)) != 0) {
515                 return (error);
516         }
517
518         /*
519          * This is not really an nfs issue, but it is much easier to
520          * set hostname here and then let the "/etc/rc.xxx" files
521          * mount the right /var based upon its preset value.
522          */
523         mtx_lock(&prison0.pr_mtx);
524         strlcpy(prison0.pr_hostname, nd->my_hostnam,
525             sizeof (prison0.pr_hostname));
526         mtx_unlock(&prison0.pr_mtx);
527         inittodr(ntohl(nd->root_time));
528         return (0);
529 }
530
531 /*
532  * Internal version of mount system call for diskless setup.
533  */
534 static int
535 nfs_mountdiskless(char *path,
536     struct sockaddr_in *sin, struct nfs_args *args, struct thread *td,
537     struct vnode **vpp, struct mount *mp)
538 {
539         struct sockaddr *nam;
540         int error;
541
542         nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK);
543         if ((error = mountnfs(args, mp, nam, path, vpp,
544             td->td_ucred)) != 0) {
545                 printf("nfs_mountroot: mount %s on /: %d\n", path, error);
546                 return (error);
547         }
548         return (0);
549 }
550
551 static int
552 nfs_sec_name_to_num(char *sec)
553 {
554         if (!strcmp(sec, "krb5"))
555                 return (RPCSEC_GSS_KRB5);
556         if (!strcmp(sec, "krb5i"))
557                 return (RPCSEC_GSS_KRB5I);
558         if (!strcmp(sec, "krb5p"))
559                 return (RPCSEC_GSS_KRB5P);
560         if (!strcmp(sec, "sys"))
561                 return (AUTH_SYS);
562         /*
563          * Userland should validate the string but we will try and
564          * cope with unexpected values.
565          */
566         return (AUTH_SYS);
567 }
568
569 static void
570 nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
571         const char *hostname)
572 {
573         int s;
574         int adjsock;
575         int maxio;
576         char *p;
577         char *secname;
578         char *principal;
579
580         s = splnet();
581
582         /*
583          * Set read-only flag if requested; otherwise, clear it if this is
584          * an update.  If this is not an update, then either the read-only
585          * flag is already clear, or this is a root mount and it was set
586          * intentionally at some previous point.
587          */
588         if (vfs_getopt(mp->mnt_optnew, "ro", NULL, NULL) == 0) {
589                 MNT_ILOCK(mp);
590                 mp->mnt_flag |= MNT_RDONLY;
591                 MNT_IUNLOCK(mp);
592         } else if (mp->mnt_flag & MNT_UPDATE) {
593                 MNT_ILOCK(mp);
594                 mp->mnt_flag &= ~MNT_RDONLY;
595                 MNT_IUNLOCK(mp);
596         }
597
598         /*
599          * Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes
600          * no sense in that context.  Also, set up appropriate retransmit
601          * and soft timeout behavior.
602          */
603         if (argp->sotype == SOCK_STREAM) {
604                 nmp->nm_flag &= ~NFSMNT_NOCONN;
605                 nmp->nm_flag |= NFSMNT_DUMBTIMR;
606                 nmp->nm_timeo = NFS_MAXTIMEO;
607                 nmp->nm_retry = NFS_RETRANS_TCP;
608         }
609
610         /* Also clear RDIRPLUS if not NFSv3, it crashes some servers */
611         if ((argp->flags & NFSMNT_NFSV3) == 0)
612                 nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
613
614         /* Re-bind if rsrvd port requested and wasn't on one */
615         adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT)
616                   && (argp->flags & NFSMNT_RESVPORT);
617         /* Also re-bind if we're switching to/from a connected UDP socket */
618         adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) !=
619                     (argp->flags & NFSMNT_NOCONN));
620
621         /* Update flags atomically.  Don't change the lock bits. */
622         nmp->nm_flag = argp->flags | nmp->nm_flag;
623         splx(s);
624
625         if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) {
626                 nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10;
627                 if (nmp->nm_timeo < NFS_MINTIMEO)
628                         nmp->nm_timeo = NFS_MINTIMEO;
629                 else if (nmp->nm_timeo > NFS_MAXTIMEO)
630                         nmp->nm_timeo = NFS_MAXTIMEO;
631         }
632
633         if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) {
634                 nmp->nm_retry = argp->retrans;
635                 if (nmp->nm_retry > NFS_MAXREXMIT)
636                         nmp->nm_retry = NFS_MAXREXMIT;
637         }
638
639         if (argp->flags & NFSMNT_NFSV3) {
640                 if (argp->sotype == SOCK_DGRAM)
641                         maxio = NFS_MAXDGRAMDATA;
642                 else
643                         maxio = NFS_MAXDATA;
644         } else
645                 maxio = NFS_V2MAXDATA;
646
647         if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) {
648                 nmp->nm_wsize = argp->wsize;
649                 /* Round down to multiple of blocksize */
650                 nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1);
651                 if (nmp->nm_wsize <= 0)
652                         nmp->nm_wsize = NFS_FABLKSIZE;
653         }
654         if (nmp->nm_wsize > maxio)
655                 nmp->nm_wsize = maxio;
656         if (nmp->nm_wsize > MAXBSIZE)
657                 nmp->nm_wsize = MAXBSIZE;
658
659         if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) {
660                 nmp->nm_rsize = argp->rsize;
661                 /* Round down to multiple of blocksize */
662                 nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1);
663                 if (nmp->nm_rsize <= 0)
664                         nmp->nm_rsize = NFS_FABLKSIZE;
665         }
666         if (nmp->nm_rsize > maxio)
667                 nmp->nm_rsize = maxio;
668         if (nmp->nm_rsize > MAXBSIZE)
669                 nmp->nm_rsize = MAXBSIZE;
670
671         if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) {
672                 nmp->nm_readdirsize = argp->readdirsize;
673         }
674         if (nmp->nm_readdirsize > maxio)
675                 nmp->nm_readdirsize = maxio;
676         if (nmp->nm_readdirsize > nmp->nm_rsize)
677                 nmp->nm_readdirsize = nmp->nm_rsize;
678
679         if ((argp->flags & NFSMNT_ACREGMIN) && argp->acregmin >= 0)
680                 nmp->nm_acregmin = argp->acregmin;
681         else
682                 nmp->nm_acregmin = NFS_MINATTRTIMO;
683         if ((argp->flags & NFSMNT_ACREGMAX) && argp->acregmax >= 0)
684                 nmp->nm_acregmax = argp->acregmax;
685         else
686                 nmp->nm_acregmax = NFS_MAXATTRTIMO;
687         if ((argp->flags & NFSMNT_ACDIRMIN) && argp->acdirmin >= 0)
688                 nmp->nm_acdirmin = argp->acdirmin;
689         else
690                 nmp->nm_acdirmin = NFS_MINDIRATTRTIMO;
691         if ((argp->flags & NFSMNT_ACDIRMAX) && argp->acdirmax >= 0)
692                 nmp->nm_acdirmax = argp->acdirmax;
693         else
694                 nmp->nm_acdirmax = NFS_MAXDIRATTRTIMO;
695         if (nmp->nm_acdirmin > nmp->nm_acdirmax)
696                 nmp->nm_acdirmin = nmp->nm_acdirmax;
697         if (nmp->nm_acregmin > nmp->nm_acregmax)
698                 nmp->nm_acregmin = nmp->nm_acregmax;
699
700         if ((argp->flags & NFSMNT_MAXGRPS) && argp->maxgrouplist >= 0) {
701                 if (argp->maxgrouplist <= NFS_MAXGRPS)
702                         nmp->nm_numgrps = argp->maxgrouplist;
703                 else
704                         nmp->nm_numgrps = NFS_MAXGRPS;
705         }
706         if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0) {
707                 if (argp->readahead <= NFS_MAXRAHEAD)
708                         nmp->nm_readahead = argp->readahead;
709                 else
710                         nmp->nm_readahead = NFS_MAXRAHEAD;
711         }
712         if ((argp->flags & NFSMNT_WCOMMITSIZE) && argp->wcommitsize >= 0) {
713                 if (argp->wcommitsize < nmp->nm_wsize)
714                         nmp->nm_wcommitsize = nmp->nm_wsize;
715                 else
716                         nmp->nm_wcommitsize = argp->wcommitsize;
717         }
718         if ((argp->flags & NFSMNT_DEADTHRESH) && argp->deadthresh >= 0) {
719                 if (argp->deadthresh <= NFS_MAXDEADTHRESH)
720                         nmp->nm_deadthresh = argp->deadthresh;
721                 else
722                         nmp->nm_deadthresh = NFS_MAXDEADTHRESH;
723         }
724
725         adjsock |= ((nmp->nm_sotype != argp->sotype) ||
726                     (nmp->nm_soproto != argp->proto));
727         nmp->nm_sotype = argp->sotype;
728         nmp->nm_soproto = argp->proto;
729
730         if (nmp->nm_client && adjsock) {
731                 nfs_safedisconnect(nmp);
732                 if (nmp->nm_sotype == SOCK_DGRAM)
733                         while (nfs_connect(nmp)) {
734                                 printf("nfs_args: retrying connect\n");
735                                 (void) tsleep(&fake_wchan, PSOCK, "nfscon", hz);
736                         }
737         }
738
739         if (hostname) {
740                 strlcpy(nmp->nm_hostname, hostname,
741                     sizeof(nmp->nm_hostname));
742                 p = strchr(nmp->nm_hostname, ':');
743                 if (p)
744                         *p = '\0';
745         }
746
747         if (vfs_getopt(mp->mnt_optnew, "sec",
748                 (void **) &secname, NULL) == 0) {
749                 nmp->nm_secflavor = nfs_sec_name_to_num(secname);
750         } else {
751                 nmp->nm_secflavor = AUTH_SYS;
752         }
753
754         if (vfs_getopt(mp->mnt_optnew, "principal",
755                 (void **) &principal, NULL) == 0) {
756                 strlcpy(nmp->nm_principal, principal,
757                     sizeof(nmp->nm_principal));
758         } else {
759                 snprintf(nmp->nm_principal, sizeof(nmp->nm_principal),
760                     "nfs@%s", nmp->nm_hostname);
761         }
762 }
763
764 static const char *nfs_opts[] = { "from", "nfs_args",
765     "noatime", "noexec", "suiddir", "nosuid", "nosymfollow", "union",
766     "noclusterr", "noclusterw", "multilabel", "acls", "force", "update",
767     "async", "dumbtimer", "noconn", "nolockd", "intr", "rdirplus", "resvport",
768     "readdirsize", "soft", "hard", "mntudp", "tcp", "udp", "wsize", "rsize",
769     "retrans", "acregmin", "acregmax", "acdirmin", "acdirmax", 
770     "deadthresh", "hostname", "timeout", "addr", "fh", "nfsv3", "sec",
771     "maxgroups", "principal",
772     NULL };
773
774 /*
775  * VFS Operations.
776  *
777  * mount system call
778  * It seems a bit dumb to copyinstr() the host and path here and then
779  * bcopy() them in mountnfs(), but I wanted to detect errors before
780  * doing the sockargs() call because sockargs() allocates an mbuf and
781  * an error after that means that I have to release the mbuf.
782  */
783 /* ARGSUSED */
784 static int
785 nfs_mount(struct mount *mp)
786 {
787         struct nfs_args args = {
788             .version = NFS_ARGSVERSION,
789             .addr = NULL,
790             .addrlen = sizeof (struct sockaddr_in),
791             .sotype = SOCK_STREAM,
792             .proto = 0,
793             .fh = NULL,
794             .fhsize = 0,
795             .flags = NFSMNT_RESVPORT,
796             .wsize = NFS_WSIZE,
797             .rsize = NFS_RSIZE,
798             .readdirsize = NFS_READDIRSIZE,
799             .timeo = 10,
800             .retrans = NFS_RETRANS,
801             .maxgrouplist = NFS_MAXGRPS,
802             .readahead = NFS_DEFRAHEAD,
803             .wcommitsize = 0,                   /* was: NQ_DEFLEASE */
804             .deadthresh = NFS_MAXDEADTHRESH,    /* was: NQ_DEADTHRESH */
805             .hostname = NULL,
806             /* args version 4 */
807             .acregmin = NFS_MINATTRTIMO,
808             .acregmax = NFS_MAXATTRTIMO,
809             .acdirmin = NFS_MINDIRATTRTIMO,
810             .acdirmax = NFS_MAXDIRATTRTIMO,
811         };
812         int error, ret, has_nfs_args_opt;
813         int has_addr_opt, has_fh_opt, has_hostname_opt;
814         struct sockaddr *nam;
815         struct vnode *vp;
816         char hst[MNAMELEN];
817         size_t len;
818         u_char nfh[NFSX_V3FHMAX];
819         char *opt;
820
821         has_nfs_args_opt = 0;
822         has_addr_opt = 0;
823         has_fh_opt = 0;
824         has_hostname_opt = 0;
825
826         if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) {
827                 error = EINVAL;
828                 goto out;
829         }
830
831         if ((mp->mnt_flag & (MNT_ROOTFS | MNT_UPDATE)) == MNT_ROOTFS) {
832                 error = nfs_mountroot(mp);
833                 goto out;
834         }
835
836         /*
837          * The old mount_nfs program passed the struct nfs_args
838          * from userspace to kernel.  The new mount_nfs program
839          * passes string options via nmount() from userspace to kernel
840          * and we populate the struct nfs_args in the kernel.
841          */
842         if (vfs_getopt(mp->mnt_optnew, "nfs_args", NULL, NULL) == 0) {
843                 error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args,
844                     sizeof args);
845                 if (error)
846                         goto out;
847
848                 if (args.version != NFS_ARGSVERSION) {
849                         error = EPROGMISMATCH;
850                         goto out;
851                 }
852                 has_nfs_args_opt = 1;
853         }
854
855         if (vfs_getopt(mp->mnt_optnew, "dumbtimer", NULL, NULL) == 0)
856                 args.flags |= NFSMNT_DUMBTIMR;
857         if (vfs_getopt(mp->mnt_optnew, "noconn", NULL, NULL) == 0)
858                 args.flags |= NFSMNT_NOCONN;
859         if (vfs_getopt(mp->mnt_optnew, "conn", NULL, NULL) == 0)
860                 args.flags |= NFSMNT_NOCONN;
861         if (vfs_getopt(mp->mnt_optnew, "nolockd", NULL, NULL) == 0)
862                 args.flags |= NFSMNT_NOLOCKD;
863         if (vfs_getopt(mp->mnt_optnew, "lockd", NULL, NULL) == 0)
864                 args.flags &= ~NFSMNT_NOLOCKD;
865         if (vfs_getopt(mp->mnt_optnew, "intr", NULL, NULL) == 0)
866                 args.flags |= NFSMNT_INT;
867         if (vfs_getopt(mp->mnt_optnew, "rdirplus", NULL, NULL) == 0)
868                 args.flags |= NFSMNT_RDIRPLUS;
869         if (vfs_getopt(mp->mnt_optnew, "resvport", NULL, NULL) == 0)
870                 args.flags |= NFSMNT_RESVPORT;
871         if (vfs_getopt(mp->mnt_optnew, "noresvport", NULL, NULL) == 0)
872                 args.flags &= ~NFSMNT_RESVPORT;
873         if (vfs_getopt(mp->mnt_optnew, "soft", NULL, NULL) == 0)
874                 args.flags |= NFSMNT_SOFT;
875         if (vfs_getopt(mp->mnt_optnew, "hard", NULL, NULL) == 0)
876                 args.flags &= ~NFSMNT_SOFT;
877         if (vfs_getopt(mp->mnt_optnew, "mntudp", NULL, NULL) == 0)
878                 args.sotype = SOCK_DGRAM;
879         if (vfs_getopt(mp->mnt_optnew, "udp", NULL, NULL) == 0)
880                 args.sotype = SOCK_DGRAM;
881         if (vfs_getopt(mp->mnt_optnew, "tcp", NULL, NULL) == 0)
882                 args.sotype = SOCK_STREAM;
883         if (vfs_getopt(mp->mnt_optnew, "nfsv3", NULL, NULL) == 0)
884                 args.flags |= NFSMNT_NFSV3;
885         if (vfs_getopt(mp->mnt_optnew, "readdirsize", (void **)&opt, NULL) == 0) {
886                 if (opt == NULL) { 
887                         vfs_mount_error(mp, "illegal readdirsize");
888                         error = EINVAL;
889                         goto out;
890                 }
891                 ret = sscanf(opt, "%d", &args.readdirsize);
892                 if (ret != 1 || args.readdirsize <= 0) {
893                         vfs_mount_error(mp, "illegal readdirsize: %s",
894                             opt);
895                         error = EINVAL;
896                         goto out;
897                 }
898                 args.flags |= NFSMNT_READDIRSIZE;
899         }
900         if (vfs_getopt(mp->mnt_optnew, "readahead", (void **)&opt, NULL) == 0) {
901                 if (opt == NULL) { 
902                         vfs_mount_error(mp, "illegal readahead");
903                         error = EINVAL;
904                         goto out;
905                 }
906                 ret = sscanf(opt, "%d", &args.readahead);
907                 if (ret != 1 || args.readahead <= 0) {
908                         vfs_mount_error(mp, "illegal readahead: %s",
909                             opt);
910                         error = EINVAL;
911                         goto out;
912                 }
913                 args.flags |= NFSMNT_READAHEAD;
914         }
915         if (vfs_getopt(mp->mnt_optnew, "wsize", (void **)&opt, NULL) == 0) {
916                 if (opt == NULL) { 
917                         vfs_mount_error(mp, "illegal wsize");
918                         error = EINVAL;
919                         goto out;
920                 }
921                 ret = sscanf(opt, "%d", &args.wsize);
922                 if (ret != 1 || args.wsize <= 0) {
923                         vfs_mount_error(mp, "illegal wsize: %s",
924                             opt);
925                         error = EINVAL;
926                         goto out;
927                 }
928                 args.flags |= NFSMNT_WSIZE;
929         }
930         if (vfs_getopt(mp->mnt_optnew, "rsize", (void **)&opt, NULL) == 0) {
931                 if (opt == NULL) { 
932                         vfs_mount_error(mp, "illegal rsize");
933                         error = EINVAL;
934                         goto out;
935                 }
936                 ret = sscanf(opt, "%d", &args.rsize);
937                 if (ret != 1 || args.rsize <= 0) {
938                         vfs_mount_error(mp, "illegal wsize: %s",
939                             opt);
940                         error = EINVAL;
941                         goto out;
942                 }
943                 args.flags |= NFSMNT_RSIZE;
944         }
945         if (vfs_getopt(mp->mnt_optnew, "retrans", (void **)&opt, NULL) == 0) {
946                 if (opt == NULL) { 
947                         vfs_mount_error(mp, "illegal retrans");
948                         error = EINVAL;
949                         goto out;
950                 }
951                 ret = sscanf(opt, "%d", &args.retrans);
952                 if (ret != 1 || args.retrans <= 0) {
953                         vfs_mount_error(mp, "illegal retrans: %s",
954                             opt);
955                         error = EINVAL;
956                         goto out;
957                 }
958                 args.flags |= NFSMNT_RETRANS;
959         }
960         if (vfs_getopt(mp->mnt_optnew, "acregmin", (void **)&opt, NULL) == 0) {
961                 ret = sscanf(opt, "%d", &args.acregmin);
962                 if (ret != 1 || args.acregmin < 0) {
963                         vfs_mount_error(mp, "illegal acregmin: %s",
964                             opt);
965                         error = EINVAL;
966                         goto out;
967                 }
968                 args.flags |= NFSMNT_ACREGMIN;
969         }
970         if (vfs_getopt(mp->mnt_optnew, "acregmax", (void **)&opt, NULL) == 0) {
971                 ret = sscanf(opt, "%d", &args.acregmax);
972                 if (ret != 1 || args.acregmax < 0) {
973                         vfs_mount_error(mp, "illegal acregmax: %s",
974                             opt);
975                         error = EINVAL;
976                         goto out;
977                 }
978                 args.flags |= NFSMNT_ACREGMAX;
979         }
980         if (vfs_getopt(mp->mnt_optnew, "acdirmin", (void **)&opt, NULL) == 0) {
981                 ret = sscanf(opt, "%d", &args.acdirmin);
982                 if (ret != 1 || args.acdirmin < 0) {
983                         vfs_mount_error(mp, "illegal acdirmin: %s",
984                             opt);
985                         error = EINVAL;
986                         goto out;
987                 }
988                 args.flags |= NFSMNT_ACDIRMIN;
989         }
990         if (vfs_getopt(mp->mnt_optnew, "acdirmax", (void **)&opt, NULL) == 0) {
991                 ret = sscanf(opt, "%d", &args.acdirmax);
992                 if (ret != 1 || args.acdirmax < 0) {
993                         vfs_mount_error(mp, "illegal acdirmax: %s",
994                             opt);
995                         error = EINVAL;
996                         goto out;
997                 }
998                 args.flags |= NFSMNT_ACDIRMAX;
999         }
1000         if (vfs_getopt(mp->mnt_optnew, "deadthresh", (void **)&opt, NULL) == 0) {
1001                 ret = sscanf(opt, "%d", &args.deadthresh);
1002                 if (ret != 1 || args.deadthresh <= 0) {
1003                         vfs_mount_error(mp, "illegal deadthresh: %s",
1004                             opt);
1005                         error = EINVAL;
1006                         goto out;
1007                 }
1008                 args.flags |= NFSMNT_DEADTHRESH;
1009         }
1010         if (vfs_getopt(mp->mnt_optnew, "timeout", (void **)&opt, NULL) == 0) {
1011                 ret = sscanf(opt, "%d", &args.timeo);
1012                 if (ret != 1 || args.timeo <= 0) {
1013                         vfs_mount_error(mp, "illegal timeout: %s",
1014                             opt);
1015                         error = EINVAL;
1016                         goto out;
1017                 }
1018                 args.flags |= NFSMNT_TIMEO;
1019         }
1020         if (vfs_getopt(mp->mnt_optnew, "maxgroups", (void **)&opt, NULL) == 0) {
1021                 ret = sscanf(opt, "%d", &args.maxgrouplist);
1022                 if (ret != 1 || args.timeo <= 0) {
1023                         vfs_mount_error(mp, "illegal maxgroups: %s",
1024                             opt);
1025                         error = EINVAL;
1026                         goto out;
1027                 }
1028                 args.flags |= NFSMNT_MAXGRPS;
1029         }
1030         if (vfs_getopt(mp->mnt_optnew, "addr", (void **)&args.addr,
1031                 &args.addrlen) == 0) {
1032                 has_addr_opt = 1;
1033                 if (args.addrlen > SOCK_MAXADDRLEN) {
1034                         error = ENAMETOOLONG;
1035                         goto out;
1036                 }
1037                 nam = malloc(args.addrlen, M_SONAME,
1038                     M_WAITOK);
1039                 bcopy(args.addr, nam, args.addrlen);
1040                 nam->sa_len = args.addrlen;
1041         }
1042         if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh,
1043                 &args.fhsize) == 0) {
1044                 has_fh_opt = 1;
1045         }
1046         if (vfs_getopt(mp->mnt_optnew, "hostname", (void **)&args.hostname,
1047                 NULL) == 0) {
1048                 has_hostname_opt = 1;
1049         }
1050         if (args.hostname == NULL) {
1051                 vfs_mount_error(mp, "Invalid hostname");
1052                 error = EINVAL;
1053                 goto out;
1054         }
1055
1056         if (mp->mnt_flag & MNT_UPDATE) {
1057                 struct nfsmount *nmp = VFSTONFS(mp);
1058
1059                 if (nmp == NULL) {
1060                         error = EIO;
1061                         goto out;
1062                 }
1063                 /*
1064                  * When doing an update, we can't change from or to
1065                  * v3, switch lockd strategies or change cookie translation
1066                  */
1067                 args.flags = (args.flags &
1068                     ~(NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) |
1069                     (nmp->nm_flag &
1070                         (NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
1071                 nfs_decode_args(mp, nmp, &args, NULL);
1072                 goto out;
1073         }
1074
1075         /*
1076          * Make the nfs_ip_paranoia sysctl serve as the default connection
1077          * or no-connection mode for those protocols that support 
1078          * no-connection mode (the flag will be cleared later for protocols
1079          * that do not support no-connection mode).  This will allow a client
1080          * to receive replies from a different IP then the request was
1081          * sent to.  Note: default value for nfs_ip_paranoia is 1 (paranoid),
1082          * not 0.
1083          */
1084         if (nfs_ip_paranoia == 0)
1085                 args.flags |= NFSMNT_NOCONN;
1086
1087         if (has_nfs_args_opt) {
1088                 /*
1089                  * In the 'nfs_args' case, the pointers in the args
1090                  * structure are in userland - we copy them in here.
1091                  */
1092                 if (!has_fh_opt) {
1093                         error = copyin((caddr_t)args.fh, (caddr_t)nfh,
1094                             args.fhsize);
1095                         if (error) {
1096                                 goto out;
1097                         }
1098                         args.fh = nfh;
1099                 }
1100                 if (!has_hostname_opt) {
1101                         error = copyinstr(args.hostname, hst, MNAMELEN-1, &len);
1102                         if (error) {
1103                                 goto out;
1104                         }
1105                         bzero(&hst[len], MNAMELEN - len);
1106                         args.hostname = hst;
1107                 }
1108                 if (!has_addr_opt) {
1109                         /* sockargs() call must be after above copyin() calls */
1110                         error = getsockaddr(&nam, (caddr_t)args.addr,
1111                             args.addrlen);
1112                         if (error) {
1113                                 goto out;
1114                         }
1115                 }
1116         }
1117         error = mountnfs(&args, mp, nam, args.hostname, &vp,
1118             curthread->td_ucred);
1119 out:
1120         if (!error) {
1121                 MNT_ILOCK(mp);
1122                 mp->mnt_kern_flag |= (MNTK_MPSAFE|MNTK_LOOKUP_SHARED);
1123                 MNT_IUNLOCK(mp);
1124         }
1125         return (error);
1126 }
1127
1128
1129 /*
1130  * VFS Operations.
1131  *
1132  * mount system call
1133  * It seems a bit dumb to copyinstr() the host and path here and then
1134  * bcopy() them in mountnfs(), but I wanted to detect errors before
1135  * doing the sockargs() call because sockargs() allocates an mbuf and
1136  * an error after that means that I have to release the mbuf.
1137  */
1138 /* ARGSUSED */
1139 static int
1140 nfs_cmount(struct mntarg *ma, void *data, int flags)
1141 {
1142         int error;
1143         struct nfs_args args;
1144
1145         error = copyin(data, &args, sizeof (struct nfs_args));
1146         if (error)
1147                 return error;
1148
1149         ma = mount_arg(ma, "nfs_args", &args, sizeof args);
1150
1151         error = kernel_mount(ma, flags);
1152         return (error);
1153 }
1154
1155 /*
1156  * Common code for mount and mountroot
1157  */
1158 static int
1159 mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
1160     char *hst, struct vnode **vpp, struct ucred *cred)
1161 {
1162         struct nfsmount *nmp;
1163         struct nfsnode *np;
1164         int error;
1165         struct vattr attrs;
1166
1167         if (mp->mnt_flag & MNT_UPDATE) {
1168                 nmp = VFSTONFS(mp);
1169                 printf("%s: MNT_UPDATE is no longer handled here\n", __func__);
1170                 free(nam, M_SONAME);
1171                 return (0);
1172         } else {
1173                 nmp = uma_zalloc(nfsmount_zone, M_WAITOK);
1174                 bzero((caddr_t)nmp, sizeof (struct nfsmount));
1175                 TAILQ_INIT(&nmp->nm_bufq);
1176                 mp->mnt_data = nmp;
1177         }
1178         vfs_getnewfsid(mp);
1179         nmp->nm_mountp = mp;
1180         mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF);                 
1181
1182         /*
1183          * V2 can only handle 32 bit filesizes.  A 4GB-1 limit may be too
1184          * high, depending on whether we end up with negative offsets in
1185          * the client or server somewhere.  2GB-1 may be safer.
1186          *
1187          * For V3, nfs_fsinfo will adjust this as necessary.  Assume maximum
1188          * that we can handle until we find out otherwise.
1189          * XXX Our "safe" limit on the client is what we can store in our
1190          * buffer cache using signed(!) block numbers.
1191          */
1192         if ((argp->flags & NFSMNT_NFSV3) == 0)
1193                 nmp->nm_maxfilesize = 0xffffffffLL;
1194         else
1195                 nmp->nm_maxfilesize = (u_int64_t)0x80000000 * DEV_BSIZE - 1;
1196
1197         nmp->nm_timeo = NFS_TIMEO;
1198         nmp->nm_retry = NFS_RETRANS;
1199         if ((argp->flags & NFSMNT_NFSV3) && argp->sotype == SOCK_STREAM) {
1200                 nmp->nm_wsize = nmp->nm_rsize = NFS_MAXDATA;
1201         } else {
1202                 nmp->nm_wsize = NFS_WSIZE;
1203                 nmp->nm_rsize = NFS_RSIZE;
1204         }
1205         nmp->nm_wcommitsize = hibufspace / (desiredvnodes / 1000);
1206         nmp->nm_readdirsize = NFS_READDIRSIZE;
1207         nmp->nm_numgrps = NFS_MAXGRPS;
1208         nmp->nm_readahead = NFS_DEFRAHEAD;
1209         nmp->nm_deadthresh = NFS_MAXDEADTHRESH;
1210         nmp->nm_tprintf_delay = nfs_tprintf_delay;
1211         if (nmp->nm_tprintf_delay < 0)
1212                 nmp->nm_tprintf_delay = 0;
1213         nmp->nm_tprintf_initial_delay = nfs_tprintf_initial_delay;
1214         if (nmp->nm_tprintf_initial_delay < 0)
1215                 nmp->nm_tprintf_initial_delay = 0;
1216         nmp->nm_fhsize = argp->fhsize;
1217         bcopy((caddr_t)argp->fh, (caddr_t)nmp->nm_fh, argp->fhsize);
1218         bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);
1219         nmp->nm_nam = nam;
1220         /* Set up the sockets and per-host congestion */
1221         nmp->nm_sotype = argp->sotype;
1222         nmp->nm_soproto = argp->proto;
1223         nmp->nm_rpcops = &nfs_rpcops;
1224
1225         nfs_decode_args(mp, nmp, argp, hst);
1226
1227         /*
1228          * For Connection based sockets (TCP,...) defer the connect until
1229          * the first request, in case the server is not responding.
1230          */
1231         if (nmp->nm_sotype == SOCK_DGRAM &&
1232                 (error = nfs_connect(nmp)))
1233                 goto bad;
1234
1235         /*
1236          * This is silly, but it has to be set so that vinifod() works.
1237          * We do not want to do an nfs_statfs() here since we can get
1238          * stuck on a dead server and we are holding a lock on the mount
1239          * point.
1240          */
1241         mtx_lock(&nmp->nm_mtx);
1242         mp->mnt_stat.f_iosize = nfs_iosize(nmp);
1243         mtx_unlock(&nmp->nm_mtx);
1244         /*
1245          * A reference count is needed on the nfsnode representing the
1246          * remote root.  If this object is not persistent, then backward
1247          * traversals of the mount point (i.e. "..") will not work if
1248          * the nfsnode gets flushed out of the cache. Ufs does not have
1249          * this problem, because one can identify root inodes by their
1250          * number == ROOTINO (2).
1251          */
1252         error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
1253         if (error)
1254                 goto bad;
1255         *vpp = NFSTOV(np);
1256
1257         /*
1258          * Get file attributes and transfer parameters for the
1259          * mountpoint.  This has the side effect of filling in
1260          * (*vpp)->v_type with the correct value.
1261          */
1262         if (argp->flags & NFSMNT_NFSV3)
1263                 nfs_fsinfo(nmp, *vpp, curthread->td_ucred, curthread);
1264         else
1265                 VOP_GETATTR(*vpp, &attrs, curthread->td_ucred);
1266
1267         /*
1268          * Lose the lock but keep the ref.
1269          */
1270         VOP_UNLOCK(*vpp, 0);
1271
1272         return (0);
1273 bad:
1274         nfs_disconnect(nmp);
1275         mtx_destroy(&nmp->nm_mtx);
1276         uma_zfree(nfsmount_zone, nmp);
1277         free(nam, M_SONAME);
1278         return (error);
1279 }
1280
1281 /*
1282  * unmount system call
1283  */
1284 static int
1285 nfs_unmount(struct mount *mp, int mntflags)
1286 {
1287         struct nfsmount *nmp;
1288         int error, flags = 0;
1289
1290         if (mntflags & MNT_FORCE)
1291                 flags |= FORCECLOSE;
1292         nmp = VFSTONFS(mp);
1293         /*
1294          * Goes something like this..
1295          * - Call vflush() to clear out vnodes for this filesystem
1296          * - Close the socket
1297          * - Free up the data structures
1298          */
1299         /* In the forced case, cancel any outstanding requests. */
1300         if (flags & FORCECLOSE) {
1301                 error = nfs_nmcancelreqs(nmp);
1302                 if (error)
1303                         goto out;
1304         }
1305         /* We hold 1 extra ref on the root vnode; see comment in mountnfs(). */
1306         error = vflush(mp, 1, flags, curthread);
1307         if (error)
1308                 goto out;
1309
1310         /*
1311          * We are now committed to the unmount.
1312          */
1313         nfs_disconnect(nmp);
1314         free(nmp->nm_nam, M_SONAME);
1315
1316         mtx_destroy(&nmp->nm_mtx);
1317         uma_zfree(nfsmount_zone, nmp);
1318 out:
1319         return (error);
1320 }
1321
1322 /*
1323  * Return root of a filesystem
1324  */
1325 static int
1326 nfs_root(struct mount *mp, int flags, struct vnode **vpp)
1327 {
1328         struct vnode *vp;
1329         struct nfsmount *nmp;
1330         struct nfsnode *np;
1331         int error;
1332
1333         nmp = VFSTONFS(mp);
1334         error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, flags);
1335         if (error)
1336                 return error;
1337         vp = NFSTOV(np);
1338         /*
1339          * Get transfer parameters and attributes for root vnode once.
1340          */
1341         mtx_lock(&nmp->nm_mtx);
1342         if ((nmp->nm_state & NFSSTA_GOTFSINFO) == 0 &&
1343             (nmp->nm_flag & NFSMNT_NFSV3)) {
1344                 mtx_unlock(&nmp->nm_mtx);
1345                 nfs_fsinfo(nmp, vp, curthread->td_ucred, curthread);
1346         } else 
1347                 mtx_unlock(&nmp->nm_mtx);
1348         if (vp->v_type == VNON)
1349             vp->v_type = VDIR;
1350         vp->v_vflag |= VV_ROOT;
1351         *vpp = vp;
1352         return (0);
1353 }
1354
1355 /*
1356  * Flush out the buffer cache
1357  */
1358 /* ARGSUSED */
1359 static int
1360 nfs_sync(struct mount *mp, int waitfor)
1361 {
1362         struct vnode *vp, *mvp;
1363         struct thread *td;
1364         int error, allerror = 0;
1365
1366         td = curthread;
1367
1368         /*
1369          * Force stale buffer cache information to be flushed.
1370          */
1371         MNT_ILOCK(mp);
1372 loop:
1373         MNT_VNODE_FOREACH(vp, mp, mvp) {
1374                 VI_LOCK(vp);
1375                 MNT_IUNLOCK(mp);
1376                 /* XXX Racy bv_cnt check. */
1377                 if (VOP_ISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
1378                     waitfor == MNT_LAZY) {
1379                         VI_UNLOCK(vp);
1380                         MNT_ILOCK(mp);
1381                         continue;
1382                 }
1383                 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
1384                         MNT_ILOCK(mp);
1385                         MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp);
1386                         goto loop;
1387                 }
1388                 error = VOP_FSYNC(vp, waitfor, td);
1389                 if (error)
1390                         allerror = error;
1391                 VOP_UNLOCK(vp, 0);
1392                 vrele(vp);
1393
1394                 MNT_ILOCK(mp);
1395         }
1396         MNT_IUNLOCK(mp);
1397         return (allerror);
1398 }
1399
1400 static int
1401 nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req)
1402 {
1403         struct nfsmount *nmp = VFSTONFS(mp);
1404         struct vfsquery vq;
1405         int error;
1406
1407         bzero(&vq, sizeof(vq));
1408         switch (op) {
1409 #if 0
1410         case VFS_CTL_NOLOCKS:
1411                 val = (nmp->nm_flag & NFSMNT_NOLOCKS) ? 1 : 0;
1412                 if (req->oldptr != NULL) {
1413                         error = SYSCTL_OUT(req, &val, sizeof(val));
1414                         if (error)
1415                                 return (error);
1416                 }
1417                 if (req->newptr != NULL) {
1418                         error = SYSCTL_IN(req, &val, sizeof(val));
1419                         if (error)
1420                                 return (error);
1421                         if (val)
1422                                 nmp->nm_flag |= NFSMNT_NOLOCKS;
1423                         else
1424                                 nmp->nm_flag &= ~NFSMNT_NOLOCKS;
1425                 }
1426                 break;
1427 #endif
1428         case VFS_CTL_QUERY:
1429                 mtx_lock(&nmp->nm_mtx);
1430                 if (nmp->nm_state & NFSSTA_TIMEO)
1431                         vq.vq_flags |= VQ_NOTRESP;
1432                 mtx_unlock(&nmp->nm_mtx);
1433 #if 0
1434                 if (!(nmp->nm_flag & NFSMNT_NOLOCKS) &&
1435                     (nmp->nm_state & NFSSTA_LOCKTIMEO))
1436                         vq.vq_flags |= VQ_NOTRESPLOCK;
1437 #endif
1438                 error = SYSCTL_OUT(req, &vq, sizeof(vq));
1439                 break;
1440         case VFS_CTL_TIMEO:
1441                 if (req->oldptr != NULL) {
1442                         error = SYSCTL_OUT(req, &nmp->nm_tprintf_initial_delay,
1443                             sizeof(nmp->nm_tprintf_initial_delay));
1444                         if (error)
1445                                 return (error);
1446                 }
1447                 if (req->newptr != NULL) {
1448                         error = vfs_suser(mp, req->td);
1449                         if (error)
1450                                 return (error);
1451                         error = SYSCTL_IN(req, &nmp->nm_tprintf_initial_delay,
1452                             sizeof(nmp->nm_tprintf_initial_delay));
1453                         if (error)
1454                                 return (error);
1455                         if (nmp->nm_tprintf_initial_delay < 0)
1456                                 nmp->nm_tprintf_initial_delay = 0;
1457                 }
1458                 break;
1459         default:
1460                 return (ENOTSUP);
1461         }
1462         return (0);
1463 }