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