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