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