1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. 23 * Copyright (c) 2017 by Delphix. All rights reserved. 24 */ 25 26 #include <sys/param.h> 27 #include <sys/systm.h> 28 #include <sys/errno.h> 29 #include <sys/proc.h> 30 #include <sys/vnode.h> 31 #include <sys/vfs.h> 32 #include <sys/vfs_opreg.h> 33 #include <sys/uio.h> 34 #include <sys/cred.h> 35 #include <sys/pathname.h> 36 #include <sys/dirent.h> 37 #include <sys/debug.h> 38 #include <sys/sysmacros.h> 39 #include <sys/tiuser.h> 40 #include <sys/cmn_err.h> 41 #include <sys/stat.h> 42 #include <sys/mode.h> 43 #include <sys/policy.h> 44 #include <rpc/types.h> 45 #include <rpc/auth.h> 46 #include <rpc/clnt.h> 47 #include <sys/fs/autofs.h> 48 #include <rpcsvc/autofs_prot.h> 49 #include <fs/fs_subr.h> 50 51 /* 52 * Vnode ops for autofs 53 */ 54 static int auto_open(vnode_t **, int, cred_t *, caller_context_t *); 55 static int auto_close(vnode_t *, int, int, offset_t, cred_t *, 56 caller_context_t *); 57 static int auto_getattr(vnode_t *, vattr_t *, int, cred_t *, 58 caller_context_t *); 59 static int auto_setattr(vnode_t *, vattr_t *, int, cred_t *, 60 caller_context_t *); 61 static int auto_access(vnode_t *, int, int, cred_t *, caller_context_t *); 62 static int auto_lookup(vnode_t *, char *, vnode_t **, 63 pathname_t *, int, vnode_t *, cred_t *, caller_context_t *, int *, 64 pathname_t *); 65 static int auto_create(vnode_t *, char *, vattr_t *, vcexcl_t, 66 int, vnode_t **, cred_t *, int, caller_context_t *, vsecattr_t *); 67 static int auto_remove(vnode_t *, char *, cred_t *, caller_context_t *, int); 68 static int auto_link(vnode_t *, vnode_t *, char *, cred_t *, 69 caller_context_t *, int); 70 static int auto_rename(vnode_t *, char *, vnode_t *, char *, cred_t *, 71 caller_context_t *, int); 72 static int auto_mkdir(vnode_t *, char *, vattr_t *, vnode_t **, cred_t *, 73 caller_context_t *, int, vsecattr_t *); 74 static int auto_rmdir(vnode_t *, char *, vnode_t *, cred_t *, 75 caller_context_t *, int); 76 static int auto_readdir(vnode_t *, uio_t *, cred_t *, int *, 77 caller_context_t *, int); 78 static int auto_symlink(vnode_t *, char *, vattr_t *, char *, cred_t *, 79 caller_context_t *, int); 80 static int auto_readlink(vnode_t *, struct uio *, cred_t *, 81 caller_context_t *); 82 static int auto_fsync(vnode_t *, int, cred_t *, caller_context_t *); 83 static void auto_inactive(vnode_t *, cred_t *, caller_context_t *); 84 static int auto_rwlock(vnode_t *, int, caller_context_t *); 85 static void auto_rwunlock(vnode_t *vp, int, caller_context_t *); 86 static int auto_seek(vnode_t *vp, offset_t, offset_t *, caller_context_t *); 87 88 static int auto_trigger_mount(vnode_t *, cred_t *, vnode_t **); 89 90 vnodeops_t *auto_vnodeops; 91 92 const fs_operation_def_t auto_vnodeops_template[] = { 93 VOPNAME_OPEN, { .vop_open = auto_open }, 94 VOPNAME_CLOSE, { .vop_close = auto_close }, 95 VOPNAME_GETATTR, { .vop_getattr = auto_getattr }, 96 VOPNAME_SETATTR, { .vop_setattr = auto_setattr }, 97 VOPNAME_ACCESS, { .vop_access = auto_access }, 98 VOPNAME_LOOKUP, { .vop_lookup = auto_lookup }, 99 VOPNAME_CREATE, { .vop_create = auto_create }, 100 VOPNAME_REMOVE, { .vop_remove = auto_remove }, 101 VOPNAME_LINK, { .vop_link = auto_link }, 102 VOPNAME_RENAME, { .vop_rename = auto_rename }, 103 VOPNAME_MKDIR, { .vop_mkdir = auto_mkdir }, 104 VOPNAME_RMDIR, { .vop_rmdir = auto_rmdir }, 105 VOPNAME_READDIR, { .vop_readdir = auto_readdir }, 106 VOPNAME_SYMLINK, { .vop_symlink = auto_symlink }, 107 VOPNAME_READLINK, { .vop_readlink = auto_readlink }, 108 VOPNAME_FSYNC, { .vop_fsync = auto_fsync }, 109 VOPNAME_INACTIVE, { .vop_inactive = auto_inactive }, 110 VOPNAME_RWLOCK, { .vop_rwlock = auto_rwlock }, 111 VOPNAME_RWUNLOCK, { .vop_rwunlock = auto_rwunlock }, 112 VOPNAME_SEEK, { .vop_seek = auto_seek }, 113 VOPNAME_FRLOCK, { .error = fs_error }, 114 VOPNAME_DISPOSE, { .error = fs_error }, 115 VOPNAME_SHRLOCK, { .error = fs_error }, 116 VOPNAME_VNEVENT, { .vop_vnevent = fs_vnevent_support }, 117 NULL, NULL 118 }; 119 120 121 122 /* ARGSUSED */ 123 static int 124 auto_open(vnode_t **vpp, int flag, cred_t *cred, caller_context_t *ct) 125 { 126 vnode_t *newvp; 127 int error; 128 129 AUTOFS_DPRINT((4, "auto_open: *vpp=%p\n", (void *)*vpp)); 130 131 error = auto_trigger_mount(*vpp, cred, &newvp); 132 if (error) 133 goto done; 134 135 if (newvp != NULL) { 136 /* 137 * Node is now mounted on. 138 */ 139 VN_RELE(*vpp); 140 *vpp = newvp; 141 error = VOP_ACCESS(*vpp, VREAD, 0, cred, ct); 142 if (!error) 143 error = VOP_OPEN(vpp, flag, cred, ct); 144 } 145 146 done: 147 AUTOFS_DPRINT((5, "auto_open: *vpp=%p error=%d\n", (void *)*vpp, 148 error)); 149 return (error); 150 } 151 152 /* ARGSUSED */ 153 static int 154 auto_close( 155 vnode_t *vp, 156 int flag, 157 int count, 158 offset_t offset, 159 cred_t *cred, 160 caller_context_t *ct) 161 { 162 return (0); 163 } 164 165 static int 166 auto_getattr( 167 vnode_t *vp, 168 vattr_t *vap, 169 int flags, 170 cred_t *cred, 171 caller_context_t *ct) 172 { 173 fnnode_t *fnp = vntofn(vp); 174 vnode_t *newvp; 175 vfs_t *vfsp; 176 int error; 177 178 AUTOFS_DPRINT((4, "auto_getattr vp %p\n", (void *)vp)); 179 180 if (flags & ATTR_TRIGGER) { 181 /* 182 * Pre-trigger the mount 183 */ 184 error = auto_trigger_mount(vp, cred, &newvp); 185 if (error) 186 return (error); 187 188 if (newvp == NULL) 189 goto defattr; 190 191 if (error = vn_vfsrlock_wait(vp)) { 192 VN_RELE(newvp); 193 return (error); 194 } 195 196 vfsp = newvp->v_vfsp; 197 VN_RELE(newvp); 198 } else { 199 /* 200 * Recursive auto_getattr/mount; go to the vfsp == NULL 201 * case. 202 */ 203 if (vn_vfswlock_held(vp)) 204 goto defattr; 205 206 if (error = vn_vfsrlock_wait(vp)) 207 return (error); 208 209 vfsp = vn_mountedvfs(vp); 210 } 211 212 if (vfsp != NULL) { 213 /* 214 * Node is mounted on. 215 */ 216 error = VFS_ROOT(vfsp, &newvp); 217 vn_vfsunlock(vp); 218 if (error) 219 return (error); 220 mutex_enter(&fnp->fn_lock); 221 if (fnp->fn_seen == newvp && fnp->fn_thread == curthread) { 222 /* 223 * Recursive auto_getattr(); just release newvp and drop 224 * into the vfsp == NULL case. 225 */ 226 mutex_exit(&fnp->fn_lock); 227 VN_RELE(newvp); 228 } else { 229 while (fnp->fn_thread && fnp->fn_thread != curthread) { 230 fnp->fn_flags |= MF_ATTR_WAIT; 231 cv_wait(&fnp->fn_cv_mount, &fnp->fn_lock); 232 } 233 fnp->fn_thread = curthread; 234 fnp->fn_seen = newvp; 235 mutex_exit(&fnp->fn_lock); 236 error = VOP_GETATTR(newvp, vap, flags, cred, ct); 237 VN_RELE(newvp); 238 mutex_enter(&fnp->fn_lock); 239 fnp->fn_seen = 0; 240 fnp->fn_thread = 0; 241 if (fnp->fn_flags & MF_ATTR_WAIT) { 242 fnp->fn_flags &= ~MF_ATTR_WAIT; 243 cv_broadcast(&fnp->fn_cv_mount); 244 } 245 mutex_exit(&fnp->fn_lock); 246 return (error); 247 } 248 } else { 249 vn_vfsunlock(vp); 250 } 251 252 defattr: 253 ASSERT(vp->v_type == VDIR || vp->v_type == VLNK); 254 vap->va_uid = 0; 255 vap->va_gid = 0; 256 vap->va_nlink = fnp->fn_linkcnt; 257 vap->va_nodeid = (u_longlong_t)fnp->fn_nodeid; 258 vap->va_size = fnp->fn_size; 259 vap->va_atime = fnp->fn_atime; 260 vap->va_mtime = fnp->fn_mtime; 261 vap->va_ctime = fnp->fn_ctime; 262 vap->va_type = vp->v_type; 263 vap->va_mode = fnp->fn_mode; 264 vap->va_fsid = vp->v_vfsp->vfs_dev; 265 vap->va_rdev = 0; 266 vap->va_blksize = MAXBSIZE; 267 vap->va_nblocks = (fsblkcnt64_t)btod(vap->va_size); 268 vap->va_seq = 0; 269 270 return (0); 271 } 272 273 /*ARGSUSED4*/ 274 static int 275 auto_setattr( 276 vnode_t *vp, 277 struct vattr *vap, 278 int flags, 279 cred_t *cred, 280 caller_context_t *ct) 281 { 282 vnode_t *newvp; 283 int error; 284 285 AUTOFS_DPRINT((4, "auto_setattr vp %p\n", (void *)vp)); 286 287 if (error = auto_trigger_mount(vp, cred, &newvp)) 288 goto done; 289 290 if (newvp != NULL) { 291 /* 292 * Node is mounted on. 293 */ 294 if (vn_is_readonly(newvp)) 295 error = EROFS; 296 else 297 error = VOP_SETATTR(newvp, vap, flags, cred, ct); 298 VN_RELE(newvp); 299 } else 300 error = ENOSYS; 301 302 done: 303 AUTOFS_DPRINT((5, "auto_setattr: error=%d\n", error)); 304 return (error); 305 } 306 307 /* ARGSUSED */ 308 static int 309 auto_access( 310 vnode_t *vp, 311 int mode, 312 int flags, 313 cred_t *cred, 314 caller_context_t *ct) 315 { 316 fnnode_t *fnp = vntofn(vp); 317 vnode_t *newvp; 318 int error; 319 320 AUTOFS_DPRINT((4, "auto_access: vp=%p\n", (void *)vp)); 321 322 if (error = auto_trigger_mount(vp, cred, &newvp)) 323 goto done; 324 325 if (newvp != NULL) { 326 /* 327 * Node is mounted on. 328 */ 329 error = VOP_ACCESS(newvp, mode, 0, cred, ct); 330 VN_RELE(newvp); 331 } else { 332 int shift = 0; 333 334 /* 335 * really interested in the autofs node, check the 336 * access on it 337 */ 338 ASSERT(error == 0); 339 if (crgetuid(cred) != fnp->fn_uid) { 340 shift += 3; 341 if (groupmember(fnp->fn_gid, cred) == 0) 342 shift += 3; 343 } 344 error = secpolicy_vnode_access2(cred, vp, fnp->fn_uid, 345 fnp->fn_mode << shift, mode); 346 } 347 348 done: 349 AUTOFS_DPRINT((5, "auto_access: error=%d\n", error)); 350 return (error); 351 } 352 353 static int 354 auto_lookup( 355 vnode_t *dvp, 356 char *nm, 357 vnode_t **vpp, 358 pathname_t *pnp, 359 int flags, 360 vnode_t *rdir, 361 cred_t *cred, 362 caller_context_t *ct, 363 int *direntflags, 364 pathname_t *realpnp) 365 { 366 int error = 0; 367 vnode_t *newvp = NULL; 368 vfs_t *vfsp; 369 fninfo_t *dfnip; 370 fnnode_t *dfnp = NULL; 371 fnnode_t *fnp = NULL; 372 char *searchnm; 373 int operation; /* either AUTOFS_LOOKUP or AUTOFS_MOUNT */ 374 375 dfnip = vfstofni(dvp->v_vfsp); 376 AUTOFS_DPRINT((3, "auto_lookup: dvp=%p (%s) name=%s\n", 377 (void *)dvp, dfnip->fi_map, nm)); 378 379 if (nm[0] == 0) { 380 VN_HOLD(dvp); 381 *vpp = dvp; 382 return (0); 383 } 384 385 if (error = VOP_ACCESS(dvp, VEXEC, 0, cred, ct)) 386 return (error); 387 388 if (nm[0] == '.' && nm[1] == 0) { 389 VN_HOLD(dvp); 390 *vpp = dvp; 391 return (0); 392 } 393 394 if (nm[0] == '.' && nm[1] == '.' && nm[2] == 0) { 395 fnnode_t *pdfnp; 396 397 pdfnp = (vntofn(dvp))->fn_parent; 398 ASSERT(pdfnp != NULL); 399 400 /* 401 * Since it is legitimate to have the VROOT flag set for the 402 * subdirectories of the indirect map in autofs filesystem, 403 * rootfnnodep is checked against fnnode of dvp instead of 404 * just checking whether VROOT flag is set in dvp 405 */ 406 407 if (pdfnp == pdfnp->fn_globals->fng_rootfnnodep) { 408 vnode_t *vp; 409 410 vfs_rlock_wait(dvp->v_vfsp); 411 if (dvp->v_vfsp->vfs_flag & VFS_UNMOUNTED) { 412 vfs_unlock(dvp->v_vfsp); 413 return (EIO); 414 } 415 vp = dvp->v_vfsp->vfs_vnodecovered; 416 VN_HOLD(vp); 417 vfs_unlock(dvp->v_vfsp); 418 error = VOP_LOOKUP(vp, nm, vpp, pnp, flags, rdir, cred, 419 ct, direntflags, realpnp); 420 VN_RELE(vp); 421 return (error); 422 } else { 423 *vpp = fntovn(pdfnp); 424 VN_HOLD(*vpp); 425 return (0); 426 } 427 } 428 429 top: 430 dfnp = vntofn(dvp); 431 searchnm = nm; 432 operation = 0; 433 434 ASSERT(vn_matchops(dvp, auto_vnodeops)); 435 436 AUTOFS_DPRINT((3, "auto_lookup: dvp=%p dfnp=%p\n", (void *)dvp, 437 (void *)dfnp)); 438 439 /* 440 * If a lookup or mount of this node is in progress, wait for it 441 * to finish, and return whatever result it got. 442 */ 443 mutex_enter(&dfnp->fn_lock); 444 if (dfnp->fn_flags & (MF_LOOKUP | MF_INPROG)) { 445 mutex_exit(&dfnp->fn_lock); 446 error = auto_wait4mount(dfnp); 447 if (error == AUTOFS_SHUTDOWN) 448 error = ENOENT; 449 if (error == EAGAIN) 450 goto top; 451 if (error) 452 return (error); 453 } else 454 mutex_exit(&dfnp->fn_lock); 455 456 457 error = vn_vfsrlock_wait(dvp); 458 if (error) 459 return (error); 460 vfsp = vn_mountedvfs(dvp); 461 if (vfsp != NULL) { 462 error = VFS_ROOT(vfsp, &newvp); 463 vn_vfsunlock(dvp); 464 if (!error) { 465 error = VOP_LOOKUP(newvp, nm, vpp, pnp, 466 flags, rdir, cred, ct, direntflags, realpnp); 467 VN_RELE(newvp); 468 } 469 return (error); 470 } 471 vn_vfsunlock(dvp); 472 473 rw_enter(&dfnp->fn_rwlock, RW_READER); 474 error = auto_search(dfnp, nm, &fnp, cred); 475 if (error) { 476 if (dfnip->fi_flags & MF_DIRECT) { 477 /* 478 * direct map. 479 */ 480 if (dfnp->fn_dirents) { 481 /* 482 * Mount previously triggered. 483 * 'nm' not found 484 */ 485 error = ENOENT; 486 } else { 487 /* 488 * I need to contact the daemon to trigger 489 * the mount. 'dfnp' will be the mountpoint. 490 */ 491 operation = AUTOFS_MOUNT; 492 VN_HOLD(fntovn(dfnp)); 493 fnp = dfnp; 494 error = 0; 495 } 496 } else if (dvp == dfnip->fi_rootvp) { 497 /* 498 * 'dfnp' is the root of the indirect AUTOFS. 499 */ 500 if (rw_tryupgrade(&dfnp->fn_rwlock) == 0) { 501 /* 502 * Could not acquire writer lock, release 503 * reader, and wait until available. We 504 * need to search for 'nm' again, since we 505 * had to release the lock before reacquiring 506 * it. 507 */ 508 rw_exit(&dfnp->fn_rwlock); 509 rw_enter(&dfnp->fn_rwlock, RW_WRITER); 510 error = auto_search(dfnp, nm, &fnp, cred); 511 } 512 513 ASSERT(RW_WRITE_HELD(&dfnp->fn_rwlock)); 514 if (error) { 515 /* 516 * create node being looked-up and request 517 * mount on it. 518 */ 519 error = auto_enter(dfnp, nm, &fnp, kcred); 520 if (!error) 521 operation = AUTOFS_LOOKUP; 522 } 523 } else if ((dfnp->fn_dirents == NULL) && 524 ((dvp->v_flag & VROOT) == 0) && 525 ((fntovn(dfnp->fn_parent))->v_flag & VROOT)) { 526 /* 527 * dfnp is the actual 'mountpoint' of indirect map, 528 * it is the equivalent of a direct mount, 529 * ie, /home/'user1' 530 */ 531 operation = AUTOFS_MOUNT; 532 VN_HOLD(fntovn(dfnp)); 533 fnp = dfnp; 534 error = 0; 535 searchnm = dfnp->fn_name; 536 } 537 } 538 539 if (error == EAGAIN) { 540 rw_exit(&dfnp->fn_rwlock); 541 goto top; 542 } 543 if (error) { 544 rw_exit(&dfnp->fn_rwlock); 545 return (error); 546 } 547 548 /* 549 * We now have the actual fnnode we're interested in. 550 * The 'MF_LOOKUP' indicates another thread is currently 551 * performing a daemon lookup of this node, therefore we 552 * wait for its completion. 553 * The 'MF_INPROG' indicates another thread is currently 554 * performing a daemon mount of this node, we wait for it 555 * to be done if we are performing a MOUNT. We don't 556 * wait for it if we are performing a LOOKUP. 557 * We can release the reader/writer lock as soon as we acquire 558 * the mutex, since the state of the lock can only change by 559 * first acquiring the mutex. 560 */ 561 mutex_enter(&fnp->fn_lock); 562 rw_exit(&dfnp->fn_rwlock); 563 if ((fnp->fn_flags & MF_LOOKUP) || 564 ((operation == AUTOFS_MOUNT) && (fnp->fn_flags & MF_INPROG))) { 565 mutex_exit(&fnp->fn_lock); 566 error = auto_wait4mount(fnp); 567 VN_RELE(fntovn(fnp)); 568 if (error == AUTOFS_SHUTDOWN) 569 error = ENOENT; 570 if (error && error != EAGAIN) 571 return (error); 572 goto top; 573 } 574 575 if (operation == 0) { 576 /* 577 * got the fnnode, check for any errors 578 * on the previous operation on that node. 579 */ 580 error = fnp->fn_error; 581 if ((error == EINTR) || (error == EAGAIN)) { 582 /* 583 * previous operation on this node was 584 * not completed, do a lookup now. 585 */ 586 operation = AUTOFS_LOOKUP; 587 } else { 588 /* 589 * previous operation completed. Return 590 * a pointer to the node only if there was 591 * no error. 592 */ 593 mutex_exit(&fnp->fn_lock); 594 if (!error) 595 *vpp = fntovn(fnp); 596 else 597 VN_RELE(fntovn(fnp)); 598 return (error); 599 } 600 } 601 602 /* 603 * Since I got to this point, it means I'm the one 604 * responsible for triggering the mount/look-up of this node. 605 */ 606 switch (operation) { 607 case AUTOFS_LOOKUP: 608 AUTOFS_BLOCK_OTHERS(fnp, MF_LOOKUP); 609 fnp->fn_error = 0; 610 mutex_exit(&fnp->fn_lock); 611 error = auto_lookup_aux(fnp, searchnm, cred); 612 if (!error) { 613 /* 614 * Return this vnode 615 */ 616 *vpp = fntovn(fnp); 617 } else { 618 /* 619 * release our reference to this vnode 620 * and return error 621 */ 622 VN_RELE(fntovn(fnp)); 623 } 624 break; 625 case AUTOFS_MOUNT: 626 AUTOFS_BLOCK_OTHERS(fnp, MF_INPROG); 627 fnp->fn_error = 0; 628 mutex_exit(&fnp->fn_lock); 629 /* 630 * auto_new_mount_thread fires up a new thread which 631 * calls automountd finishing up the work 632 */ 633 auto_new_mount_thread(fnp, searchnm, cred); 634 635 /* 636 * At this point, we are simply another thread 637 * waiting for the mount to complete 638 */ 639 error = auto_wait4mount(fnp); 640 if (error == AUTOFS_SHUTDOWN) 641 error = ENOENT; 642 643 /* 644 * now release our reference to this vnode 645 */ 646 VN_RELE(fntovn(fnp)); 647 if (!error) 648 goto top; 649 break; 650 default: 651 auto_log(dfnp->fn_globals->fng_verbose, 652 dfnp->fn_globals->fng_zoneid, CE_WARN, 653 "auto_lookup: unknown operation %d", 654 operation); 655 } 656 657 AUTOFS_DPRINT((5, "auto_lookup: name=%s *vpp=%p return=%d\n", 658 nm, (void *)*vpp, error)); 659 660 return (error); 661 } 662 663 static int 664 auto_create( 665 vnode_t *dvp, 666 char *nm, 667 vattr_t *va, 668 vcexcl_t excl, 669 int mode, 670 vnode_t **vpp, 671 cred_t *cred, 672 int flag, 673 caller_context_t *ct, 674 vsecattr_t *vsecp) 675 { 676 vnode_t *newvp; 677 int error; 678 679 AUTOFS_DPRINT((4, "auto_create dvp %p nm %s\n", (void *)dvp, nm)); 680 681 if (error = auto_trigger_mount(dvp, cred, &newvp)) 682 goto done; 683 684 if (newvp != NULL) { 685 /* 686 * Node is now mounted on. 687 */ 688 if (vn_is_readonly(newvp)) 689 error = EROFS; 690 else 691 error = VOP_CREATE(newvp, nm, va, excl, 692 mode, vpp, cred, flag, ct, vsecp); 693 VN_RELE(newvp); 694 } else 695 error = ENOSYS; 696 697 done: 698 AUTOFS_DPRINT((5, "auto_create: error=%d\n", error)); 699 return (error); 700 } 701 702 static int 703 auto_remove( 704 vnode_t *dvp, 705 char *nm, 706 cred_t *cred, 707 caller_context_t *ct, 708 int flags) 709 { 710 vnode_t *newvp; 711 int error; 712 713 AUTOFS_DPRINT((4, "auto_remove dvp %p nm %s\n", (void *)dvp, nm)); 714 715 if (error = auto_trigger_mount(dvp, cred, &newvp)) 716 goto done; 717 718 if (newvp != NULL) { 719 /* 720 * Node is now mounted on. 721 */ 722 if (vn_is_readonly(newvp)) 723 error = EROFS; 724 else 725 error = VOP_REMOVE(newvp, nm, cred, ct, flags); 726 VN_RELE(newvp); 727 } else 728 error = ENOSYS; 729 730 done: 731 AUTOFS_DPRINT((5, "auto_remove: error=%d\n", error)); 732 return (error); 733 } 734 735 static int 736 auto_link( 737 vnode_t *tdvp, 738 vnode_t *svp, 739 char *nm, 740 cred_t *cred, 741 caller_context_t *ct, 742 int flags) 743 { 744 vnode_t *newvp; 745 int error; 746 747 AUTOFS_DPRINT((4, "auto_link tdvp %p svp %p nm %s\n", (void *)tdvp, 748 (void *)svp, nm)); 749 750 if (error = auto_trigger_mount(tdvp, cred, &newvp)) 751 goto done; 752 753 if (newvp == NULL) { 754 /* 755 * an autonode can not be a link to another node 756 */ 757 error = ENOSYS; 758 goto done; 759 } 760 761 if (vn_is_readonly(newvp)) { 762 error = EROFS; 763 VN_RELE(newvp); 764 goto done; 765 } 766 767 if (vn_matchops(svp, auto_vnodeops)) { 768 /* 769 * source vp can't be an autonode 770 */ 771 error = ENOSYS; 772 VN_RELE(newvp); 773 goto done; 774 } 775 776 error = VOP_LINK(newvp, svp, nm, cred, ct, flags); 777 VN_RELE(newvp); 778 779 done: 780 AUTOFS_DPRINT((5, "auto_link error=%d\n", error)); 781 return (error); 782 } 783 784 static int 785 auto_rename( 786 vnode_t *odvp, 787 char *onm, 788 vnode_t *ndvp, 789 char *nnm, 790 cred_t *cr, 791 caller_context_t *ct, 792 int flags) 793 { 794 vnode_t *o_newvp, *n_newvp; 795 int error; 796 797 AUTOFS_DPRINT((4, "auto_rename odvp %p onm %s to ndvp %p nnm %s\n", 798 (void *)odvp, onm, (void *)ndvp, nnm)); 799 800 /* 801 * we know odvp is an autonode, otherwise this function 802 * could not have ever been called. 803 */ 804 ASSERT(vn_matchops(odvp, auto_vnodeops)); 805 806 if (error = auto_trigger_mount(odvp, cr, &o_newvp)) 807 goto done; 808 809 if (o_newvp == NULL) { 810 /* 811 * can't rename an autonode 812 */ 813 error = ENOSYS; 814 goto done; 815 } 816 817 if (vn_matchops(ndvp, auto_vnodeops)) { 818 /* 819 * directory is AUTOFS, need to trigger the 820 * mount of the real filesystem. 821 */ 822 if (error = auto_trigger_mount(ndvp, cr, &n_newvp)) { 823 VN_RELE(o_newvp); 824 goto done; 825 } 826 827 if (n_newvp == NULL) { 828 /* 829 * target can't be an autonode 830 */ 831 error = ENOSYS; 832 VN_RELE(o_newvp); 833 goto done; 834 } 835 } else { 836 /* 837 * destination directory mount had been 838 * triggered prior to the call to this function. 839 */ 840 n_newvp = ndvp; 841 } 842 843 ASSERT(!vn_matchops(n_newvp, auto_vnodeops)); 844 845 if (vn_is_readonly(n_newvp)) { 846 error = EROFS; 847 VN_RELE(o_newvp); 848 if (n_newvp != ndvp) 849 VN_RELE(n_newvp); 850 goto done; 851 } 852 853 error = VOP_RENAME(o_newvp, onm, n_newvp, nnm, cr, ct, flags); 854 VN_RELE(o_newvp); 855 if (n_newvp != ndvp) 856 VN_RELE(n_newvp); 857 858 done: 859 AUTOFS_DPRINT((5, "auto_rename error=%d\n", error)); 860 return (error); 861 } 862 863 static int 864 auto_mkdir( 865 vnode_t *dvp, 866 char *nm, 867 vattr_t *va, 868 vnode_t **vpp, 869 cred_t *cred, 870 caller_context_t *ct, 871 int flags, 872 vsecattr_t *vsecp) 873 { 874 vnode_t *newvp; 875 int error; 876 877 AUTOFS_DPRINT((4, "auto_mkdir dvp %p nm %s\n", (void *)dvp, nm)); 878 879 if (error = auto_trigger_mount(dvp, cred, &newvp)) 880 goto done; 881 882 if (newvp != NULL) { 883 /* 884 * Node is now mounted on. 885 */ 886 if (vn_is_readonly(newvp)) 887 error = EROFS; 888 else 889 error = VOP_MKDIR(newvp, nm, va, vpp, cred, ct, 890 flags, vsecp); 891 VN_RELE(newvp); 892 } else 893 error = ENOSYS; 894 895 done: 896 AUTOFS_DPRINT((5, "auto_mkdir: error=%d\n", error)); 897 return (error); 898 } 899 900 static int 901 auto_rmdir( 902 vnode_t *dvp, 903 char *nm, 904 vnode_t *cdir, 905 cred_t *cred, 906 caller_context_t *ct, 907 int flags) 908 { 909 vnode_t *newvp; 910 int error; 911 912 AUTOFS_DPRINT((4, "auto_rmdir: vp=%p nm=%s\n", (void *)dvp, nm)); 913 914 if (error = auto_trigger_mount(dvp, cred, &newvp)) 915 goto done; 916 917 if (newvp != NULL) { 918 /* 919 * Node is now mounted on. 920 */ 921 if (vn_is_readonly(newvp)) 922 error = EROFS; 923 else 924 error = VOP_RMDIR(newvp, nm, cdir, cred, ct, flags); 925 VN_RELE(newvp); 926 } else 927 error = ENOSYS; 928 929 done: 930 AUTOFS_DPRINT((5, "auto_rmdir: error=%d\n", error)); 931 return (error); 932 } 933 934 static int autofs_nobrowse = 0; 935 936 #ifdef nextdp 937 #undef nextdp 938 #endif 939 #define nextdp(dp) ((struct dirent64 *)((char *)(dp) + (dp)->d_reclen)) 940 941 /* ARGSUSED */ 942 static int 943 auto_readdir( 944 vnode_t *vp, 945 uio_t *uiop, 946 cred_t *cred, 947 int *eofp, 948 caller_context_t *ct, 949 int flags) 950 { 951 struct autofs_rddirargs rda; 952 autofs_rddirres rd; 953 fnnode_t *fnp = vntofn(vp); 954 fnnode_t *cfnp, *nfnp; 955 dirent64_t *dp; 956 ulong_t offset; 957 ulong_t outcount = 0, count = 0; 958 size_t namelen; 959 ulong_t alloc_count; 960 void *outbuf = NULL; 961 fninfo_t *fnip = vfstofni(vp->v_vfsp); 962 struct iovec *iovp; 963 int error = 0; 964 int reached_max = 0; 965 int myeof = 0; 966 int this_reclen; 967 struct autofs_globals *fngp = vntofn(fnip->fi_rootvp)->fn_globals; 968 969 AUTOFS_DPRINT((4, "auto_readdir vp=%p offset=%lld\n", 970 (void *)vp, uiop->uio_loffset)); 971 972 if (eofp != NULL) 973 *eofp = 0; 974 975 if (uiop->uio_iovcnt != 1) 976 return (EINVAL); 977 978 iovp = uiop->uio_iov; 979 alloc_count = iovp->iov_len; 980 981 gethrestime(&fnp->fn_atime); 982 fnp->fn_ref_time = fnp->fn_atime.tv_sec; 983 984 dp = outbuf = kmem_zalloc(alloc_count, KM_SLEEP); 985 986 /* 987 * Held when getdents calls VOP_RWLOCK.... 988 */ 989 ASSERT(RW_READ_HELD(&fnp->fn_rwlock)); 990 if (uiop->uio_offset >= AUTOFS_DAEMONCOOKIE) { 991 again: 992 /* 993 * Do readdir of daemon contents only 994 * Drop readers lock and reacquire after reply. 995 */ 996 rw_exit(&fnp->fn_rwlock); 997 bzero(&rd, sizeof (struct autofs_rddirres)); 998 count = 0; 999 rda.rda_map = fnip->fi_map; 1000 rda.rda_offset = (uint_t)uiop->uio_offset; 1001 rd.rd_rddir.rddir_entries = dp; 1002 rda.rda_count = rd.rd_rddir.rddir_size = (uint_t)alloc_count; 1003 rda.uid = crgetuid(cred); 1004 1005 error = auto_calldaemon(fngp->fng_zoneid, 1006 AUTOFS_READDIR, 1007 xdr_autofs_rddirargs, 1008 &rda, 1009 xdr_autofs_rddirres, 1010 (void *)&rd, 1011 sizeof (autofs_rddirres), 1012 TRUE); 1013 1014 /* 1015 * reacquire previously dropped lock 1016 */ 1017 rw_enter(&fnp->fn_rwlock, RW_READER); 1018 1019 if (!error) { 1020 error = rd.rd_status; 1021 dp = rd.rd_rddir.rddir_entries; 1022 } 1023 1024 if (error) { 1025 if (error == AUTOFS_SHUTDOWN) { 1026 /* 1027 * treat as empty directory 1028 */ 1029 error = 0; 1030 myeof = 1; 1031 if (eofp) 1032 *eofp = 1; 1033 } 1034 goto done; 1035 } 1036 if (rd.rd_rddir.rddir_size) { 1037 dirent64_t *odp = dp; /* next in output buffer */ 1038 dirent64_t *cdp = dp; /* current examined entry */ 1039 1040 /* 1041 * Check for duplicates here 1042 */ 1043 do { 1044 this_reclen = cdp->d_reclen; 1045 if (auto_search(fnp, cdp->d_name, 1046 NULL, cred)) { 1047 /* 1048 * entry not found in kernel list, 1049 * include it in readdir output. 1050 * 1051 * If we are skipping entries. then 1052 * we need to copy this entry to the 1053 * correct position in the buffer 1054 * to be copied out. 1055 */ 1056 if (cdp != odp) 1057 bcopy(cdp, odp, 1058 (size_t)this_reclen); 1059 odp = nextdp(odp); 1060 outcount += this_reclen; 1061 } else { 1062 /* 1063 * Entry was found in the kernel 1064 * list. If it is the first entry 1065 * in this buffer, then just skip it 1066 */ 1067 if (odp == dp) { 1068 dp = nextdp(dp); 1069 odp = dp; 1070 } 1071 } 1072 count += this_reclen; 1073 cdp = (struct dirent64 *) 1074 ((char *)cdp + this_reclen); 1075 } while (count < rd.rd_rddir.rddir_size); 1076 1077 if (outcount) 1078 error = uiomove(dp, outcount, UIO_READ, uiop); 1079 uiop->uio_offset = rd.rd_rddir.rddir_offset; 1080 } else { 1081 if (rd.rd_rddir.rddir_eof == 0) { 1082 /* 1083 * alloc_count not large enough for one 1084 * directory entry 1085 */ 1086 error = EINVAL; 1087 } 1088 } 1089 if (rd.rd_rddir.rddir_eof && !error) { 1090 myeof = 1; 1091 if (eofp) 1092 *eofp = 1; 1093 } 1094 if (!error && !myeof && outcount == 0) { 1095 /* 1096 * call daemon with new cookie, all previous 1097 * elements happened to be duplicates 1098 */ 1099 dp = outbuf; 1100 goto again; 1101 } 1102 goto done; 1103 } 1104 1105 if (uiop->uio_offset == 0) { 1106 /* 1107 * first time: so fudge the . and .. 1108 */ 1109 this_reclen = DIRENT64_RECLEN(1); 1110 if (alloc_count < this_reclen) { 1111 error = EINVAL; 1112 goto done; 1113 } 1114 dp->d_ino = (ino64_t)fnp->fn_nodeid; 1115 dp->d_off = (off64_t)1; 1116 dp->d_reclen = (ushort_t)this_reclen; 1117 1118 /* use strncpy(9f) to zero out uninitialized bytes */ 1119 1120 (void) strncpy(dp->d_name, ".", 1121 DIRENT64_NAMELEN(this_reclen)); 1122 outcount += dp->d_reclen; 1123 dp = nextdp(dp); 1124 1125 this_reclen = DIRENT64_RECLEN(2); 1126 if (alloc_count < outcount + this_reclen) { 1127 error = EINVAL; 1128 goto done; 1129 } 1130 dp->d_reclen = (ushort_t)this_reclen; 1131 dp->d_ino = (ino64_t)fnp->fn_parent->fn_nodeid; 1132 dp->d_off = (off64_t)2; 1133 1134 /* use strncpy(9f) to zero out uninitialized bytes */ 1135 1136 (void) strncpy(dp->d_name, "..", 1137 DIRENT64_NAMELEN(this_reclen)); 1138 outcount += dp->d_reclen; 1139 dp = nextdp(dp); 1140 } 1141 1142 offset = 2; 1143 cfnp = fnp->fn_dirents; 1144 while (cfnp != NULL) { 1145 nfnp = cfnp->fn_next; 1146 offset = cfnp->fn_offset; 1147 if ((offset >= uiop->uio_offset) && 1148 (!(cfnp->fn_flags & MF_LOOKUP))) { 1149 int reclen; 1150 1151 /* 1152 * include node only if its offset is greater or 1153 * equal to the one required and it is not in 1154 * transient state (not being looked-up) 1155 */ 1156 namelen = strlen(cfnp->fn_name); 1157 reclen = (int)DIRENT64_RECLEN(namelen); 1158 if (outcount + reclen > alloc_count) { 1159 reached_max = 1; 1160 break; 1161 } 1162 dp->d_reclen = (ushort_t)reclen; 1163 dp->d_ino = (ino64_t)cfnp->fn_nodeid; 1164 if (nfnp != NULL) { 1165 /* 1166 * get the offset of the next element 1167 */ 1168 dp->d_off = (off64_t)nfnp->fn_offset; 1169 } else { 1170 /* 1171 * This is the last element, make 1172 * offset one plus the current 1173 */ 1174 dp->d_off = (off64_t)cfnp->fn_offset + 1; 1175 } 1176 1177 /* use strncpy(9f) to zero out uninitialized bytes */ 1178 1179 (void) strncpy(dp->d_name, cfnp->fn_name, 1180 DIRENT64_NAMELEN(reclen)); 1181 outcount += dp->d_reclen; 1182 dp = nextdp(dp); 1183 } 1184 cfnp = nfnp; 1185 } 1186 1187 if (outcount) 1188 error = uiomove(outbuf, outcount, UIO_READ, uiop); 1189 1190 if (!error) { 1191 if (reached_max) { 1192 /* 1193 * This entry did not get added to the buffer on this, 1194 * call. We need to add it on the next call therefore 1195 * set uio_offset to this entry's offset. If there 1196 * wasn't enough space for one dirent, return EINVAL. 1197 */ 1198 uiop->uio_offset = offset; 1199 if (outcount == 0) 1200 error = EINVAL; 1201 } else if (autofs_nobrowse || 1202 auto_nobrowse_option(fnip->fi_opts) || 1203 (fnip->fi_flags & MF_DIRECT) || 1204 (fnp->fn_trigger != NULL) || 1205 (((vp->v_flag & VROOT) == 0) && 1206 ((fntovn(fnp->fn_parent))->v_flag & VROOT) && 1207 (fnp->fn_dirents == NULL))) { 1208 /* 1209 * done reading directory entries 1210 */ 1211 uiop->uio_offset = offset + 1; 1212 if (eofp) 1213 *eofp = 1; 1214 } else { 1215 /* 1216 * Need to get the rest of the entries from the daemon. 1217 */ 1218 uiop->uio_offset = AUTOFS_DAEMONCOOKIE; 1219 } 1220 } 1221 1222 done: 1223 kmem_free(outbuf, alloc_count); 1224 AUTOFS_DPRINT((5, "auto_readdir vp=%p offset=%lld eof=%d\n", 1225 (void *)vp, uiop->uio_loffset, myeof)); 1226 return (error); 1227 } 1228 1229 static int 1230 auto_symlink( 1231 vnode_t *dvp, 1232 char *lnknm, /* new entry */ 1233 vattr_t *tva, 1234 char *tnm, /* existing entry */ 1235 cred_t *cred, 1236 caller_context_t *ct, 1237 int flags) 1238 { 1239 vnode_t *newvp; 1240 int error; 1241 1242 AUTOFS_DPRINT((4, "auto_symlink: dvp=%p lnknm=%s tnm=%s\n", 1243 (void *)dvp, lnknm, tnm)); 1244 1245 if (error = auto_trigger_mount(dvp, cred, &newvp)) 1246 goto done; 1247 1248 if (newvp != NULL) { 1249 /* 1250 * Node is mounted on. 1251 */ 1252 if (vn_is_readonly(newvp)) 1253 error = EROFS; 1254 else 1255 error = VOP_SYMLINK(newvp, lnknm, tva, tnm, cred, 1256 ct, flags); 1257 VN_RELE(newvp); 1258 } else 1259 error = ENOSYS; 1260 1261 done: 1262 AUTOFS_DPRINT((5, "auto_symlink: error=%d\n", error)); 1263 return (error); 1264 } 1265 1266 /* ARGSUSED */ 1267 static int 1268 auto_readlink(vnode_t *vp, struct uio *uiop, cred_t *cr, caller_context_t *ct) 1269 { 1270 fnnode_t *fnp = vntofn(vp); 1271 int error; 1272 timestruc_t now; 1273 1274 AUTOFS_DPRINT((4, "auto_readlink: vp=%p\n", (void *)vp)); 1275 1276 gethrestime(&now); 1277 fnp->fn_ref_time = now.tv_sec; 1278 1279 if (vp->v_type != VLNK) 1280 error = EINVAL; 1281 else { 1282 ASSERT(!(fnp->fn_flags & (MF_INPROG | MF_LOOKUP))); 1283 fnp->fn_atime = now; 1284 error = uiomove(fnp->fn_symlink, MIN(fnp->fn_symlinklen, 1285 uiop->uio_resid), UIO_READ, uiop); 1286 } 1287 1288 AUTOFS_DPRINT((5, "auto_readlink: error=%d\n", error)); 1289 return (error); 1290 } 1291 1292 /* ARGSUSED */ 1293 static int 1294 auto_fsync(vnode_t *cp, int syncflag, cred_t *cred, caller_context_t *ct) 1295 { 1296 return (0); 1297 } 1298 1299 /* ARGSUSED */ 1300 static void 1301 auto_inactive(vnode_t *vp, cred_t *cred, caller_context_t *ct) 1302 { 1303 fnnode_t *fnp = vntofn(vp); 1304 fnnode_t *dfnp = fnp->fn_parent; 1305 int count; 1306 1307 AUTOFS_DPRINT((4, "auto_inactive: vp=%p v_count=%u fn_link=%d\n", 1308 (void *)vp, vp->v_count, fnp->fn_linkcnt)); 1309 1310 /* 1311 * The rwlock should not be already held by this thread. 1312 * The assert relies on the fact that the owner field is cleared 1313 * when the lock is released. 1314 */ 1315 ASSERT(dfnp != NULL); 1316 ASSERT(rw_owner(&dfnp->fn_rwlock) != curthread); 1317 rw_enter(&dfnp->fn_rwlock, RW_WRITER); 1318 mutex_enter(&vp->v_lock); 1319 ASSERT(vp->v_count > 0); 1320 VN_RELE_LOCKED(vp); 1321 count = vp->v_count; 1322 mutex_exit(&vp->v_lock); 1323 if (count == 0) { 1324 /* 1325 * Free only if node has no subdirectories. 1326 */ 1327 if (fnp->fn_linkcnt == 1) { 1328 auto_disconnect(dfnp, fnp); 1329 rw_exit(&dfnp->fn_rwlock); 1330 auto_freefnnode(fnp); 1331 AUTOFS_DPRINT((5, "auto_inactive: (exit) vp=%p freed\n", 1332 (void *)vp)); 1333 return; 1334 } 1335 } 1336 rw_exit(&dfnp->fn_rwlock); 1337 1338 AUTOFS_DPRINT((5, "auto_inactive: (exit) vp=%p v_count=%u fn_link=%d\n", 1339 (void *)vp, vp->v_count, fnp->fn_linkcnt)); 1340 } 1341 1342 /* ARGSUSED2 */ 1343 static int 1344 auto_rwlock(vnode_t *vp, int write_lock, caller_context_t *ct) 1345 { 1346 fnnode_t *fnp = vntofn(vp); 1347 if (write_lock) 1348 rw_enter(&fnp->fn_rwlock, RW_WRITER); 1349 else 1350 rw_enter(&fnp->fn_rwlock, RW_READER); 1351 return (write_lock); 1352 } 1353 1354 /* ARGSUSED */ 1355 static void 1356 auto_rwunlock(vnode_t *vp, int write_lock, caller_context_t *ct) 1357 { 1358 fnnode_t *fnp = vntofn(vp); 1359 rw_exit(&fnp->fn_rwlock); 1360 } 1361 1362 1363 /* ARGSUSED */ 1364 static int 1365 auto_seek( 1366 struct vnode *vp, 1367 offset_t ooff, 1368 offset_t *noffp, 1369 caller_context_t *ct) 1370 { 1371 /* 1372 * Return 0 unconditionally, since we expect 1373 * a VDIR all the time 1374 */ 1375 return (0); 1376 } 1377 1378 /* 1379 * Triggers the mount if needed. If the mount has been triggered by 1380 * another thread, it will wait for its return status, and return it. 1381 * Whether the mount is triggered by this thread, another thread, or 1382 * if the vnode was already covered, '*newvp' is a 1383 * VN_HELD vnode pointing to the root of the filesystem covering 'vp'. 1384 * If the node is not mounted on, and should not be mounted on, '*newvp' 1385 * will be NULL. 1386 * The calling routine may use '*newvp' to do the filesystem jump. 1387 */ 1388 static int 1389 auto_trigger_mount(vnode_t *vp, cred_t *cred, vnode_t **newvp) 1390 { 1391 fnnode_t *fnp = vntofn(vp); 1392 fninfo_t *fnip = vfstofni(vp->v_vfsp); 1393 vnode_t *dvp; 1394 vfs_t *vfsp; 1395 int delayed_ind; 1396 char name[AUTOFS_MAXPATHLEN]; 1397 int error; 1398 1399 AUTOFS_DPRINT((4, "auto_trigger_mount: vp=%p\n", (void *)vp)); 1400 1401 *newvp = NULL; 1402 1403 /* 1404 * Cross-zone mount triggering is disallowed. 1405 */ 1406 if (fnip->fi_zoneid != getzoneid()) 1407 return (EPERM); /* Not owner of mount */ 1408 1409 retry: 1410 error = 0; 1411 delayed_ind = 0; 1412 mutex_enter(&fnp->fn_lock); 1413 while (fnp->fn_flags & (MF_LOOKUP | MF_INPROG)) { 1414 /* 1415 * Mount or lookup in progress, 1416 * wait for it before proceeding. 1417 */ 1418 mutex_exit(&fnp->fn_lock); 1419 error = auto_wait4mount(fnp); 1420 if (error == AUTOFS_SHUTDOWN) { 1421 error = 0; 1422 goto done; 1423 } 1424 if (error && error != EAGAIN) 1425 goto done; 1426 error = 0; 1427 mutex_enter(&fnp->fn_lock); 1428 } 1429 1430 /* 1431 * If the vfslock can't be acquired for the first time. 1432 * drop the fn_lock and retry next time in blocking mode. 1433 */ 1434 if (vn_vfswlock(vp)) { 1435 /* 1436 * Lock held by another thread. 1437 * Perform blocking by dropping the 1438 * fn_lock. 1439 */ 1440 mutex_exit(&fnp->fn_lock); 1441 error = vn_vfswlock_wait(vp); 1442 if (error) 1443 goto done; 1444 /* 1445 * Because fn_lock wasn't held, the state 1446 * of the trigger node might have changed. 1447 * Need to run through the checks on trigger 1448 * node again. 1449 */ 1450 vn_vfsunlock(vp); 1451 goto retry; 1452 } 1453 1454 vfsp = vn_mountedvfs(vp); 1455 if (vfsp != NULL) { 1456 mutex_exit(&fnp->fn_lock); 1457 error = VFS_ROOT(vfsp, newvp); 1458 vn_vfsunlock(vp); 1459 goto done; 1460 } else { 1461 vn_vfsunlock(vp); 1462 if ((fnp->fn_flags & MF_MOUNTPOINT) && 1463 fnp->fn_trigger != NULL) { 1464 ASSERT(fnp->fn_dirents == NULL); 1465 mutex_exit(&fnp->fn_lock); 1466 /* 1467 * The filesystem that used to sit here has been 1468 * forcibly unmounted. Do our best to recover. 1469 * Try to unmount autofs subtree below this node 1470 * and retry the action. 1471 */ 1472 if (unmount_subtree(fnp, B_TRUE) != 0) { 1473 error = EIO; 1474 goto done; 1475 } 1476 goto retry; 1477 } 1478 } 1479 1480 ASSERT(vp->v_type == VDIR); 1481 dvp = fntovn(fnp->fn_parent); 1482 1483 if ((fnp->fn_dirents == NULL) && 1484 ((fnip->fi_flags & MF_DIRECT) == 0) && 1485 ((vp->v_flag & VROOT) == 0) && 1486 (dvp->v_flag & VROOT)) { 1487 /* 1488 * If the parent of this node is the root of an indirect 1489 * AUTOFS filesystem, this node is remountable. 1490 */ 1491 delayed_ind = 1; 1492 } 1493 1494 if (delayed_ind || 1495 ((fnip->fi_flags & MF_DIRECT) && (fnp->fn_dirents == NULL))) { 1496 /* 1497 * Trigger mount since: 1498 * direct mountpoint with no subdirs or 1499 * delayed indirect. 1500 */ 1501 AUTOFS_BLOCK_OTHERS(fnp, MF_INPROG); 1502 fnp->fn_error = 0; 1503 mutex_exit(&fnp->fn_lock); 1504 if (delayed_ind) 1505 (void) strcpy(name, fnp->fn_name); 1506 else 1507 (void) strcpy(name, "."); 1508 fnp->fn_ref_time = gethrestime_sec(); 1509 auto_new_mount_thread(fnp, name, cred); 1510 /* 1511 * At this point we're simply another thread waiting 1512 * for the mount to finish. 1513 */ 1514 error = auto_wait4mount(fnp); 1515 if (error == EAGAIN) 1516 goto retry; 1517 if (error == AUTOFS_SHUTDOWN) { 1518 error = 0; 1519 goto done; 1520 } 1521 if (error == 0) { 1522 if (error = vn_vfsrlock_wait(vp)) 1523 goto done; 1524 /* Reacquire after dropping locks */ 1525 vfsp = vn_mountedvfs(vp); 1526 if (vfsp != NULL) { 1527 error = VFS_ROOT(vfsp, newvp); 1528 vn_vfsunlock(vp); 1529 } else { 1530 vn_vfsunlock(vp); 1531 goto retry; 1532 } 1533 } 1534 } else 1535 mutex_exit(&fnp->fn_lock); 1536 1537 done: 1538 AUTOFS_DPRINT((5, "auto_trigger_mount: error=%d\n", error)); 1539 return (error); 1540 } 1541