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