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