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); 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(RTM_ADD, (struct sockaddr *)&sin, 463 (struct sockaddr *)&nd->mygateway, 464 (struct sockaddr *)&mask, 465 RTF_UP | RTF_GATEWAY, NULL); 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_NEGNAMETIMEO)) != 0) { 524 printf("nfs_mountroot: mount %s on /: %d\n", path, error); 525 return (error); 526 } 527 return (0); 528 } 529 530 static void 531 nfs_sec_name(char *sec, int *flagsp) 532 { 533 if (!strcmp(sec, "krb5")) 534 *flagsp |= NFSMNT_KERB; 535 else if (!strcmp(sec, "krb5i")) 536 *flagsp |= (NFSMNT_KERB | NFSMNT_INTEGRITY); 537 else if (!strcmp(sec, "krb5p")) 538 *flagsp |= (NFSMNT_KERB | NFSMNT_PRIVACY); 539 } 540 541 static void 542 nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp, 543 const char *hostname, struct ucred *cred, struct thread *td) 544 { 545 int s; 546 int adjsock; 547 char *p; 548 549 s = splnet(); 550 551 /* 552 * Set read-only flag if requested; otherwise, clear it if this is 553 * an update. If this is not an update, then either the read-only 554 * flag is already clear, or this is a root mount and it was set 555 * intentionally at some previous point. 556 */ 557 if (vfs_getopt(mp->mnt_optnew, "ro", NULL, NULL) == 0) { 558 MNT_ILOCK(mp); 559 mp->mnt_flag |= MNT_RDONLY; 560 MNT_IUNLOCK(mp); 561 } else if (mp->mnt_flag & MNT_UPDATE) { 562 MNT_ILOCK(mp); 563 mp->mnt_flag &= ~MNT_RDONLY; 564 MNT_IUNLOCK(mp); 565 } 566 567 /* 568 * Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes 569 * no sense in that context. Also, set up appropriate retransmit 570 * and soft timeout behavior. 571 */ 572 if (argp->sotype == SOCK_STREAM) { 573 nmp->nm_flag &= ~NFSMNT_NOCONN; 574 nmp->nm_timeo = NFS_MAXTIMEO; 575 if ((argp->flags & NFSMNT_NFSV4) != 0) 576 nmp->nm_retry = INT_MAX; 577 else 578 nmp->nm_retry = NFS_RETRANS_TCP; 579 } 580 581 /* Also clear RDIRPLUS if NFSv2, it crashes some servers */ 582 if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0) { 583 argp->flags &= ~NFSMNT_RDIRPLUS; 584 nmp->nm_flag &= ~NFSMNT_RDIRPLUS; 585 } 586 587 /* Clear NFSMNT_RESVPORT for NFSv4, since it is not required. */ 588 if ((argp->flags & NFSMNT_NFSV4) != 0) { 589 argp->flags &= ~NFSMNT_RESVPORT; 590 nmp->nm_flag &= ~NFSMNT_RESVPORT; 591 } 592 593 /* Re-bind if rsrvd port requested and wasn't on one */ 594 adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT) 595 && (argp->flags & NFSMNT_RESVPORT); 596 /* Also re-bind if we're switching to/from a connected UDP socket */ 597 adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) != 598 (argp->flags & NFSMNT_NOCONN)); 599 600 /* Update flags atomically. Don't change the lock bits. */ 601 nmp->nm_flag = argp->flags | nmp->nm_flag; 602 splx(s); 603 604 if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) { 605 nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10; 606 if (nmp->nm_timeo < NFS_MINTIMEO) 607 nmp->nm_timeo = NFS_MINTIMEO; 608 else if (nmp->nm_timeo > NFS_MAXTIMEO) 609 nmp->nm_timeo = NFS_MAXTIMEO; 610 } 611 612 if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) { 613 nmp->nm_retry = argp->retrans; 614 if (nmp->nm_retry > NFS_MAXREXMIT) 615 nmp->nm_retry = NFS_MAXREXMIT; 616 } 617 618 if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) { 619 nmp->nm_wsize = argp->wsize; 620 /* Round down to multiple of blocksize */ 621 nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1); 622 if (nmp->nm_wsize <= 0) 623 nmp->nm_wsize = NFS_FABLKSIZE; 624 } 625 626 if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) { 627 nmp->nm_rsize = argp->rsize; 628 /* Round down to multiple of blocksize */ 629 nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1); 630 if (nmp->nm_rsize <= 0) 631 nmp->nm_rsize = NFS_FABLKSIZE; 632 } 633 634 if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) { 635 nmp->nm_readdirsize = argp->readdirsize; 636 } 637 638 if ((argp->flags & NFSMNT_ACREGMIN) && argp->acregmin >= 0) 639 nmp->nm_acregmin = argp->acregmin; 640 else 641 nmp->nm_acregmin = NFS_MINATTRTIMO; 642 if ((argp->flags & NFSMNT_ACREGMAX) && argp->acregmax >= 0) 643 nmp->nm_acregmax = argp->acregmax; 644 else 645 nmp->nm_acregmax = NFS_MAXATTRTIMO; 646 if ((argp->flags & NFSMNT_ACDIRMIN) && argp->acdirmin >= 0) 647 nmp->nm_acdirmin = argp->acdirmin; 648 else 649 nmp->nm_acdirmin = NFS_MINDIRATTRTIMO; 650 if ((argp->flags & NFSMNT_ACDIRMAX) && argp->acdirmax >= 0) 651 nmp->nm_acdirmax = argp->acdirmax; 652 else 653 nmp->nm_acdirmax = NFS_MAXDIRATTRTIMO; 654 if (nmp->nm_acdirmin > nmp->nm_acdirmax) 655 nmp->nm_acdirmin = nmp->nm_acdirmax; 656 if (nmp->nm_acregmin > nmp->nm_acregmax) 657 nmp->nm_acregmin = nmp->nm_acregmax; 658 659 if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0) { 660 if (argp->readahead <= NFS_MAXRAHEAD) 661 nmp->nm_readahead = argp->readahead; 662 else 663 nmp->nm_readahead = NFS_MAXRAHEAD; 664 } 665 if ((argp->flags & NFSMNT_WCOMMITSIZE) && argp->wcommitsize >= 0) { 666 if (argp->wcommitsize < nmp->nm_wsize) 667 nmp->nm_wcommitsize = nmp->nm_wsize; 668 else 669 nmp->nm_wcommitsize = argp->wcommitsize; 670 } 671 672 adjsock |= ((nmp->nm_sotype != argp->sotype) || 673 (nmp->nm_soproto != argp->proto)); 674 675 if (nmp->nm_client != NULL && adjsock) { 676 int haslock = 0, error = 0; 677 678 if (nmp->nm_sotype == SOCK_STREAM) { 679 error = newnfs_sndlock(&nmp->nm_sockreq.nr_lock); 680 if (!error) 681 haslock = 1; 682 } 683 if (!error) { 684 newnfs_disconnect(&nmp->nm_sockreq); 685 if (haslock) 686 newnfs_sndunlock(&nmp->nm_sockreq.nr_lock); 687 nmp->nm_sotype = argp->sotype; 688 nmp->nm_soproto = argp->proto; 689 if (nmp->nm_sotype == SOCK_DGRAM) 690 while (newnfs_connect(nmp, &nmp->nm_sockreq, 691 cred, td, 0)) { 692 printf("newnfs_args: retrying connect\n"); 693 (void) nfs_catnap(PSOCK, 0, "newnfscon"); 694 } 695 } 696 } else { 697 nmp->nm_sotype = argp->sotype; 698 nmp->nm_soproto = argp->proto; 699 } 700 701 if (hostname != NULL) { 702 strlcpy(nmp->nm_hostname, hostname, 703 sizeof(nmp->nm_hostname)); 704 p = strchr(nmp->nm_hostname, ':'); 705 if (p != NULL) 706 *p = '\0'; 707 } 708 } 709 710 static const char *nfs_opts[] = { "from", "nfs_args", 711 "noatime", "noexec", "suiddir", "nosuid", "nosymfollow", "union", 712 "noclusterr", "noclusterw", "multilabel", "acls", "force", "update", 713 "async", "noconn", "nolockd", "conn", "lockd", "intr", "rdirplus", 714 "readdirsize", "soft", "hard", "mntudp", "tcp", "udp", "wsize", "rsize", 715 "retrans", "acregmin", "acregmax", "acdirmin", "acdirmax", "resvport", 716 "readahead", "hostname", "timeout", "addr", "fh", "nfsv3", "sec", 717 "principal", "nfsv4", "gssname", "allgssname", "dirpath", 718 "negnametimeo", "nocto", "wcommitsize", 719 NULL }; 720 721 /* 722 * VFS Operations. 723 * 724 * mount system call 725 * It seems a bit dumb to copyinstr() the host and path here and then 726 * bcopy() them in mountnfs(), but I wanted to detect errors before 727 * doing the sockargs() call because sockargs() allocates an mbuf and 728 * an error after that means that I have to release the mbuf. 729 */ 730 /* ARGSUSED */ 731 static int 732 nfs_mount(struct mount *mp) 733 { 734 struct nfs_args args = { 735 .version = NFS_ARGSVERSION, 736 .addr = NULL, 737 .addrlen = sizeof (struct sockaddr_in), 738 .sotype = SOCK_STREAM, 739 .proto = 0, 740 .fh = NULL, 741 .fhsize = 0, 742 .flags = NFSMNT_RESVPORT, 743 .wsize = NFS_WSIZE, 744 .rsize = NFS_RSIZE, 745 .readdirsize = NFS_READDIRSIZE, 746 .timeo = 10, 747 .retrans = NFS_RETRANS, 748 .readahead = NFS_DEFRAHEAD, 749 .wcommitsize = 0, /* was: NQ_DEFLEASE */ 750 .hostname = NULL, 751 .acregmin = NFS_MINATTRTIMO, 752 .acregmax = NFS_MAXATTRTIMO, 753 .acdirmin = NFS_MINDIRATTRTIMO, 754 .acdirmax = NFS_MAXDIRATTRTIMO, 755 }; 756 int error = 0, ret, len; 757 struct sockaddr *nam = NULL; 758 struct vnode *vp; 759 struct thread *td; 760 char hst[MNAMELEN]; 761 u_char nfh[NFSX_FHMAX], krbname[100], dirpath[100], srvkrbname[100]; 762 char *opt, *name, *secname; 763 int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO; 764 int dirlen, has_nfs_args_opt, krbnamelen, srvkrbnamelen; 765 size_t hstlen; 766 767 has_nfs_args_opt = 0; 768 if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) { 769 error = EINVAL; 770 goto out; 771 } 772 773 td = curthread; 774 if ((mp->mnt_flag & (MNT_ROOTFS | MNT_UPDATE)) == MNT_ROOTFS) { 775 error = nfs_mountroot(mp); 776 goto out; 777 } 778 779 nfscl_init(); 780 781 /* 782 * The old mount_nfs program passed the struct nfs_args 783 * from userspace to kernel. The new mount_nfs program 784 * passes string options via nmount() from userspace to kernel 785 * and we populate the struct nfs_args in the kernel. 786 */ 787 if (vfs_getopt(mp->mnt_optnew, "nfs_args", NULL, NULL) == 0) { 788 error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args, 789 sizeof(args)); 790 if (error != 0) 791 goto out; 792 793 if (args.version != NFS_ARGSVERSION) { 794 error = EPROGMISMATCH; 795 goto out; 796 } 797 has_nfs_args_opt = 1; 798 } 799 800 /* Handle the new style options. */ 801 if (vfs_getopt(mp->mnt_optnew, "noconn", NULL, NULL) == 0) 802 args.flags |= NFSMNT_NOCONN; 803 if (vfs_getopt(mp->mnt_optnew, "conn", NULL, NULL) == 0) 804 args.flags |= NFSMNT_NOCONN; 805 if (vfs_getopt(mp->mnt_optnew, "nolockd", NULL, NULL) == 0) 806 args.flags |= NFSMNT_NOLOCKD; 807 if (vfs_getopt(mp->mnt_optnew, "lockd", NULL, NULL) == 0) 808 args.flags &= ~NFSMNT_NOLOCKD; 809 if (vfs_getopt(mp->mnt_optnew, "intr", NULL, NULL) == 0) 810 args.flags |= NFSMNT_INT; 811 if (vfs_getopt(mp->mnt_optnew, "rdirplus", NULL, NULL) == 0) 812 args.flags |= NFSMNT_RDIRPLUS; 813 if (vfs_getopt(mp->mnt_optnew, "resvport", NULL, NULL) == 0) 814 args.flags |= NFSMNT_RESVPORT; 815 if (vfs_getopt(mp->mnt_optnew, "noresvport", NULL, NULL) == 0) 816 args.flags &= ~NFSMNT_RESVPORT; 817 if (vfs_getopt(mp->mnt_optnew, "soft", NULL, NULL) == 0) 818 args.flags |= NFSMNT_SOFT; 819 if (vfs_getopt(mp->mnt_optnew, "hard", NULL, NULL) == 0) 820 args.flags &= ~NFSMNT_SOFT; 821 if (vfs_getopt(mp->mnt_optnew, "mntudp", NULL, NULL) == 0) 822 args.sotype = SOCK_DGRAM; 823 if (vfs_getopt(mp->mnt_optnew, "udp", NULL, NULL) == 0) 824 args.sotype = SOCK_DGRAM; 825 if (vfs_getopt(mp->mnt_optnew, "tcp", NULL, NULL) == 0) 826 args.sotype = SOCK_STREAM; 827 if (vfs_getopt(mp->mnt_optnew, "nfsv3", NULL, NULL) == 0) 828 args.flags |= NFSMNT_NFSV3; 829 if (vfs_getopt(mp->mnt_optnew, "nfsv4", NULL, NULL) == 0) { 830 args.flags |= NFSMNT_NFSV4; 831 args.sotype = SOCK_STREAM; 832 } 833 if (vfs_getopt(mp->mnt_optnew, "allgssname", NULL, NULL) == 0) 834 args.flags |= NFSMNT_ALLGSSNAME; 835 if (vfs_getopt(mp->mnt_optnew, "nocto", NULL, NULL) == 0) 836 args.flags |= NFSMNT_NOCTO; 837 if (vfs_getopt(mp->mnt_optnew, "readdirsize", (void **)&opt, NULL) == 0) { 838 if (opt == NULL) { 839 vfs_mount_error(mp, "illegal readdirsize"); 840 error = EINVAL; 841 goto out; 842 } 843 ret = sscanf(opt, "%d", &args.readdirsize); 844 if (ret != 1 || args.readdirsize <= 0) { 845 vfs_mount_error(mp, "illegal readdirsize: %s", 846 opt); 847 error = EINVAL; 848 goto out; 849 } 850 args.flags |= NFSMNT_READDIRSIZE; 851 } 852 if (vfs_getopt(mp->mnt_optnew, "readahead", (void **)&opt, NULL) == 0) { 853 if (opt == NULL) { 854 vfs_mount_error(mp, "illegal readahead"); 855 error = EINVAL; 856 goto out; 857 } 858 ret = sscanf(opt, "%d", &args.readahead); 859 if (ret != 1 || args.readahead <= 0) { 860 vfs_mount_error(mp, "illegal readahead: %s", 861 opt); 862 error = EINVAL; 863 goto out; 864 } 865 args.flags |= NFSMNT_READAHEAD; 866 } 867 if (vfs_getopt(mp->mnt_optnew, "wsize", (void **)&opt, NULL) == 0) { 868 if (opt == NULL) { 869 vfs_mount_error(mp, "illegal wsize"); 870 error = EINVAL; 871 goto out; 872 } 873 ret = sscanf(opt, "%d", &args.wsize); 874 if (ret != 1 || args.wsize <= 0) { 875 vfs_mount_error(mp, "illegal wsize: %s", 876 opt); 877 error = EINVAL; 878 goto out; 879 } 880 args.flags |= NFSMNT_WSIZE; 881 } 882 if (vfs_getopt(mp->mnt_optnew, "rsize", (void **)&opt, NULL) == 0) { 883 if (opt == NULL) { 884 vfs_mount_error(mp, "illegal rsize"); 885 error = EINVAL; 886 goto out; 887 } 888 ret = sscanf(opt, "%d", &args.rsize); 889 if (ret != 1 || args.rsize <= 0) { 890 vfs_mount_error(mp, "illegal wsize: %s", 891 opt); 892 error = EINVAL; 893 goto out; 894 } 895 args.flags |= NFSMNT_RSIZE; 896 } 897 if (vfs_getopt(mp->mnt_optnew, "retrans", (void **)&opt, NULL) == 0) { 898 if (opt == NULL) { 899 vfs_mount_error(mp, "illegal retrans"); 900 error = EINVAL; 901 goto out; 902 } 903 ret = sscanf(opt, "%d", &args.retrans); 904 if (ret != 1 || args.retrans <= 0) { 905 vfs_mount_error(mp, "illegal retrans: %s", 906 opt); 907 error = EINVAL; 908 goto out; 909 } 910 args.flags |= NFSMNT_RETRANS; 911 } 912 if (vfs_getopt(mp->mnt_optnew, "acregmin", (void **)&opt, NULL) == 0) { 913 ret = sscanf(opt, "%d", &args.acregmin); 914 if (ret != 1 || args.acregmin < 0) { 915 vfs_mount_error(mp, "illegal acregmin: %s", 916 opt); 917 error = EINVAL; 918 goto out; 919 } 920 args.flags |= NFSMNT_ACREGMIN; 921 } 922 if (vfs_getopt(mp->mnt_optnew, "acregmax", (void **)&opt, NULL) == 0) { 923 ret = sscanf(opt, "%d", &args.acregmax); 924 if (ret != 1 || args.acregmax < 0) { 925 vfs_mount_error(mp, "illegal acregmax: %s", 926 opt); 927 error = EINVAL; 928 goto out; 929 } 930 args.flags |= NFSMNT_ACREGMAX; 931 } 932 if (vfs_getopt(mp->mnt_optnew, "acdirmin", (void **)&opt, NULL) == 0) { 933 ret = sscanf(opt, "%d", &args.acdirmin); 934 if (ret != 1 || args.acdirmin < 0) { 935 vfs_mount_error(mp, "illegal acdirmin: %s", 936 opt); 937 error = EINVAL; 938 goto out; 939 } 940 args.flags |= NFSMNT_ACDIRMIN; 941 } 942 if (vfs_getopt(mp->mnt_optnew, "acdirmax", (void **)&opt, NULL) == 0) { 943 ret = sscanf(opt, "%d", &args.acdirmax); 944 if (ret != 1 || args.acdirmax < 0) { 945 vfs_mount_error(mp, "illegal acdirmax: %s", 946 opt); 947 error = EINVAL; 948 goto out; 949 } 950 args.flags |= NFSMNT_ACDIRMAX; 951 } 952 if (vfs_getopt(mp->mnt_optnew, "wcommitsize", (void **)&opt, NULL) == 0) { 953 ret = sscanf(opt, "%d", &args.wcommitsize); 954 if (ret != 1 || args.wcommitsize < 0) { 955 vfs_mount_error(mp, "illegal wcommitsize: %s", opt); 956 error = EINVAL; 957 goto out; 958 } 959 args.flags |= NFSMNT_WCOMMITSIZE; 960 } 961 if (vfs_getopt(mp->mnt_optnew, "timeout", (void **)&opt, NULL) == 0) { 962 ret = sscanf(opt, "%d", &args.timeo); 963 if (ret != 1 || args.timeo <= 0) { 964 vfs_mount_error(mp, "illegal timeout: %s", 965 opt); 966 error = EINVAL; 967 goto out; 968 } 969 args.flags |= NFSMNT_TIMEO; 970 } 971 if (vfs_getopt(mp->mnt_optnew, "negnametimeo", (void **)&opt, NULL) 972 == 0) { 973 ret = sscanf(opt, "%d", &negnametimeo); 974 if (ret != 1 || negnametimeo < 0) { 975 vfs_mount_error(mp, "illegal negnametimeo: %s", 976 opt); 977 error = EINVAL; 978 goto out; 979 } 980 } 981 if (vfs_getopt(mp->mnt_optnew, "sec", 982 (void **) &secname, NULL) == 0) 983 nfs_sec_name(secname, &args.flags); 984 985 if (mp->mnt_flag & MNT_UPDATE) { 986 struct nfsmount *nmp = VFSTONFS(mp); 987 988 if (nmp == NULL) { 989 error = EIO; 990 goto out; 991 } 992 /* 993 * When doing an update, we can't change version, 994 * security, switch lockd strategies or change cookie 995 * translation 996 */ 997 args.flags = (args.flags & 998 ~(NFSMNT_NFSV3 | 999 NFSMNT_NFSV4 | 1000 NFSMNT_KERB | 1001 NFSMNT_INTEGRITY | 1002 NFSMNT_PRIVACY | 1003 NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) | 1004 (nmp->nm_flag & 1005 (NFSMNT_NFSV3 | 1006 NFSMNT_NFSV4 | 1007 NFSMNT_KERB | 1008 NFSMNT_INTEGRITY | 1009 NFSMNT_PRIVACY | 1010 NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)); 1011 nfs_decode_args(mp, nmp, &args, NULL, td->td_ucred, td); 1012 goto out; 1013 } 1014 1015 /* 1016 * Make the nfs_ip_paranoia sysctl serve as the default connection 1017 * or no-connection mode for those protocols that support 1018 * no-connection mode (the flag will be cleared later for protocols 1019 * that do not support no-connection mode). This will allow a client 1020 * to receive replies from a different IP then the request was 1021 * sent to. Note: default value for nfs_ip_paranoia is 1 (paranoid), 1022 * not 0. 1023 */ 1024 if (nfs_ip_paranoia == 0) 1025 args.flags |= NFSMNT_NOCONN; 1026 1027 if (has_nfs_args_opt != 0) { 1028 /* 1029 * In the 'nfs_args' case, the pointers in the args 1030 * structure are in userland - we copy them in here. 1031 */ 1032 if (args.fhsize < 0 || args.fhsize > NFSX_V3FHMAX) { 1033 vfs_mount_error(mp, "Bad file handle"); 1034 error = EINVAL; 1035 goto out; 1036 } 1037 error = copyin((caddr_t)args.fh, (caddr_t)nfh, 1038 args.fhsize); 1039 if (error != 0) 1040 goto out; 1041 error = copyinstr(args.hostname, hst, MNAMELEN - 1, &hstlen); 1042 if (error != 0) 1043 goto out; 1044 bzero(&hst[hstlen], MNAMELEN - hstlen); 1045 args.hostname = hst; 1046 /* sockargs() call must be after above copyin() calls */ 1047 error = getsockaddr(&nam, (caddr_t)args.addr, 1048 args.addrlen); 1049 if (error != 0) 1050 goto out; 1051 } else { 1052 if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh, 1053 &args.fhsize) == 0) { 1054 if (args.fhsize < 0 || args.fhsize > NFSX_FHMAX) { 1055 vfs_mount_error(mp, "Bad file handle"); 1056 error = EINVAL; 1057 goto out; 1058 } 1059 bcopy(args.fh, nfh, args.fhsize); 1060 } else { 1061 args.fhsize = 0; 1062 } 1063 (void) vfs_getopt(mp->mnt_optnew, "hostname", 1064 (void **)&args.hostname, &len); 1065 if (args.hostname == NULL) { 1066 vfs_mount_error(mp, "Invalid hostname"); 1067 error = EINVAL; 1068 goto out; 1069 } 1070 bcopy(args.hostname, hst, MNAMELEN); 1071 hst[MNAMELEN - 1] = '\0'; 1072 } 1073 1074 if (vfs_getopt(mp->mnt_optnew, "principal", (void **)&name, NULL) == 0) 1075 strlcpy(srvkrbname, name, sizeof (srvkrbname)); 1076 else 1077 snprintf(srvkrbname, sizeof (srvkrbname), "nfs@%s", hst); 1078 srvkrbnamelen = strlen(srvkrbname); 1079 1080 if (vfs_getopt(mp->mnt_optnew, "gssname", (void **)&name, NULL) == 0) 1081 strlcpy(krbname, name, sizeof (krbname)); 1082 else 1083 krbname[0] = '\0'; 1084 krbnamelen = strlen(krbname); 1085 1086 if (vfs_getopt(mp->mnt_optnew, "dirpath", (void **)&name, NULL) == 0) 1087 strlcpy(dirpath, name, sizeof (dirpath)); 1088 else 1089 dirpath[0] = '\0'; 1090 dirlen = strlen(dirpath); 1091 1092 if (has_nfs_args_opt == 0) { 1093 if (vfs_getopt(mp->mnt_optnew, "addr", 1094 (void **)&args.addr, &args.addrlen) == 0) { 1095 if (args.addrlen > SOCK_MAXADDRLEN) { 1096 error = ENAMETOOLONG; 1097 goto out; 1098 } 1099 nam = malloc(args.addrlen, M_SONAME, M_WAITOK); 1100 bcopy(args.addr, nam, args.addrlen); 1101 nam->sa_len = args.addrlen; 1102 } else { 1103 vfs_mount_error(mp, "No server address"); 1104 error = EINVAL; 1105 goto out; 1106 } 1107 } 1108 1109 args.fh = nfh; 1110 error = mountnfs(&args, mp, nam, hst, krbname, krbnamelen, dirpath, 1111 dirlen, srvkrbname, srvkrbnamelen, &vp, td->td_ucred, td, 1112 negnametimeo); 1113 out: 1114 if (!error) { 1115 MNT_ILOCK(mp); 1116 mp->mnt_kern_flag |= (MNTK_MPSAFE|MNTK_LOOKUP_SHARED); 1117 MNT_IUNLOCK(mp); 1118 } 1119 return (error); 1120 } 1121 1122 1123 /* 1124 * VFS Operations. 1125 * 1126 * mount system call 1127 * It seems a bit dumb to copyinstr() the host and path here and then 1128 * bcopy() them in mountnfs(), but I wanted to detect errors before 1129 * doing the sockargs() call because sockargs() allocates an mbuf and 1130 * an error after that means that I have to release the mbuf. 1131 */ 1132 /* ARGSUSED */ 1133 static int 1134 nfs_cmount(struct mntarg *ma, void *data, int flags) 1135 { 1136 int error; 1137 struct nfs_args args; 1138 1139 error = copyin(data, &args, sizeof (struct nfs_args)); 1140 if (error) 1141 return error; 1142 1143 ma = mount_arg(ma, "nfs_args", &args, sizeof args); 1144 1145 error = kernel_mount(ma, flags); 1146 return (error); 1147 } 1148 1149 /* 1150 * Common code for mount and mountroot 1151 */ 1152 static int 1153 mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam, 1154 char *hst, u_char *krbname, int krbnamelen, u_char *dirpath, int dirlen, 1155 u_char *srvkrbname, int srvkrbnamelen, struct vnode **vpp, 1156 struct ucred *cred, struct thread *td, int negnametimeo) 1157 { 1158 struct nfsmount *nmp; 1159 struct nfsnode *np; 1160 int error, trycnt, ret; 1161 struct nfsvattr nfsva; 1162 static u_int64_t clval = 0; 1163 1164 if (mp->mnt_flag & MNT_UPDATE) { 1165 nmp = VFSTONFS(mp); 1166 printf("%s: MNT_UPDATE is no longer handled here\n", __func__); 1167 FREE(nam, M_SONAME); 1168 return (0); 1169 } else { 1170 MALLOC(nmp, struct nfsmount *, sizeof (struct nfsmount) + 1171 krbnamelen + dirlen + srvkrbnamelen + 2, 1172 M_NEWNFSMNT, M_WAITOK | M_ZERO); 1173 TAILQ_INIT(&nmp->nm_bufq); 1174 if (clval == 0) 1175 clval = (u_int64_t)nfsboottime.tv_sec; 1176 nmp->nm_clval = clval++; 1177 nmp->nm_krbnamelen = krbnamelen; 1178 nmp->nm_dirpathlen = dirlen; 1179 nmp->nm_srvkrbnamelen = srvkrbnamelen; 1180 if (td->td_ucred->cr_uid != (uid_t)0) { 1181 /* 1182 * nm_uid is used to get KerberosV credentials for 1183 * the nfsv4 state handling operations if there is 1184 * no host based principal set. Use the uid of 1185 * this user if not root, since they are doing the 1186 * mount. I don't think setting this for root will 1187 * work, since root normally does not have user 1188 * credentials in a credentials cache. 1189 */ 1190 nmp->nm_uid = td->td_ucred->cr_uid; 1191 } else { 1192 /* 1193 * Just set to -1, so it won't be used. 1194 */ 1195 nmp->nm_uid = (uid_t)-1; 1196 } 1197 1198 /* Copy and null terminate all the names */ 1199 if (nmp->nm_krbnamelen > 0) { 1200 bcopy(krbname, nmp->nm_krbname, nmp->nm_krbnamelen); 1201 nmp->nm_name[nmp->nm_krbnamelen] = '\0'; 1202 } 1203 if (nmp->nm_dirpathlen > 0) { 1204 bcopy(dirpath, NFSMNT_DIRPATH(nmp), 1205 nmp->nm_dirpathlen); 1206 nmp->nm_name[nmp->nm_krbnamelen + nmp->nm_dirpathlen 1207 + 1] = '\0'; 1208 } 1209 if (nmp->nm_srvkrbnamelen > 0) { 1210 bcopy(srvkrbname, NFSMNT_SRVKRBNAME(nmp), 1211 nmp->nm_srvkrbnamelen); 1212 nmp->nm_name[nmp->nm_krbnamelen + nmp->nm_dirpathlen 1213 + nmp->nm_srvkrbnamelen + 2] = '\0'; 1214 } 1215 nmp->nm_sockreq.nr_cred = crhold(cred); 1216 mtx_init(&nmp->nm_sockreq.nr_mtx, "nfssock", NULL, MTX_DEF); 1217 mp->mnt_data = nmp; 1218 nmp->nm_getinfo = nfs_getnlminfo; 1219 nmp->nm_vinvalbuf = ncl_vinvalbuf; 1220 } 1221 vfs_getnewfsid(mp); 1222 nmp->nm_mountp = mp; 1223 mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF | MTX_DUPOK); 1224 1225 /* 1226 * Since nfs_decode_args() might optionally set them, these need to 1227 * set to defaults before the call, so that the optional settings 1228 * aren't overwritten. 1229 */ 1230 nmp->nm_negnametimeo = negnametimeo; 1231 nmp->nm_timeo = NFS_TIMEO; 1232 nmp->nm_retry = NFS_RETRANS; 1233 nmp->nm_readahead = NFS_DEFRAHEAD; 1234 if (desiredvnodes >= 11000) 1235 nmp->nm_wcommitsize = hibufspace / (desiredvnodes / 1000); 1236 else 1237 nmp->nm_wcommitsize = hibufspace / 10; 1238 1239 nfs_decode_args(mp, nmp, argp, hst, cred, td); 1240 1241 /* 1242 * V2 can only handle 32 bit filesizes. A 4GB-1 limit may be too 1243 * high, depending on whether we end up with negative offsets in 1244 * the client or server somewhere. 2GB-1 may be safer. 1245 * 1246 * For V3, ncl_fsinfo will adjust this as necessary. Assume maximum 1247 * that we can handle until we find out otherwise. 1248 */ 1249 if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0) 1250 nmp->nm_maxfilesize = 0xffffffffLL; 1251 else 1252 nmp->nm_maxfilesize = OFF_MAX; 1253 1254 if ((argp->flags & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0) { 1255 nmp->nm_wsize = NFS_WSIZE; 1256 nmp->nm_rsize = NFS_RSIZE; 1257 nmp->nm_readdirsize = NFS_READDIRSIZE; 1258 } 1259 nmp->nm_numgrps = NFS_MAXGRPS; 1260 nmp->nm_tprintf_delay = nfs_tprintf_delay; 1261 if (nmp->nm_tprintf_delay < 0) 1262 nmp->nm_tprintf_delay = 0; 1263 nmp->nm_tprintf_initial_delay = nfs_tprintf_initial_delay; 1264 if (nmp->nm_tprintf_initial_delay < 0) 1265 nmp->nm_tprintf_initial_delay = 0; 1266 nmp->nm_fhsize = argp->fhsize; 1267 if (nmp->nm_fhsize > 0) 1268 bcopy((caddr_t)argp->fh, (caddr_t)nmp->nm_fh, argp->fhsize); 1269 bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN); 1270 nmp->nm_nam = nam; 1271 /* Set up the sockets and per-host congestion */ 1272 nmp->nm_sotype = argp->sotype; 1273 nmp->nm_soproto = argp->proto; 1274 nmp->nm_sockreq.nr_prog = NFS_PROG; 1275 if ((argp->flags & NFSMNT_NFSV4)) 1276 nmp->nm_sockreq.nr_vers = NFS_VER4; 1277 else if ((argp->flags & NFSMNT_NFSV3)) 1278 nmp->nm_sockreq.nr_vers = NFS_VER3; 1279 else 1280 nmp->nm_sockreq.nr_vers = NFS_VER2; 1281 1282 1283 if ((error = newnfs_connect(nmp, &nmp->nm_sockreq, cred, td, 0))) 1284 goto bad; 1285 1286 /* 1287 * A reference count is needed on the nfsnode representing the 1288 * remote root. If this object is not persistent, then backward 1289 * traversals of the mount point (i.e. "..") will not work if 1290 * the nfsnode gets flushed out of the cache. Ufs does not have 1291 * this problem, because one can identify root inodes by their 1292 * number == ROOTINO (2). 1293 */ 1294 if (nmp->nm_fhsize == 0 && (nmp->nm_flag & NFSMNT_NFSV4) && 1295 nmp->nm_dirpathlen > 0) { 1296 /* 1297 * If the fhsize on the mount point == 0 for V4, the mount 1298 * path needs to be looked up. 1299 */ 1300 trycnt = 3; 1301 do { 1302 error = nfsrpc_getdirpath(nmp, NFSMNT_DIRPATH(nmp), 1303 cred, td); 1304 if (error) 1305 (void) nfs_catnap(PZERO, error, "nfsgetdirp"); 1306 } while (error && --trycnt > 0); 1307 if (error) { 1308 error = nfscl_maperr(td, error, (uid_t)0, (gid_t)0); 1309 goto bad; 1310 } 1311 } 1312 if (nmp->nm_fhsize > 0) { 1313 /* 1314 * Set f_iosize to NFS_DIRBLKSIZ so that bo_bsize gets set 1315 * non-zero for the root vnode. f_iosize will be set correctly 1316 * by nfs_statfs() before any I/O occurs. 1317 */ 1318 mp->mnt_stat.f_iosize = NFS_DIRBLKSIZ; 1319 error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np, 1320 LK_EXCLUSIVE); 1321 if (error) 1322 goto bad; 1323 *vpp = NFSTOV(np); 1324 1325 /* 1326 * Get file attributes and transfer parameters for the 1327 * mountpoint. This has the side effect of filling in 1328 * (*vpp)->v_type with the correct value. 1329 */ 1330 ret = nfsrpc_getattrnovp(nmp, nmp->nm_fh, nmp->nm_fhsize, 1, 1331 cred, td, &nfsva, NULL); 1332 if (ret) { 1333 /* 1334 * Just set default values to get things going. 1335 */ 1336 NFSBZERO((caddr_t)&nfsva, sizeof (struct nfsvattr)); 1337 nfsva.na_vattr.va_type = VDIR; 1338 nfsva.na_vattr.va_mode = 0777; 1339 nfsva.na_vattr.va_nlink = 100; 1340 nfsva.na_vattr.va_uid = (uid_t)0; 1341 nfsva.na_vattr.va_gid = (gid_t)0; 1342 nfsva.na_vattr.va_fileid = 2; 1343 nfsva.na_vattr.va_gen = 1; 1344 nfsva.na_vattr.va_blocksize = NFS_FABLKSIZE; 1345 nfsva.na_vattr.va_size = 512 * 1024; 1346 } 1347 (void) nfscl_loadattrcache(vpp, &nfsva, NULL, NULL, 0, 1); 1348 if (argp->flags & NFSMNT_NFSV3) 1349 ncl_fsinfo(nmp, *vpp, cred, td); 1350 1351 /* Mark if the mount point supports NFSv4 ACLs. */ 1352 if ((argp->flags & NFSMNT_NFSV4) != 0 && nfsrv_useacl != 0 && 1353 ret == 0 && 1354 NFSISSET_ATTRBIT(&nfsva.na_suppattr, NFSATTRBIT_ACL)) { 1355 MNT_ILOCK(mp); 1356 mp->mnt_flag |= MNT_NFS4ACLS; 1357 MNT_IUNLOCK(mp); 1358 } 1359 1360 /* 1361 * Lose the lock but keep the ref. 1362 */ 1363 NFSVOPUNLOCK(*vpp, 0); 1364 return (0); 1365 } 1366 error = EIO; 1367 1368 bad: 1369 newnfs_disconnect(&nmp->nm_sockreq); 1370 crfree(nmp->nm_sockreq.nr_cred); 1371 mtx_destroy(&nmp->nm_sockreq.nr_mtx); 1372 mtx_destroy(&nmp->nm_mtx); 1373 FREE(nmp, M_NEWNFSMNT); 1374 FREE(nam, M_SONAME); 1375 return (error); 1376 } 1377 1378 /* 1379 * unmount system call 1380 */ 1381 static int 1382 nfs_unmount(struct mount *mp, int mntflags) 1383 { 1384 struct thread *td; 1385 struct nfsmount *nmp; 1386 int error, flags = 0, trycnt = 0; 1387 1388 td = curthread; 1389 1390 if (mntflags & MNT_FORCE) 1391 flags |= FORCECLOSE; 1392 nmp = VFSTONFS(mp); 1393 /* 1394 * Goes something like this.. 1395 * - Call vflush() to clear out vnodes for this filesystem 1396 * - Close the socket 1397 * - Free up the data structures 1398 */ 1399 /* In the forced case, cancel any outstanding requests. */ 1400 if (mntflags & MNT_FORCE) { 1401 error = newnfs_nmcancelreqs(nmp); 1402 if (error) 1403 goto out; 1404 /* For a forced close, get rid of the renew thread now */ 1405 nfscl_umount(nmp, td); 1406 } 1407 /* We hold 1 extra ref on the root vnode; see comment in mountnfs(). */ 1408 do { 1409 error = vflush(mp, 1, flags, td); 1410 if ((mntflags & MNT_FORCE) && error != 0 && ++trycnt < 30) 1411 (void) nfs_catnap(PSOCK, error, "newndm"); 1412 } while ((mntflags & MNT_FORCE) && error != 0 && trycnt < 30); 1413 if (error) 1414 goto out; 1415 1416 /* 1417 * We are now committed to the unmount. 1418 */ 1419 if ((mntflags & MNT_FORCE) == 0) 1420 nfscl_umount(nmp, td); 1421 newnfs_disconnect(&nmp->nm_sockreq); 1422 crfree(nmp->nm_sockreq.nr_cred); 1423 FREE(nmp->nm_nam, M_SONAME); 1424 1425 mtx_destroy(&nmp->nm_sockreq.nr_mtx); 1426 mtx_destroy(&nmp->nm_mtx); 1427 FREE(nmp, M_NEWNFSMNT); 1428 out: 1429 return (error); 1430 } 1431 1432 /* 1433 * Return root of a filesystem 1434 */ 1435 static int 1436 nfs_root(struct mount *mp, int flags, struct vnode **vpp) 1437 { 1438 struct vnode *vp; 1439 struct nfsmount *nmp; 1440 struct nfsnode *np; 1441 int error; 1442 1443 nmp = VFSTONFS(mp); 1444 error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np, flags); 1445 if (error) 1446 return error; 1447 vp = NFSTOV(np); 1448 /* 1449 * Get transfer parameters and attributes for root vnode once. 1450 */ 1451 mtx_lock(&nmp->nm_mtx); 1452 if (NFSHASNFSV3(nmp) && !NFSHASGOTFSINFO(nmp)) { 1453 mtx_unlock(&nmp->nm_mtx); 1454 ncl_fsinfo(nmp, vp, curthread->td_ucred, curthread); 1455 } else 1456 mtx_unlock(&nmp->nm_mtx); 1457 if (vp->v_type == VNON) 1458 vp->v_type = VDIR; 1459 vp->v_vflag |= VV_ROOT; 1460 *vpp = vp; 1461 return (0); 1462 } 1463 1464 /* 1465 * Flush out the buffer cache 1466 */ 1467 /* ARGSUSED */ 1468 static int 1469 nfs_sync(struct mount *mp, int waitfor) 1470 { 1471 struct vnode *vp, *mvp; 1472 struct thread *td; 1473 int error, allerror = 0; 1474 1475 td = curthread; 1476 1477 MNT_ILOCK(mp); 1478 /* 1479 * If a forced dismount is in progress, return from here so that 1480 * the umount(2) syscall doesn't get stuck in VFS_SYNC() before 1481 * calling VFS_UNMOUNT(). 1482 */ 1483 if ((mp->mnt_kern_flag & MNTK_UNMOUNTF) != 0) { 1484 MNT_IUNLOCK(mp); 1485 return (EBADF); 1486 } 1487 1488 /* 1489 * Force stale buffer cache information to be flushed. 1490 */ 1491 loop: 1492 MNT_VNODE_FOREACH(vp, mp, mvp) { 1493 VI_LOCK(vp); 1494 MNT_IUNLOCK(mp); 1495 /* XXX Racy bv_cnt check. */ 1496 if (NFSVOPISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 || 1497 waitfor == MNT_LAZY) { 1498 VI_UNLOCK(vp); 1499 MNT_ILOCK(mp); 1500 continue; 1501 } 1502 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) { 1503 MNT_ILOCK(mp); 1504 MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp); 1505 goto loop; 1506 } 1507 error = VOP_FSYNC(vp, waitfor, td); 1508 if (error) 1509 allerror = error; 1510 NFSVOPUNLOCK(vp, 0); 1511 vrele(vp); 1512 1513 MNT_ILOCK(mp); 1514 } 1515 MNT_IUNLOCK(mp); 1516 return (allerror); 1517 } 1518 1519 static int 1520 nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req) 1521 { 1522 struct nfsmount *nmp = VFSTONFS(mp); 1523 struct vfsquery vq; 1524 int error; 1525 1526 bzero(&vq, sizeof(vq)); 1527 switch (op) { 1528 #if 0 1529 case VFS_CTL_NOLOCKS: 1530 val = (nmp->nm_flag & NFSMNT_NOLOCKS) ? 1 : 0; 1531 if (req->oldptr != NULL) { 1532 error = SYSCTL_OUT(req, &val, sizeof(val)); 1533 if (error) 1534 return (error); 1535 } 1536 if (req->newptr != NULL) { 1537 error = SYSCTL_IN(req, &val, sizeof(val)); 1538 if (error) 1539 return (error); 1540 if (val) 1541 nmp->nm_flag |= NFSMNT_NOLOCKS; 1542 else 1543 nmp->nm_flag &= ~NFSMNT_NOLOCKS; 1544 } 1545 break; 1546 #endif 1547 case VFS_CTL_QUERY: 1548 mtx_lock(&nmp->nm_mtx); 1549 if (nmp->nm_state & NFSSTA_TIMEO) 1550 vq.vq_flags |= VQ_NOTRESP; 1551 mtx_unlock(&nmp->nm_mtx); 1552 #if 0 1553 if (!(nmp->nm_flag & NFSMNT_NOLOCKS) && 1554 (nmp->nm_state & NFSSTA_LOCKTIMEO)) 1555 vq.vq_flags |= VQ_NOTRESPLOCK; 1556 #endif 1557 error = SYSCTL_OUT(req, &vq, sizeof(vq)); 1558 break; 1559 case VFS_CTL_TIMEO: 1560 if (req->oldptr != NULL) { 1561 error = SYSCTL_OUT(req, &nmp->nm_tprintf_initial_delay, 1562 sizeof(nmp->nm_tprintf_initial_delay)); 1563 if (error) 1564 return (error); 1565 } 1566 if (req->newptr != NULL) { 1567 error = vfs_suser(mp, req->td); 1568 if (error) 1569 return (error); 1570 error = SYSCTL_IN(req, &nmp->nm_tprintf_initial_delay, 1571 sizeof(nmp->nm_tprintf_initial_delay)); 1572 if (error) 1573 return (error); 1574 if (nmp->nm_tprintf_initial_delay < 0) 1575 nmp->nm_tprintf_initial_delay = 0; 1576 } 1577 break; 1578 default: 1579 return (ENOTSUP); 1580 } 1581 return (0); 1582 } 1583 1584 /* 1585 * Extract the information needed by the nlm from the nfs vnode. 1586 */ 1587 static void 1588 nfs_getnlminfo(struct vnode *vp, uint8_t *fhp, size_t *fhlenp, 1589 struct sockaddr_storage *sp, int *is_v3p, off_t *sizep, 1590 struct timeval *timeop) 1591 { 1592 struct nfsmount *nmp; 1593 struct nfsnode *np = VTONFS(vp); 1594 1595 nmp = VFSTONFS(vp->v_mount); 1596 if (fhlenp != NULL) 1597 *fhlenp = (size_t)np->n_fhp->nfh_len; 1598 if (fhp != NULL) 1599 bcopy(np->n_fhp->nfh_fh, fhp, np->n_fhp->nfh_len); 1600 if (sp != NULL) 1601 bcopy(nmp->nm_nam, sp, min(nmp->nm_nam->sa_len, sizeof(*sp))); 1602 if (is_v3p != NULL) 1603 *is_v3p = NFS_ISV3(vp); 1604 if (sizep != NULL) 1605 *sizep = np->n_size; 1606 if (timeop != NULL) { 1607 timeop->tv_sec = nmp->nm_timeo / NFS_HZ; 1608 timeop->tv_usec = (nmp->nm_timeo % NFS_HZ) * (1000000 / NFS_HZ); 1609 } 1610 } 1611 1612