1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1992, 1993, 1994, 1995 Jan-Simon Pendry. 5 * Copyright (c) 1992, 1993, 1994, 1995 6 * The Regents of the University of California. 7 * Copyright (c) 2005, 2006, 2012 Masanori Ozawa <ozawa@ongs.co.jp>, ONGS Inc. 8 * Copyright (c) 2006, 2012 Daichi Goto <daichi@freebsd.org> 9 * All rights reserved. 10 * 11 * This code is derived from software contributed to Berkeley by 12 * Jan-Simon Pendry. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 3. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)union_vnops.c 8.32 (Berkeley) 6/23/95 39 * $FreeBSD$ 40 * 41 */ 42 43 #include <sys/param.h> 44 #include <sys/systm.h> 45 #include <sys/conf.h> 46 #include <sys/kernel.h> 47 #include <sys/lock.h> 48 #include <sys/malloc.h> 49 #include <sys/mount.h> 50 #include <sys/mutex.h> 51 #include <sys/namei.h> 52 #include <sys/sysctl.h> 53 #include <sys/vnode.h> 54 #include <sys/kdb.h> 55 #include <sys/fcntl.h> 56 #include <sys/stat.h> 57 #include <sys/dirent.h> 58 #include <sys/proc.h> 59 #include <sys/bio.h> 60 #include <sys/buf.h> 61 62 #include <fs/unionfs/union.h> 63 64 #include <machine/atomic.h> 65 66 #include <vm/vm.h> 67 #include <vm/vm_extern.h> 68 #include <vm/vm_object.h> 69 #include <vm/vnode_pager.h> 70 71 #if 0 72 #define UNIONFS_INTERNAL_DEBUG(msg, args...) printf(msg, ## args) 73 #define UNIONFS_IDBG_RENAME 74 #else 75 #define UNIONFS_INTERNAL_DEBUG(msg, args...) 76 #endif 77 78 #define KASSERT_UNIONFS_VNODE(vp) \ 79 VNASSERT(((vp)->v_op == &unionfs_vnodeops), vp, \ 80 ("%s: non-unionfs vnode", __func__)) 81 82 static int 83 unionfs_lookup(struct vop_cachedlookup_args *ap) 84 { 85 struct unionfs_node *dunp; 86 struct vnode *dvp, *udvp, *ldvp, *vp, *uvp, *lvp, *dtmpvp; 87 struct vattr va; 88 struct componentname *cnp; 89 struct thread *td; 90 u_long nameiop; 91 u_long cnflags, cnflagsbk; 92 int iswhiteout; 93 int lockflag; 94 int error , uerror, lerror; 95 96 iswhiteout = 0; 97 lockflag = 0; 98 error = uerror = lerror = ENOENT; 99 cnp = ap->a_cnp; 100 nameiop = cnp->cn_nameiop; 101 cnflags = cnp->cn_flags; 102 dvp = ap->a_dvp; 103 dunp = VTOUNIONFS(dvp); 104 udvp = dunp->un_uppervp; 105 ldvp = dunp->un_lowervp; 106 vp = uvp = lvp = NULLVP; 107 td = curthread; 108 *(ap->a_vpp) = NULLVP; 109 110 UNIONFS_INTERNAL_DEBUG( 111 "unionfs_lookup: enter: nameiop=%ld, flags=%lx, path=%s\n", 112 nameiop, cnflags, cnp->cn_nameptr); 113 114 if (dvp->v_type != VDIR) 115 return (ENOTDIR); 116 117 /* 118 * If read-only and op is not LOOKUP, will return EROFS. 119 */ 120 if ((cnflags & ISLASTCN) && 121 (dvp->v_mount->mnt_flag & MNT_RDONLY) && 122 LOOKUP != nameiop) 123 return (EROFS); 124 125 /* 126 * lookup dotdot 127 */ 128 if (cnflags & ISDOTDOT) { 129 if (LOOKUP != nameiop && udvp == NULLVP) 130 return (EROFS); 131 132 if (udvp != NULLVP) { 133 dtmpvp = udvp; 134 if (ldvp != NULLVP) 135 VOP_UNLOCK(ldvp); 136 } 137 else 138 dtmpvp = ldvp; 139 140 error = VOP_LOOKUP(dtmpvp, &vp, cnp); 141 142 if (dtmpvp == udvp && ldvp != NULLVP) { 143 VOP_UNLOCK(udvp); 144 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); 145 } 146 147 if (error == 0) { 148 /* 149 * Exchange lock and reference from vp to 150 * dunp->un_dvp. vp is upper/lower vnode, but it 151 * will need to return the unionfs vnode. 152 */ 153 if (nameiop == DELETE || nameiop == RENAME || 154 (cnp->cn_lkflags & LK_TYPE_MASK)) 155 VOP_UNLOCK(vp); 156 vrele(vp); 157 158 VOP_UNLOCK(dvp); 159 *(ap->a_vpp) = dunp->un_dvp; 160 vref(dunp->un_dvp); 161 162 if (nameiop == DELETE || nameiop == RENAME) 163 vn_lock(dunp->un_dvp, LK_EXCLUSIVE | LK_RETRY); 164 else if (cnp->cn_lkflags & LK_TYPE_MASK) 165 vn_lock(dunp->un_dvp, cnp->cn_lkflags | 166 LK_RETRY); 167 168 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); 169 } else if (error == ENOENT && (cnflags & MAKEENTRY) != 0) 170 cache_enter(dvp, NULLVP, cnp); 171 172 goto unionfs_lookup_return; 173 } 174 175 /* 176 * lookup upper layer 177 */ 178 if (udvp != NULLVP) { 179 uerror = VOP_LOOKUP(udvp, &uvp, cnp); 180 181 if (uerror == 0) { 182 if (udvp == uvp) { /* is dot */ 183 vrele(uvp); 184 *(ap->a_vpp) = dvp; 185 vref(dvp); 186 187 error = uerror; 188 goto unionfs_lookup_return; 189 } 190 if (nameiop == DELETE || nameiop == RENAME || 191 (cnp->cn_lkflags & LK_TYPE_MASK)) 192 VOP_UNLOCK(uvp); 193 } 194 195 /* check whiteout */ 196 if (uerror == ENOENT || uerror == EJUSTRETURN) 197 if (cnp->cn_flags & ISWHITEOUT) 198 iswhiteout = 1; /* don't lookup lower */ 199 if (iswhiteout == 0 && ldvp != NULLVP) 200 if (!VOP_GETATTR(udvp, &va, cnp->cn_cred) && 201 (va.va_flags & OPAQUE)) 202 iswhiteout = 1; /* don't lookup lower */ 203 #if 0 204 UNIONFS_INTERNAL_DEBUG( 205 "unionfs_lookup: debug: whiteout=%d, path=%s\n", 206 iswhiteout, cnp->cn_nameptr); 207 #endif 208 } 209 210 /* 211 * lookup lower layer 212 */ 213 if (ldvp != NULLVP && !(cnflags & DOWHITEOUT) && iswhiteout == 0) { 214 /* always op is LOOKUP */ 215 cnp->cn_nameiop = LOOKUP; 216 cnflagsbk = cnp->cn_flags; 217 cnp->cn_flags = cnflags; 218 219 lerror = VOP_LOOKUP(ldvp, &lvp, cnp); 220 221 cnp->cn_nameiop = nameiop; 222 if (udvp != NULLVP && (uerror == 0 || uerror == EJUSTRETURN)) 223 cnp->cn_flags = cnflagsbk; 224 225 if (lerror == 0) { 226 if (ldvp == lvp) { /* is dot */ 227 if (uvp != NULLVP) 228 vrele(uvp); /* no need? */ 229 vrele(lvp); 230 *(ap->a_vpp) = dvp; 231 vref(dvp); 232 233 UNIONFS_INTERNAL_DEBUG( 234 "unionfs_lookup: leave (%d)\n", lerror); 235 236 return (lerror); 237 } 238 if (cnp->cn_lkflags & LK_TYPE_MASK) 239 VOP_UNLOCK(lvp); 240 } 241 } 242 243 /* 244 * check lookup result 245 */ 246 if (uvp == NULLVP && lvp == NULLVP) { 247 error = (udvp != NULLVP ? uerror : lerror); 248 goto unionfs_lookup_return; 249 } 250 251 /* 252 * check vnode type 253 */ 254 if (uvp != NULLVP && lvp != NULLVP && uvp->v_type != lvp->v_type) { 255 vrele(lvp); 256 lvp = NULLVP; 257 } 258 259 /* 260 * check shadow dir 261 */ 262 if (uerror != 0 && uerror != EJUSTRETURN && udvp != NULLVP && 263 lerror == 0 && lvp != NULLVP && lvp->v_type == VDIR && 264 !(dvp->v_mount->mnt_flag & MNT_RDONLY) && 265 (1 < cnp->cn_namelen || '.' != *(cnp->cn_nameptr))) { 266 /* get unionfs vnode in order to create a new shadow dir. */ 267 error = unionfs_nodeget(dvp->v_mount, NULLVP, lvp, dvp, &vp, 268 cnp); 269 if (error != 0) 270 goto unionfs_lookup_cleanup; 271 272 if (LK_SHARED == (cnp->cn_lkflags & LK_TYPE_MASK)) 273 VOP_UNLOCK(vp); 274 if (LK_EXCLUSIVE != VOP_ISLOCKED(vp)) { 275 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 276 lockflag = 1; 277 } 278 error = unionfs_mkshadowdir(MOUNTTOUNIONFSMOUNT(dvp->v_mount), 279 udvp, VTOUNIONFS(vp), cnp, td); 280 if (lockflag != 0) 281 VOP_UNLOCK(vp); 282 if (error != 0) { 283 UNIONFSDEBUG( 284 "unionfs_lookup: Unable to create shadow dir."); 285 if ((cnp->cn_lkflags & LK_TYPE_MASK) == LK_EXCLUSIVE) 286 vput(vp); 287 else 288 vrele(vp); 289 goto unionfs_lookup_cleanup; 290 } 291 if ((cnp->cn_lkflags & LK_TYPE_MASK) == LK_SHARED) 292 vn_lock(vp, LK_SHARED | LK_RETRY); 293 } 294 /* 295 * get unionfs vnode. 296 */ 297 else { 298 if (uvp != NULLVP) 299 error = uerror; 300 else 301 error = lerror; 302 if (error != 0) 303 goto unionfs_lookup_cleanup; 304 /* 305 * get socket vnode. 306 */ 307 if (uvp != NULLVP && uvp->v_type == VSOCK) { 308 vp = uvp; 309 vref(vp); 310 if (cnp->cn_lkflags & LK_TYPE_MASK) 311 vn_lock(vp, cnp->cn_lkflags | LK_RETRY); 312 } 313 else if (lvp != NULLVP && lvp->v_type == VSOCK) { 314 vp = lvp; 315 vref(vp); 316 if (cnp->cn_lkflags & LK_TYPE_MASK) 317 vn_lock(vp, cnp->cn_lkflags | LK_RETRY); 318 } 319 /* 320 * get unionfs vnode. 321 */ 322 else 323 error = unionfs_nodeget(dvp->v_mount, uvp, lvp, 324 dvp, &vp, cnp); 325 if (error != 0) { 326 UNIONFSDEBUG( 327 "unionfs_lookup: Unable to create unionfs vnode."); 328 goto unionfs_lookup_cleanup; 329 } 330 if ((nameiop == DELETE || nameiop == RENAME) && 331 (cnp->cn_lkflags & LK_TYPE_MASK) == 0) 332 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 333 } 334 335 *(ap->a_vpp) = vp; 336 337 if ((cnflags & MAKEENTRY) && vp->v_type != VSOCK) 338 cache_enter(dvp, vp, cnp); 339 340 unionfs_lookup_cleanup: 341 if (uvp != NULLVP) 342 vrele(uvp); 343 if (lvp != NULLVP) 344 vrele(lvp); 345 346 if (error == ENOENT && (cnflags & MAKEENTRY) != 0) 347 cache_enter(dvp, NULLVP, cnp); 348 349 unionfs_lookup_return: 350 351 /* Ensure subsequent vnops will get a valid pathname buffer. */ 352 if (nameiop != LOOKUP && (error == 0 || error == EJUSTRETURN)) 353 cnp->cn_flags |= SAVENAME; 354 355 UNIONFS_INTERNAL_DEBUG("unionfs_lookup: leave (%d)\n", error); 356 357 return (error); 358 } 359 360 static int 361 unionfs_create(struct vop_create_args *ap) 362 { 363 struct unionfs_node *dunp; 364 struct componentname *cnp; 365 struct vnode *udvp; 366 struct vnode *vp; 367 int error; 368 369 UNIONFS_INTERNAL_DEBUG("unionfs_create: enter\n"); 370 371 KASSERT_UNIONFS_VNODE(ap->a_dvp); 372 373 dunp = VTOUNIONFS(ap->a_dvp); 374 cnp = ap->a_cnp; 375 udvp = dunp->un_uppervp; 376 error = EROFS; 377 378 if (udvp != NULLVP) { 379 error = VOP_CREATE(udvp, &vp, cnp, ap->a_vap); 380 if (error != 0) 381 goto unionfs_create_abort; 382 383 if (vp->v_type == VSOCK) 384 *(ap->a_vpp) = vp; 385 else { 386 VOP_UNLOCK(vp); 387 error = unionfs_nodeget(ap->a_dvp->v_mount, vp, NULLVP, 388 ap->a_dvp, ap->a_vpp, cnp); 389 vrele(vp); 390 } 391 } 392 393 unionfs_create_abort: 394 UNIONFS_INTERNAL_DEBUG("unionfs_create: leave (%d)\n", error); 395 396 return (error); 397 } 398 399 static int 400 unionfs_whiteout(struct vop_whiteout_args *ap) 401 { 402 struct unionfs_node *dunp; 403 struct componentname *cnp; 404 struct vnode *udvp; 405 int error; 406 407 UNIONFS_INTERNAL_DEBUG("unionfs_whiteout: enter\n"); 408 409 KASSERT_UNIONFS_VNODE(ap->a_dvp); 410 411 dunp = VTOUNIONFS(ap->a_dvp); 412 cnp = ap->a_cnp; 413 udvp = dunp->un_uppervp; 414 error = EOPNOTSUPP; 415 416 if (udvp != NULLVP) { 417 switch (ap->a_flags) { 418 case CREATE: 419 case DELETE: 420 case LOOKUP: 421 error = VOP_WHITEOUT(udvp, cnp, ap->a_flags); 422 break; 423 default: 424 error = EINVAL; 425 break; 426 } 427 } 428 429 UNIONFS_INTERNAL_DEBUG("unionfs_whiteout: leave (%d)\n", error); 430 431 return (error); 432 } 433 434 static int 435 unionfs_mknod(struct vop_mknod_args *ap) 436 { 437 struct unionfs_node *dunp; 438 struct componentname *cnp; 439 struct vnode *udvp; 440 struct vnode *vp; 441 int error; 442 443 UNIONFS_INTERNAL_DEBUG("unionfs_mknod: enter\n"); 444 445 KASSERT_UNIONFS_VNODE(ap->a_dvp); 446 447 dunp = VTOUNIONFS(ap->a_dvp); 448 cnp = ap->a_cnp; 449 udvp = dunp->un_uppervp; 450 error = EROFS; 451 452 if (udvp != NULLVP) { 453 error = VOP_MKNOD(udvp, &vp, cnp, ap->a_vap); 454 if (error != 0) 455 goto unionfs_mknod_abort; 456 457 if (vp->v_type == VSOCK) 458 *(ap->a_vpp) = vp; 459 else { 460 VOP_UNLOCK(vp); 461 error = unionfs_nodeget(ap->a_dvp->v_mount, vp, NULLVP, 462 ap->a_dvp, ap->a_vpp, cnp); 463 vrele(vp); 464 } 465 } 466 467 unionfs_mknod_abort: 468 UNIONFS_INTERNAL_DEBUG("unionfs_mknod: leave (%d)\n", error); 469 470 return (error); 471 } 472 473 enum unionfs_lkupgrade { 474 UNIONFS_LKUPGRADE_SUCCESS, /* lock successfully upgraded */ 475 UNIONFS_LKUPGRADE_ALREADY, /* lock already held exclusive */ 476 UNIONFS_LKUPGRADE_DOOMED /* lock was upgraded, but vnode reclaimed */ 477 }; 478 479 static inline enum unionfs_lkupgrade 480 unionfs_upgrade_lock(struct vnode *vp) 481 { 482 ASSERT_VOP_LOCKED(vp, __func__); 483 484 if (VOP_ISLOCKED(vp) == LK_EXCLUSIVE) 485 return (UNIONFS_LKUPGRADE_ALREADY); 486 487 if (vn_lock(vp, LK_UPGRADE) != 0) { 488 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 489 if (VN_IS_DOOMED(vp)) 490 return (UNIONFS_LKUPGRADE_DOOMED); 491 } 492 return (UNIONFS_LKUPGRADE_SUCCESS); 493 } 494 495 static inline void 496 unionfs_downgrade_lock(struct vnode *vp, enum unionfs_lkupgrade status) 497 { 498 if (status != UNIONFS_LKUPGRADE_ALREADY) 499 vn_lock(vp, LK_DOWNGRADE | LK_RETRY); 500 } 501 502 static int 503 unionfs_open(struct vop_open_args *ap) 504 { 505 struct unionfs_node *unp; 506 struct unionfs_node_status *unsp; 507 struct vnode *vp; 508 struct vnode *uvp; 509 struct vnode *lvp; 510 struct vnode *targetvp; 511 struct ucred *cred; 512 struct thread *td; 513 int error; 514 enum unionfs_lkupgrade lkstatus; 515 516 UNIONFS_INTERNAL_DEBUG("unionfs_open: enter\n"); 517 518 KASSERT_UNIONFS_VNODE(ap->a_vp); 519 520 error = 0; 521 vp = ap->a_vp; 522 targetvp = NULLVP; 523 cred = ap->a_cred; 524 td = ap->a_td; 525 526 /* 527 * The executable loader path may call this function with vp locked 528 * shared. If the vnode is reclaimed while upgrading, we can't safely 529 * use unp or do anything else unionfs- specific. 530 */ 531 lkstatus = unionfs_upgrade_lock(vp); 532 if (lkstatus == UNIONFS_LKUPGRADE_DOOMED) { 533 error = ENOENT; 534 goto unionfs_open_cleanup; 535 } 536 537 unp = VTOUNIONFS(vp); 538 uvp = unp->un_uppervp; 539 lvp = unp->un_lowervp; 540 unionfs_get_node_status(unp, td, &unsp); 541 542 if (unsp->uns_lower_opencnt > 0 || unsp->uns_upper_opencnt > 0) { 543 /* vnode is already opend. */ 544 if (unsp->uns_upper_opencnt > 0) 545 targetvp = uvp; 546 else 547 targetvp = lvp; 548 549 if (targetvp == lvp && 550 (ap->a_mode & FWRITE) && lvp->v_type == VREG) 551 targetvp = NULLVP; 552 } 553 if (targetvp == NULLVP) { 554 if (uvp == NULLVP) { 555 if ((ap->a_mode & FWRITE) && lvp->v_type == VREG) { 556 error = unionfs_copyfile(unp, 557 !(ap->a_mode & O_TRUNC), cred, td); 558 if (error != 0) 559 goto unionfs_open_abort; 560 targetvp = uvp = unp->un_uppervp; 561 } else 562 targetvp = lvp; 563 } else 564 targetvp = uvp; 565 } 566 567 error = VOP_OPEN(targetvp, ap->a_mode, cred, td, ap->a_fp); 568 if (error == 0) { 569 if (targetvp == uvp) { 570 if (uvp->v_type == VDIR && lvp != NULLVP && 571 unsp->uns_lower_opencnt <= 0) { 572 /* open lower for readdir */ 573 error = VOP_OPEN(lvp, FREAD, cred, td, NULL); 574 if (error != 0) { 575 VOP_CLOSE(uvp, ap->a_mode, cred, td); 576 goto unionfs_open_abort; 577 } 578 unsp->uns_node_flag |= UNS_OPENL_4_READDIR; 579 unsp->uns_lower_opencnt++; 580 } 581 unsp->uns_upper_opencnt++; 582 } else { 583 unsp->uns_lower_opencnt++; 584 unsp->uns_lower_openmode = ap->a_mode; 585 } 586 vp->v_object = targetvp->v_object; 587 } 588 589 unionfs_open_abort: 590 if (error != 0) 591 unionfs_tryrem_node_status(unp, unsp); 592 593 unionfs_open_cleanup: 594 unionfs_downgrade_lock(vp, lkstatus); 595 596 UNIONFS_INTERNAL_DEBUG("unionfs_open: leave (%d)\n", error); 597 598 return (error); 599 } 600 601 static int 602 unionfs_close(struct vop_close_args *ap) 603 { 604 struct unionfs_node *unp; 605 struct unionfs_node_status *unsp; 606 struct ucred *cred; 607 struct thread *td; 608 struct vnode *vp; 609 struct vnode *ovp; 610 int error; 611 enum unionfs_lkupgrade lkstatus;; 612 613 UNIONFS_INTERNAL_DEBUG("unionfs_close: enter\n"); 614 615 KASSERT_UNIONFS_VNODE(ap->a_vp); 616 617 vp = ap->a_vp; 618 cred = ap->a_cred; 619 td = ap->a_td; 620 error = 0; 621 622 /* 623 * If the vnode is reclaimed while upgrading, we can't safely use unp 624 * or do anything else unionfs- specific. 625 */ 626 lkstatus = unionfs_upgrade_lock(vp); 627 if (lkstatus == UNIONFS_LKUPGRADE_DOOMED) 628 goto unionfs_close_cleanup; 629 630 unp = VTOUNIONFS(vp); 631 unionfs_get_node_status(unp, td, &unsp); 632 633 if (unsp->uns_lower_opencnt <= 0 && unsp->uns_upper_opencnt <= 0) { 634 #ifdef DIAGNOSTIC 635 printf("unionfs_close: warning: open count is 0\n"); 636 #endif 637 if (unp->un_uppervp != NULLVP) 638 ovp = unp->un_uppervp; 639 else 640 ovp = unp->un_lowervp; 641 } else if (unsp->uns_upper_opencnt > 0) 642 ovp = unp->un_uppervp; 643 else 644 ovp = unp->un_lowervp; 645 646 error = VOP_CLOSE(ovp, ap->a_fflag, cred, td); 647 648 if (error != 0) 649 goto unionfs_close_abort; 650 651 vp->v_object = ovp->v_object; 652 653 if (ovp == unp->un_uppervp) { 654 unsp->uns_upper_opencnt--; 655 if (unsp->uns_upper_opencnt == 0) { 656 if (unsp->uns_node_flag & UNS_OPENL_4_READDIR) { 657 VOP_CLOSE(unp->un_lowervp, FREAD, cred, td); 658 unsp->uns_node_flag &= ~UNS_OPENL_4_READDIR; 659 unsp->uns_lower_opencnt--; 660 } 661 if (unsp->uns_lower_opencnt > 0) 662 vp->v_object = unp->un_lowervp->v_object; 663 } 664 } else 665 unsp->uns_lower_opencnt--; 666 667 unionfs_close_abort: 668 unionfs_tryrem_node_status(unp, unsp); 669 670 unionfs_close_cleanup: 671 unionfs_downgrade_lock(vp, lkstatus); 672 673 UNIONFS_INTERNAL_DEBUG("unionfs_close: leave (%d)\n", error); 674 675 return (error); 676 } 677 678 /* 679 * Check the access mode toward shadow file/dir. 680 */ 681 static int 682 unionfs_check_corrected_access(accmode_t accmode, struct vattr *va, 683 struct ucred *cred) 684 { 685 uid_t uid; /* upper side vnode's uid */ 686 gid_t gid; /* upper side vnode's gid */ 687 u_short vmode; /* upper side vnode's mode */ 688 u_short mask; 689 690 mask = 0; 691 uid = va->va_uid; 692 gid = va->va_gid; 693 vmode = va->va_mode; 694 695 /* check owner */ 696 if (cred->cr_uid == uid) { 697 if (accmode & VEXEC) 698 mask |= S_IXUSR; 699 if (accmode & VREAD) 700 mask |= S_IRUSR; 701 if (accmode & VWRITE) 702 mask |= S_IWUSR; 703 return ((vmode & mask) == mask ? 0 : EACCES); 704 } 705 706 /* check group */ 707 if (groupmember(gid, cred)) { 708 if (accmode & VEXEC) 709 mask |= S_IXGRP; 710 if (accmode & VREAD) 711 mask |= S_IRGRP; 712 if (accmode & VWRITE) 713 mask |= S_IWGRP; 714 return ((vmode & mask) == mask ? 0 : EACCES); 715 } 716 717 /* check other */ 718 if (accmode & VEXEC) 719 mask |= S_IXOTH; 720 if (accmode & VREAD) 721 mask |= S_IROTH; 722 if (accmode & VWRITE) 723 mask |= S_IWOTH; 724 725 return ((vmode & mask) == mask ? 0 : EACCES); 726 } 727 728 static int 729 unionfs_access(struct vop_access_args *ap) 730 { 731 struct unionfs_mount *ump; 732 struct unionfs_node *unp; 733 struct vnode *uvp; 734 struct vnode *lvp; 735 struct thread *td; 736 struct vattr va; 737 accmode_t accmode; 738 int error; 739 740 UNIONFS_INTERNAL_DEBUG("unionfs_access: enter\n"); 741 742 KASSERT_UNIONFS_VNODE(ap->a_vp); 743 744 ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount); 745 unp = VTOUNIONFS(ap->a_vp); 746 uvp = unp->un_uppervp; 747 lvp = unp->un_lowervp; 748 td = ap->a_td; 749 accmode = ap->a_accmode; 750 error = EACCES; 751 752 if ((accmode & VWRITE) && 753 (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY)) { 754 switch (ap->a_vp->v_type) { 755 case VREG: 756 case VDIR: 757 case VLNK: 758 return (EROFS); 759 default: 760 break; 761 } 762 } 763 764 if (uvp != NULLVP) { 765 error = VOP_ACCESS(uvp, accmode, ap->a_cred, td); 766 767 UNIONFS_INTERNAL_DEBUG("unionfs_access: leave (%d)\n", error); 768 769 return (error); 770 } 771 772 if (lvp != NULLVP) { 773 if (accmode & VWRITE) { 774 if (ump->um_uppervp->v_mount->mnt_flag & MNT_RDONLY) { 775 switch (ap->a_vp->v_type) { 776 case VREG: 777 case VDIR: 778 case VLNK: 779 return (EROFS); 780 default: 781 break; 782 } 783 } else if (ap->a_vp->v_type == VREG || 784 ap->a_vp->v_type == VDIR) { 785 /* check shadow file/dir */ 786 if (ump->um_copymode != UNIONFS_TRANSPARENT) { 787 error = unionfs_create_uppervattr(ump, 788 lvp, &va, ap->a_cred, td); 789 if (error != 0) 790 return (error); 791 792 error = unionfs_check_corrected_access( 793 accmode, &va, ap->a_cred); 794 if (error != 0) 795 return (error); 796 } 797 } 798 accmode &= ~(VWRITE | VAPPEND); 799 accmode |= VREAD; /* will copy to upper */ 800 } 801 error = VOP_ACCESS(lvp, accmode, ap->a_cred, td); 802 } 803 804 UNIONFS_INTERNAL_DEBUG("unionfs_access: leave (%d)\n", error); 805 806 return (error); 807 } 808 809 static int 810 unionfs_getattr(struct vop_getattr_args *ap) 811 { 812 struct unionfs_node *unp; 813 struct unionfs_mount *ump; 814 struct vnode *uvp; 815 struct vnode *lvp; 816 struct thread *td; 817 struct vattr va; 818 int error; 819 820 UNIONFS_INTERNAL_DEBUG("unionfs_getattr: enter\n"); 821 822 KASSERT_UNIONFS_VNODE(ap->a_vp); 823 824 unp = VTOUNIONFS(ap->a_vp); 825 ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount); 826 uvp = unp->un_uppervp; 827 lvp = unp->un_lowervp; 828 td = curthread; 829 830 if (uvp != NULLVP) { 831 if ((error = VOP_GETATTR(uvp, ap->a_vap, ap->a_cred)) == 0) 832 ap->a_vap->va_fsid = 833 ap->a_vp->v_mount->mnt_stat.f_fsid.val[0]; 834 835 UNIONFS_INTERNAL_DEBUG( 836 "unionfs_getattr: leave mode=%o, uid=%d, gid=%d (%d)\n", 837 ap->a_vap->va_mode, ap->a_vap->va_uid, 838 ap->a_vap->va_gid, error); 839 840 return (error); 841 } 842 843 error = VOP_GETATTR(lvp, ap->a_vap, ap->a_cred); 844 845 if (error == 0 && !(ump->um_uppervp->v_mount->mnt_flag & MNT_RDONLY)) { 846 /* correct the attr toward shadow file/dir. */ 847 if (ap->a_vp->v_type == VREG || ap->a_vp->v_type == VDIR) { 848 unionfs_create_uppervattr_core(ump, ap->a_vap, &va, td); 849 ap->a_vap->va_mode = va.va_mode; 850 ap->a_vap->va_uid = va.va_uid; 851 ap->a_vap->va_gid = va.va_gid; 852 } 853 } 854 855 if (error == 0) 856 ap->a_vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsid.val[0]; 857 858 UNIONFS_INTERNAL_DEBUG( 859 "unionfs_getattr: leave mode=%o, uid=%d, gid=%d (%d)\n", 860 ap->a_vap->va_mode, ap->a_vap->va_uid, ap->a_vap->va_gid, error); 861 862 return (error); 863 } 864 865 static int 866 unionfs_setattr(struct vop_setattr_args *ap) 867 { 868 struct unionfs_node *unp; 869 struct vnode *uvp; 870 struct vnode *lvp; 871 struct thread *td; 872 struct vattr *vap; 873 int error; 874 875 UNIONFS_INTERNAL_DEBUG("unionfs_setattr: enter\n"); 876 877 KASSERT_UNIONFS_VNODE(ap->a_vp); 878 879 error = EROFS; 880 unp = VTOUNIONFS(ap->a_vp); 881 uvp = unp->un_uppervp; 882 lvp = unp->un_lowervp; 883 td = curthread; 884 vap = ap->a_vap; 885 886 if ((ap->a_vp->v_mount->mnt_flag & MNT_RDONLY) && 887 (vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL || 888 vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL || 889 vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL)) 890 return (EROFS); 891 892 if (uvp == NULLVP && lvp->v_type == VREG) { 893 error = unionfs_copyfile(unp, (vap->va_size != 0), 894 ap->a_cred, td); 895 if (error != 0) 896 return (error); 897 uvp = unp->un_uppervp; 898 } 899 900 if (uvp != NULLVP) 901 error = VOP_SETATTR(uvp, vap, ap->a_cred); 902 903 UNIONFS_INTERNAL_DEBUG("unionfs_setattr: leave (%d)\n", error); 904 905 return (error); 906 } 907 908 static int 909 unionfs_read(struct vop_read_args *ap) 910 { 911 struct unionfs_node *unp; 912 struct vnode *tvp; 913 int error; 914 915 /* UNIONFS_INTERNAL_DEBUG("unionfs_read: enter\n"); */ 916 917 KASSERT_UNIONFS_VNODE(ap->a_vp); 918 919 unp = VTOUNIONFS(ap->a_vp); 920 tvp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); 921 922 error = VOP_READ(tvp, ap->a_uio, ap->a_ioflag, ap->a_cred); 923 924 /* UNIONFS_INTERNAL_DEBUG("unionfs_read: leave (%d)\n", error); */ 925 926 return (error); 927 } 928 929 static int 930 unionfs_write(struct vop_write_args *ap) 931 { 932 struct unionfs_node *unp; 933 struct vnode *tvp; 934 int error; 935 936 /* UNIONFS_INTERNAL_DEBUG("unionfs_write: enter\n"); */ 937 938 KASSERT_UNIONFS_VNODE(ap->a_vp); 939 940 unp = VTOUNIONFS(ap->a_vp); 941 tvp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); 942 943 error = VOP_WRITE(tvp, ap->a_uio, ap->a_ioflag, ap->a_cred); 944 945 /* UNIONFS_INTERNAL_DEBUG("unionfs_write: leave (%d)\n", error); */ 946 947 return (error); 948 } 949 950 static int 951 unionfs_ioctl(struct vop_ioctl_args *ap) 952 { 953 struct unionfs_node *unp; 954 struct unionfs_node_status *unsp; 955 struct vnode *ovp; 956 int error; 957 958 UNIONFS_INTERNAL_DEBUG("unionfs_ioctl: enter\n"); 959 960 KASSERT_UNIONFS_VNODE(ap->a_vp); 961 962 vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY); 963 unp = VTOUNIONFS(ap->a_vp); 964 unionfs_get_node_status(unp, ap->a_td, &unsp); 965 ovp = (unsp->uns_upper_opencnt ? unp->un_uppervp : unp->un_lowervp); 966 unionfs_tryrem_node_status(unp, unsp); 967 VOP_UNLOCK(ap->a_vp); 968 969 if (ovp == NULLVP) 970 return (EBADF); 971 972 error = VOP_IOCTL(ovp, ap->a_command, ap->a_data, ap->a_fflag, 973 ap->a_cred, ap->a_td); 974 975 UNIONFS_INTERNAL_DEBUG("unionfs_ioctl: leave (%d)\n", error); 976 977 return (error); 978 } 979 980 static int 981 unionfs_poll(struct vop_poll_args *ap) 982 { 983 struct unionfs_node *unp; 984 struct unionfs_node_status *unsp; 985 struct vnode *ovp; 986 987 KASSERT_UNIONFS_VNODE(ap->a_vp); 988 989 vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY); 990 unp = VTOUNIONFS(ap->a_vp); 991 unionfs_get_node_status(unp, ap->a_td, &unsp); 992 ovp = (unsp->uns_upper_opencnt ? unp->un_uppervp : unp->un_lowervp); 993 unionfs_tryrem_node_status(unp, unsp); 994 VOP_UNLOCK(ap->a_vp); 995 996 if (ovp == NULLVP) 997 return (EBADF); 998 999 return (VOP_POLL(ovp, ap->a_events, ap->a_cred, ap->a_td)); 1000 } 1001 1002 static int 1003 unionfs_fsync(struct vop_fsync_args *ap) 1004 { 1005 struct unionfs_node *unp; 1006 struct unionfs_node_status *unsp; 1007 struct vnode *ovp; 1008 1009 KASSERT_UNIONFS_VNODE(ap->a_vp); 1010 1011 unp = VTOUNIONFS(ap->a_vp); 1012 unionfs_get_node_status(unp, ap->a_td, &unsp); 1013 ovp = (unsp->uns_upper_opencnt ? unp->un_uppervp : unp->un_lowervp); 1014 unionfs_tryrem_node_status(unp, unsp); 1015 1016 if (ovp == NULLVP) 1017 return (EBADF); 1018 1019 return (VOP_FSYNC(ovp, ap->a_waitfor, ap->a_td)); 1020 } 1021 1022 static int 1023 unionfs_remove(struct vop_remove_args *ap) 1024 { 1025 char *path; 1026 struct unionfs_node *dunp; 1027 struct unionfs_node *unp; 1028 struct unionfs_mount *ump; 1029 struct vnode *udvp; 1030 struct vnode *uvp; 1031 struct vnode *lvp; 1032 struct vnode *vp; 1033 struct componentname *cnp; 1034 struct componentname cn; 1035 struct thread *td; 1036 int error; 1037 int pathlen; 1038 1039 UNIONFS_INTERNAL_DEBUG("unionfs_remove: enter\n"); 1040 1041 KASSERT_UNIONFS_VNODE(ap->a_dvp); 1042 1043 error = 0; 1044 dunp = VTOUNIONFS(ap->a_dvp); 1045 udvp = dunp->un_uppervp; 1046 cnp = ap->a_cnp; 1047 td = curthread; 1048 1049 if (ap->a_vp->v_op != &unionfs_vnodeops) { 1050 if (ap->a_vp->v_type != VSOCK) 1051 return (EINVAL); 1052 ump = NULL; 1053 vp = uvp = lvp = NULLVP; 1054 /* search vnode */ 1055 VOP_UNLOCK(ap->a_vp); 1056 error = unionfs_relookup(udvp, &vp, cnp, &cn, td, 1057 cnp->cn_nameptr, cnp->cn_namelen, DELETE); 1058 if (error != 0 && error != ENOENT) { 1059 vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY); 1060 return (error); 1061 } 1062 1063 if (error == 0 && vp == ap->a_vp) { 1064 /* target vnode in upper */ 1065 uvp = vp; 1066 vrele(vp); 1067 } else { 1068 /* target vnode in lower */ 1069 if (vp != NULLVP) { 1070 if (udvp == vp) 1071 vrele(vp); 1072 else 1073 vput(vp); 1074 } 1075 vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY); 1076 lvp = ap->a_vp; 1077 } 1078 path = cnp->cn_nameptr; 1079 pathlen = cnp->cn_namelen; 1080 } else { 1081 ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount); 1082 unp = VTOUNIONFS(ap->a_vp); 1083 uvp = unp->un_uppervp; 1084 lvp = unp->un_lowervp; 1085 path = unp->un_path; 1086 pathlen = unp->un_pathlen; 1087 } 1088 1089 if (udvp == NULLVP) 1090 return (EROFS); 1091 1092 if (uvp != NULLVP) { 1093 /* 1094 * XXX: if the vnode type is VSOCK, it will create whiteout 1095 * after remove. 1096 */ 1097 if (ump == NULL || ump->um_whitemode == UNIONFS_WHITE_ALWAYS || 1098 lvp != NULLVP) 1099 cnp->cn_flags |= DOWHITEOUT; 1100 error = VOP_REMOVE(udvp, uvp, cnp); 1101 } else if (lvp != NULLVP) 1102 error = unionfs_mkwhiteout(udvp, cnp, td, path, pathlen); 1103 1104 UNIONFS_INTERNAL_DEBUG("unionfs_remove: leave (%d)\n", error); 1105 1106 return (error); 1107 } 1108 1109 static int 1110 unionfs_link(struct vop_link_args *ap) 1111 { 1112 struct unionfs_node *dunp; 1113 struct unionfs_node *unp; 1114 struct vnode *udvp; 1115 struct vnode *uvp; 1116 struct componentname *cnp; 1117 struct thread *td; 1118 int error; 1119 int needrelookup; 1120 1121 UNIONFS_INTERNAL_DEBUG("unionfs_link: enter\n"); 1122 1123 KASSERT_UNIONFS_VNODE(ap->a_tdvp); 1124 KASSERT_UNIONFS_VNODE(ap->a_vp); 1125 1126 error = 0; 1127 needrelookup = 0; 1128 dunp = VTOUNIONFS(ap->a_tdvp); 1129 unp = NULL; 1130 udvp = dunp->un_uppervp; 1131 uvp = NULLVP; 1132 cnp = ap->a_cnp; 1133 td = curthread; 1134 1135 if (udvp == NULLVP) 1136 return (EROFS); 1137 1138 if (ap->a_vp->v_op != &unionfs_vnodeops) 1139 uvp = ap->a_vp; 1140 else { 1141 unp = VTOUNIONFS(ap->a_vp); 1142 1143 if (unp->un_uppervp == NULLVP) { 1144 if (ap->a_vp->v_type != VREG) 1145 return (EOPNOTSUPP); 1146 1147 error = unionfs_copyfile(unp, 1, cnp->cn_cred, td); 1148 if (error != 0) 1149 return (error); 1150 needrelookup = 1; 1151 } 1152 uvp = unp->un_uppervp; 1153 } 1154 1155 if (needrelookup != 0) 1156 error = unionfs_relookup_for_create(ap->a_tdvp, cnp, td); 1157 1158 if (error == 0) 1159 error = VOP_LINK(udvp, uvp, cnp); 1160 1161 UNIONFS_INTERNAL_DEBUG("unionfs_link: leave (%d)\n", error); 1162 1163 return (error); 1164 } 1165 1166 static int 1167 unionfs_rename(struct vop_rename_args *ap) 1168 { 1169 struct vnode *fdvp; 1170 struct vnode *fvp; 1171 struct componentname *fcnp; 1172 struct vnode *tdvp; 1173 struct vnode *tvp; 1174 struct componentname *tcnp; 1175 struct vnode *ltdvp; 1176 struct vnode *ltvp; 1177 struct thread *td; 1178 1179 /* rename target vnodes */ 1180 struct vnode *rfdvp; 1181 struct vnode *rfvp; 1182 struct vnode *rtdvp; 1183 struct vnode *rtvp; 1184 1185 struct unionfs_mount *ump; 1186 struct unionfs_node *unp; 1187 int error; 1188 int needrelookup; 1189 1190 UNIONFS_INTERNAL_DEBUG("unionfs_rename: enter\n"); 1191 1192 error = 0; 1193 fdvp = ap->a_fdvp; 1194 fvp = ap->a_fvp; 1195 fcnp = ap->a_fcnp; 1196 tdvp = ap->a_tdvp; 1197 tvp = ap->a_tvp; 1198 tcnp = ap->a_tcnp; 1199 ltdvp = NULLVP; 1200 ltvp = NULLVP; 1201 td = curthread; 1202 rfdvp = fdvp; 1203 rfvp = fvp; 1204 rtdvp = tdvp; 1205 rtvp = tvp; 1206 needrelookup = 0; 1207 1208 #ifdef DIAGNOSTIC 1209 if (!(fcnp->cn_flags & HASBUF) || !(tcnp->cn_flags & HASBUF)) 1210 panic("unionfs_rename: no name"); 1211 #endif 1212 1213 /* check for cross device rename */ 1214 if (fvp->v_mount != tdvp->v_mount || 1215 (tvp != NULLVP && fvp->v_mount != tvp->v_mount)) { 1216 if (fvp->v_op != &unionfs_vnodeops) 1217 error = ENODEV; 1218 else 1219 error = EXDEV; 1220 goto unionfs_rename_abort; 1221 } 1222 1223 /* Renaming a file to itself has no effect. */ 1224 if (fvp == tvp) 1225 goto unionfs_rename_abort; 1226 1227 /* 1228 * from/to vnode is unionfs node. 1229 */ 1230 1231 KASSERT_UNIONFS_VNODE(fdvp); 1232 KASSERT_UNIONFS_VNODE(fvp); 1233 KASSERT_UNIONFS_VNODE(tdvp); 1234 if (tvp != NULLVP) 1235 KASSERT_UNIONFS_VNODE(tvp); 1236 1237 unp = VTOUNIONFS(fdvp); 1238 #ifdef UNIONFS_IDBG_RENAME 1239 UNIONFS_INTERNAL_DEBUG("fdvp=%p, ufdvp=%p, lfdvp=%p\n", 1240 fdvp, unp->un_uppervp, unp->un_lowervp); 1241 #endif 1242 if (unp->un_uppervp == NULLVP) { 1243 error = ENODEV; 1244 goto unionfs_rename_abort; 1245 } 1246 rfdvp = unp->un_uppervp; 1247 vref(rfdvp); 1248 1249 unp = VTOUNIONFS(fvp); 1250 #ifdef UNIONFS_IDBG_RENAME 1251 UNIONFS_INTERNAL_DEBUG("fvp=%p, ufvp=%p, lfvp=%p\n", 1252 fvp, unp->un_uppervp, unp->un_lowervp); 1253 #endif 1254 ump = MOUNTTOUNIONFSMOUNT(fvp->v_mount); 1255 if (unp->un_uppervp == NULLVP) { 1256 switch (fvp->v_type) { 1257 case VREG: 1258 if ((error = vn_lock(fvp, LK_EXCLUSIVE)) != 0) 1259 goto unionfs_rename_abort; 1260 error = unionfs_copyfile(unp, 1, fcnp->cn_cred, td); 1261 VOP_UNLOCK(fvp); 1262 if (error != 0) 1263 goto unionfs_rename_abort; 1264 break; 1265 case VDIR: 1266 if ((error = vn_lock(fvp, LK_EXCLUSIVE)) != 0) 1267 goto unionfs_rename_abort; 1268 error = unionfs_mkshadowdir(ump, rfdvp, unp, fcnp, td); 1269 VOP_UNLOCK(fvp); 1270 if (error != 0) 1271 goto unionfs_rename_abort; 1272 break; 1273 default: 1274 error = ENODEV; 1275 goto unionfs_rename_abort; 1276 } 1277 1278 needrelookup = 1; 1279 } 1280 1281 if (unp->un_lowervp != NULLVP) 1282 fcnp->cn_flags |= DOWHITEOUT; 1283 rfvp = unp->un_uppervp; 1284 vref(rfvp); 1285 1286 unp = VTOUNIONFS(tdvp); 1287 #ifdef UNIONFS_IDBG_RENAME 1288 UNIONFS_INTERNAL_DEBUG("tdvp=%p, utdvp=%p, ltdvp=%p\n", 1289 tdvp, unp->un_uppervp, unp->un_lowervp); 1290 #endif 1291 if (unp->un_uppervp == NULLVP) { 1292 error = ENODEV; 1293 goto unionfs_rename_abort; 1294 } 1295 rtdvp = unp->un_uppervp; 1296 ltdvp = unp->un_lowervp; 1297 vref(rtdvp); 1298 1299 if (tdvp == tvp) { 1300 rtvp = rtdvp; 1301 vref(rtvp); 1302 } else if (tvp != NULLVP) { 1303 unp = VTOUNIONFS(tvp); 1304 #ifdef UNIONFS_IDBG_RENAME 1305 UNIONFS_INTERNAL_DEBUG("tvp=%p, utvp=%p, ltvp=%p\n", 1306 tvp, unp->un_uppervp, unp->un_lowervp); 1307 #endif 1308 if (unp->un_uppervp == NULLVP) 1309 rtvp = NULLVP; 1310 else { 1311 if (tvp->v_type == VDIR) { 1312 error = EINVAL; 1313 goto unionfs_rename_abort; 1314 } 1315 rtvp = unp->un_uppervp; 1316 ltvp = unp->un_lowervp; 1317 vref(rtvp); 1318 } 1319 } 1320 1321 if (rfvp == rtvp) 1322 goto unionfs_rename_abort; 1323 1324 if (needrelookup != 0) { 1325 if ((error = vn_lock(fdvp, LK_EXCLUSIVE)) != 0) 1326 goto unionfs_rename_abort; 1327 error = unionfs_relookup_for_delete(fdvp, fcnp, td); 1328 VOP_UNLOCK(fdvp); 1329 if (error != 0) 1330 goto unionfs_rename_abort; 1331 1332 /* Lock of tvp is canceled in order to avoid recursive lock. */ 1333 if (tvp != NULLVP && tvp != tdvp) 1334 VOP_UNLOCK(tvp); 1335 error = unionfs_relookup_for_rename(tdvp, tcnp, td); 1336 if (tvp != NULLVP && tvp != tdvp) 1337 vn_lock(tvp, LK_EXCLUSIVE | LK_RETRY); 1338 if (error != 0) 1339 goto unionfs_rename_abort; 1340 } 1341 1342 error = VOP_RENAME(rfdvp, rfvp, fcnp, rtdvp, rtvp, tcnp); 1343 1344 if (error == 0) { 1345 if (rtvp != NULLVP && rtvp->v_type == VDIR) 1346 cache_purge(tdvp); 1347 if (fvp->v_type == VDIR && fdvp != tdvp) 1348 cache_purge(fdvp); 1349 } 1350 1351 if (ltdvp != NULLVP) 1352 VOP_UNLOCK(ltdvp); 1353 if (tdvp != rtdvp) 1354 vrele(tdvp); 1355 if (ltvp != NULLVP) 1356 VOP_UNLOCK(ltvp); 1357 if (tvp != rtvp && tvp != NULLVP) { 1358 if (rtvp == NULLVP) 1359 vput(tvp); 1360 else 1361 vrele(tvp); 1362 } 1363 if (fdvp != rfdvp) 1364 vrele(fdvp); 1365 if (fvp != rfvp) 1366 vrele(fvp); 1367 1368 UNIONFS_INTERNAL_DEBUG("unionfs_rename: leave (%d)\n", error); 1369 1370 return (error); 1371 1372 unionfs_rename_abort: 1373 vput(tdvp); 1374 if (tdvp != rtdvp) 1375 vrele(rtdvp); 1376 if (tvp != NULLVP) { 1377 if (tdvp != tvp) 1378 vput(tvp); 1379 else 1380 vrele(tvp); 1381 } 1382 if (tvp != rtvp && rtvp != NULLVP) 1383 vrele(rtvp); 1384 if (fdvp != rfdvp) 1385 vrele(rfdvp); 1386 if (fvp != rfvp) 1387 vrele(rfvp); 1388 vrele(fdvp); 1389 vrele(fvp); 1390 1391 UNIONFS_INTERNAL_DEBUG("unionfs_rename: leave (%d)\n", error); 1392 1393 return (error); 1394 } 1395 1396 static int 1397 unionfs_mkdir(struct vop_mkdir_args *ap) 1398 { 1399 struct unionfs_node *dunp; 1400 struct componentname *cnp; 1401 struct vnode *udvp; 1402 struct vnode *uvp; 1403 struct vattr va; 1404 int error; 1405 int lkflags; 1406 1407 UNIONFS_INTERNAL_DEBUG("unionfs_mkdir: enter\n"); 1408 1409 KASSERT_UNIONFS_VNODE(ap->a_dvp); 1410 1411 error = EROFS; 1412 dunp = VTOUNIONFS(ap->a_dvp); 1413 cnp = ap->a_cnp; 1414 lkflags = cnp->cn_lkflags; 1415 udvp = dunp->un_uppervp; 1416 1417 if (udvp != NULLVP) { 1418 /* check opaque */ 1419 if (!(cnp->cn_flags & ISWHITEOUT)) { 1420 error = VOP_GETATTR(udvp, &va, cnp->cn_cred); 1421 if (error != 0) 1422 return (error); 1423 if ((va.va_flags & OPAQUE) != 0) 1424 cnp->cn_flags |= ISWHITEOUT; 1425 } 1426 1427 if ((error = VOP_MKDIR(udvp, &uvp, cnp, ap->a_vap)) == 0) { 1428 VOP_UNLOCK(uvp); 1429 cnp->cn_lkflags = LK_EXCLUSIVE; 1430 error = unionfs_nodeget(ap->a_dvp->v_mount, uvp, NULLVP, 1431 ap->a_dvp, ap->a_vpp, cnp); 1432 cnp->cn_lkflags = lkflags; 1433 vrele(uvp); 1434 } 1435 } 1436 1437 UNIONFS_INTERNAL_DEBUG("unionfs_mkdir: leave (%d)\n", error); 1438 1439 return (error); 1440 } 1441 1442 static int 1443 unionfs_rmdir(struct vop_rmdir_args *ap) 1444 { 1445 struct unionfs_node *dunp; 1446 struct unionfs_node *unp; 1447 struct unionfs_mount *ump; 1448 struct componentname *cnp; 1449 struct thread *td; 1450 struct vnode *udvp; 1451 struct vnode *uvp; 1452 struct vnode *lvp; 1453 int error; 1454 1455 UNIONFS_INTERNAL_DEBUG("unionfs_rmdir: enter\n"); 1456 1457 KASSERT_UNIONFS_VNODE(ap->a_dvp); 1458 KASSERT_UNIONFS_VNODE(ap->a_vp); 1459 1460 error = 0; 1461 dunp = VTOUNIONFS(ap->a_dvp); 1462 unp = VTOUNIONFS(ap->a_vp); 1463 cnp = ap->a_cnp; 1464 td = curthread; 1465 udvp = dunp->un_uppervp; 1466 uvp = unp->un_uppervp; 1467 lvp = unp->un_lowervp; 1468 1469 if (udvp == NULLVP) 1470 return (EROFS); 1471 1472 if (udvp == uvp) 1473 return (EOPNOTSUPP); 1474 1475 if (uvp != NULLVP) { 1476 if (lvp != NULLVP) { 1477 error = unionfs_check_rmdir(ap->a_vp, cnp->cn_cred, td); 1478 if (error != 0) 1479 return (error); 1480 } 1481 ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount); 1482 if (ump->um_whitemode == UNIONFS_WHITE_ALWAYS || lvp != NULLVP) 1483 cnp->cn_flags |= DOWHITEOUT; 1484 /* 1485 * The relookup path will need to relock the parent dvp and 1486 * possibly the vp as well. Locking is expected to be done 1487 * in parent->child order; drop the lock on vp to avoid LOR 1488 * and potential recursion on vp's lock. 1489 * vp is expected to remain referenced during VOP_RMDIR(), 1490 * so vref/vrele should not be necessary here. 1491 */ 1492 VOP_UNLOCK(ap->a_vp); 1493 VNPASS(vrefcnt(ap->a_vp) > 0, ap->a_vp); 1494 error = unionfs_relookup_for_delete(ap->a_dvp, cnp, td); 1495 vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY); 1496 /* 1497 * VOP_RMDIR is dispatched against udvp, so if uvp became 1498 * doomed while the lock was dropped above the target 1499 * filesystem may not be able to cope. 1500 */ 1501 if (error == 0 && VN_IS_DOOMED(uvp)) 1502 error = ENOENT; 1503 if (error == 0) 1504 error = VOP_RMDIR(udvp, uvp, cnp); 1505 } else if (lvp != NULLVP) 1506 error = unionfs_mkwhiteout(udvp, cnp, td, 1507 unp->un_path, unp->un_pathlen); 1508 1509 if (error == 0) { 1510 cache_purge(ap->a_dvp); 1511 cache_purge(ap->a_vp); 1512 } 1513 1514 UNIONFS_INTERNAL_DEBUG("unionfs_rmdir: leave (%d)\n", error); 1515 1516 return (error); 1517 } 1518 1519 static int 1520 unionfs_symlink(struct vop_symlink_args *ap) 1521 { 1522 struct unionfs_node *dunp; 1523 struct componentname *cnp; 1524 struct vnode *udvp; 1525 struct vnode *uvp; 1526 int error; 1527 int lkflags; 1528 1529 UNIONFS_INTERNAL_DEBUG("unionfs_symlink: enter\n"); 1530 1531 KASSERT_UNIONFS_VNODE(ap->a_dvp); 1532 1533 error = EROFS; 1534 dunp = VTOUNIONFS(ap->a_dvp); 1535 cnp = ap->a_cnp; 1536 lkflags = cnp->cn_lkflags; 1537 udvp = dunp->un_uppervp; 1538 1539 if (udvp != NULLVP) { 1540 error = VOP_SYMLINK(udvp, &uvp, cnp, ap->a_vap, ap->a_target); 1541 if (error == 0) { 1542 VOP_UNLOCK(uvp); 1543 cnp->cn_lkflags = LK_EXCLUSIVE; 1544 error = unionfs_nodeget(ap->a_dvp->v_mount, uvp, NULLVP, 1545 ap->a_dvp, ap->a_vpp, cnp); 1546 cnp->cn_lkflags = lkflags; 1547 vrele(uvp); 1548 } 1549 } 1550 1551 UNIONFS_INTERNAL_DEBUG("unionfs_symlink: leave (%d)\n", error); 1552 1553 return (error); 1554 } 1555 1556 static int 1557 unionfs_readdir(struct vop_readdir_args *ap) 1558 { 1559 struct unionfs_node *unp; 1560 struct unionfs_node_status *unsp; 1561 struct uio *uio; 1562 struct vnode *vp; 1563 struct vnode *uvp; 1564 struct vnode *lvp; 1565 struct thread *td; 1566 struct vattr va; 1567 1568 uint64_t *cookies_bk; 1569 int error; 1570 int eofflag; 1571 int ncookies_bk; 1572 int uio_offset_bk; 1573 enum unionfs_lkupgrade lkstatus; 1574 1575 UNIONFS_INTERNAL_DEBUG("unionfs_readdir: enter\n"); 1576 1577 KASSERT_UNIONFS_VNODE(ap->a_vp); 1578 1579 error = 0; 1580 eofflag = 0; 1581 uio_offset_bk = 0; 1582 uio = ap->a_uio; 1583 uvp = NULLVP; 1584 lvp = NULLVP; 1585 td = uio->uio_td; 1586 ncookies_bk = 0; 1587 cookies_bk = NULL; 1588 1589 vp = ap->a_vp; 1590 if (vp->v_type != VDIR) 1591 return (ENOTDIR); 1592 1593 /* 1594 * If the vnode is reclaimed while upgrading, we can't safely use unp 1595 * or do anything else unionfs- specific. 1596 */ 1597 lkstatus = unionfs_upgrade_lock(vp); 1598 if (lkstatus == UNIONFS_LKUPGRADE_DOOMED) 1599 error = EBADF; 1600 if (error == 0) { 1601 unp = VTOUNIONFS(vp); 1602 uvp = unp->un_uppervp; 1603 lvp = unp->un_lowervp; 1604 /* check the open count. unionfs needs open before readdir. */ 1605 unionfs_get_node_status(unp, td, &unsp); 1606 if ((uvp != NULLVP && unsp->uns_upper_opencnt <= 0) || 1607 (lvp != NULLVP && unsp->uns_lower_opencnt <= 0)) { 1608 unionfs_tryrem_node_status(unp, unsp); 1609 error = EBADF; 1610 } 1611 } 1612 unionfs_downgrade_lock(vp, lkstatus); 1613 if (error != 0) 1614 goto unionfs_readdir_exit; 1615 1616 /* check opaque */ 1617 if (uvp != NULLVP && lvp != NULLVP) { 1618 if ((error = VOP_GETATTR(uvp, &va, ap->a_cred)) != 0) 1619 goto unionfs_readdir_exit; 1620 if (va.va_flags & OPAQUE) 1621 lvp = NULLVP; 1622 } 1623 1624 /* upper only */ 1625 if (uvp != NULLVP && lvp == NULLVP) { 1626 error = VOP_READDIR(uvp, uio, ap->a_cred, ap->a_eofflag, 1627 ap->a_ncookies, ap->a_cookies); 1628 unsp->uns_readdir_status = 0; 1629 1630 goto unionfs_readdir_exit; 1631 } 1632 1633 /* lower only */ 1634 if (uvp == NULLVP && lvp != NULLVP) { 1635 error = VOP_READDIR(lvp, uio, ap->a_cred, ap->a_eofflag, 1636 ap->a_ncookies, ap->a_cookies); 1637 unsp->uns_readdir_status = 2; 1638 1639 goto unionfs_readdir_exit; 1640 } 1641 1642 /* 1643 * readdir upper and lower 1644 */ 1645 KASSERT(uvp != NULLVP, ("unionfs_readdir: null upper vp")); 1646 KASSERT(lvp != NULLVP, ("unionfs_readdir: null lower vp")); 1647 if (uio->uio_offset == 0) 1648 unsp->uns_readdir_status = 0; 1649 1650 if (unsp->uns_readdir_status == 0) { 1651 /* read upper */ 1652 error = VOP_READDIR(uvp, uio, ap->a_cred, &eofflag, 1653 ap->a_ncookies, ap->a_cookies); 1654 1655 if (error != 0 || eofflag == 0) 1656 goto unionfs_readdir_exit; 1657 unsp->uns_readdir_status = 1; 1658 1659 /* 1660 * UFS(and other FS) needs size of uio_resid larger than 1661 * DIRBLKSIZ. 1662 * size of DIRBLKSIZ equals DEV_BSIZE. 1663 * (see: ufs/ufs/ufs_vnops.c ufs_readdir func , ufs/ufs/dir.h) 1664 */ 1665 if (uio->uio_resid <= (uio->uio_resid & (DEV_BSIZE -1))) 1666 goto unionfs_readdir_exit; 1667 1668 /* 1669 * Backup cookies. 1670 * It prepares to readdir in lower. 1671 */ 1672 if (ap->a_ncookies != NULL) { 1673 ncookies_bk = *(ap->a_ncookies); 1674 *(ap->a_ncookies) = 0; 1675 } 1676 if (ap->a_cookies != NULL) { 1677 cookies_bk = *(ap->a_cookies); 1678 *(ap->a_cookies) = NULL; 1679 } 1680 } 1681 1682 /* initialize for readdir in lower */ 1683 if (unsp->uns_readdir_status == 1) { 1684 unsp->uns_readdir_status = 2; 1685 /* 1686 * Backup uio_offset. See the comment after the 1687 * VOP_READDIR call on the lower layer. 1688 */ 1689 uio_offset_bk = uio->uio_offset; 1690 uio->uio_offset = 0; 1691 } 1692 1693 if (lvp == NULLVP) { 1694 error = EBADF; 1695 goto unionfs_readdir_exit; 1696 } 1697 /* read lower */ 1698 error = VOP_READDIR(lvp, uio, ap->a_cred, ap->a_eofflag, 1699 ap->a_ncookies, ap->a_cookies); 1700 1701 /* 1702 * We can't return an uio_offset of 0: this would trigger an 1703 * infinite loop, because the next call to unionfs_readdir would 1704 * always restart with the upper layer (uio_offset == 0) and 1705 * always return some data. 1706 * 1707 * This happens when the lower layer root directory is removed. 1708 * (A root directory deleting of unionfs should not be permitted. 1709 * But current VFS can not do it.) 1710 */ 1711 if (uio->uio_offset == 0) 1712 uio->uio_offset = uio_offset_bk; 1713 1714 if (cookies_bk != NULL) { 1715 /* merge cookies */ 1716 int size; 1717 uint64_t *newcookies, *pos; 1718 1719 size = *(ap->a_ncookies) + ncookies_bk; 1720 newcookies = (uint64_t *) malloc(size * sizeof(*newcookies), 1721 M_TEMP, M_WAITOK); 1722 pos = newcookies; 1723 1724 memcpy(pos, cookies_bk, ncookies_bk * sizeof(*newcookies)); 1725 pos += ncookies_bk; 1726 memcpy(pos, *(ap->a_cookies), 1727 *(ap->a_ncookies) * sizeof(*newcookies)); 1728 free(cookies_bk, M_TEMP); 1729 free(*(ap->a_cookies), M_TEMP); 1730 *(ap->a_ncookies) = size; 1731 *(ap->a_cookies) = newcookies; 1732 } 1733 1734 unionfs_readdir_exit: 1735 if (error != 0 && ap->a_eofflag != NULL) 1736 *(ap->a_eofflag) = 1; 1737 1738 UNIONFS_INTERNAL_DEBUG("unionfs_readdir: leave (%d)\n", error); 1739 1740 return (error); 1741 } 1742 1743 static int 1744 unionfs_readlink(struct vop_readlink_args *ap) 1745 { 1746 struct unionfs_node *unp; 1747 struct vnode *vp; 1748 int error; 1749 1750 UNIONFS_INTERNAL_DEBUG("unionfs_readlink: enter\n"); 1751 1752 KASSERT_UNIONFS_VNODE(ap->a_vp); 1753 1754 unp = VTOUNIONFS(ap->a_vp); 1755 vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); 1756 1757 error = VOP_READLINK(vp, ap->a_uio, ap->a_cred); 1758 1759 UNIONFS_INTERNAL_DEBUG("unionfs_readlink: leave (%d)\n", error); 1760 1761 return (error); 1762 } 1763 1764 static int 1765 unionfs_getwritemount(struct vop_getwritemount_args *ap) 1766 { 1767 struct unionfs_node *unp; 1768 struct vnode *uvp; 1769 struct vnode *vp, *ovp; 1770 int error; 1771 1772 UNIONFS_INTERNAL_DEBUG("unionfs_getwritemount: enter\n"); 1773 1774 error = 0; 1775 vp = ap->a_vp; 1776 uvp = NULLVP; 1777 1778 VI_LOCK(vp); 1779 unp = VTOUNIONFS(vp); 1780 if (unp != NULL) 1781 uvp = unp->un_uppervp; 1782 1783 /* 1784 * If our node has no upper vnode, check the parent directory. 1785 * We may be initiating a write operation that will produce a 1786 * new upper vnode through CoW. 1787 */ 1788 if (uvp == NULLVP && unp != NULL) { 1789 ovp = vp; 1790 vp = unp->un_dvp; 1791 /* 1792 * Only the root vnode should have an empty parent, but it 1793 * should not have an empty uppervp, so we shouldn't get here. 1794 */ 1795 VNASSERT(vp != NULL, ovp, ("%s: NULL parent vnode", __func__)); 1796 VI_UNLOCK(ovp); 1797 VI_LOCK(vp); 1798 unp = VTOUNIONFS(vp); 1799 if (unp != NULL) 1800 uvp = unp->un_uppervp; 1801 if (uvp == NULLVP) 1802 error = EACCES; 1803 } 1804 1805 if (uvp != NULLVP) { 1806 vholdnz(uvp); 1807 VI_UNLOCK(vp); 1808 error = VOP_GETWRITEMOUNT(uvp, ap->a_mpp); 1809 vdrop(uvp); 1810 } else { 1811 VI_UNLOCK(vp); 1812 *(ap->a_mpp) = NULL; 1813 } 1814 1815 UNIONFS_INTERNAL_DEBUG("unionfs_getwritemount: leave (%d)\n", error); 1816 1817 return (error); 1818 } 1819 1820 static int 1821 unionfs_inactive(struct vop_inactive_args *ap) 1822 { 1823 ap->a_vp->v_object = NULL; 1824 vrecycle(ap->a_vp); 1825 return (0); 1826 } 1827 1828 static int 1829 unionfs_reclaim(struct vop_reclaim_args *ap) 1830 { 1831 /* UNIONFS_INTERNAL_DEBUG("unionfs_reclaim: enter\n"); */ 1832 1833 unionfs_noderem(ap->a_vp); 1834 1835 /* UNIONFS_INTERNAL_DEBUG("unionfs_reclaim: leave\n"); */ 1836 1837 return (0); 1838 } 1839 1840 static int 1841 unionfs_print(struct vop_print_args *ap) 1842 { 1843 struct unionfs_node *unp; 1844 /* struct unionfs_node_status *unsp; */ 1845 1846 unp = VTOUNIONFS(ap->a_vp); 1847 /* unionfs_get_node_status(unp, curthread, &unsp); */ 1848 1849 printf("unionfs_vp=%p, uppervp=%p, lowervp=%p\n", 1850 ap->a_vp, unp->un_uppervp, unp->un_lowervp); 1851 /* 1852 printf("unionfs opencnt: uppervp=%d, lowervp=%d\n", 1853 unsp->uns_upper_opencnt, unsp->uns_lower_opencnt); 1854 */ 1855 1856 if (unp->un_uppervp != NULLVP) 1857 vn_printf(unp->un_uppervp, "unionfs: upper "); 1858 if (unp->un_lowervp != NULLVP) 1859 vn_printf(unp->un_lowervp, "unionfs: lower "); 1860 1861 return (0); 1862 } 1863 1864 static int 1865 unionfs_islocked(struct vop_islocked_args *ap) 1866 { 1867 struct unionfs_node *unp; 1868 1869 KASSERT_UNIONFS_VNODE(ap->a_vp); 1870 1871 unp = VTOUNIONFS(ap->a_vp); 1872 if (unp == NULL) 1873 return (vop_stdislocked(ap)); 1874 1875 if (unp->un_uppervp != NULLVP) 1876 return (VOP_ISLOCKED(unp->un_uppervp)); 1877 if (unp->un_lowervp != NULLVP) 1878 return (VOP_ISLOCKED(unp->un_lowervp)); 1879 return (vop_stdislocked(ap)); 1880 } 1881 1882 static int 1883 unionfs_get_llt_revlock(struct vnode *vp, int flags) 1884 { 1885 int revlock; 1886 1887 revlock = 0; 1888 1889 switch (flags & LK_TYPE_MASK) { 1890 case LK_SHARED: 1891 if (VOP_ISLOCKED(vp) == LK_EXCLUSIVE) 1892 revlock = LK_UPGRADE; 1893 else 1894 revlock = LK_RELEASE; 1895 break; 1896 case LK_EXCLUSIVE: 1897 case LK_UPGRADE: 1898 revlock = LK_RELEASE; 1899 break; 1900 case LK_DOWNGRADE: 1901 revlock = LK_UPGRADE; 1902 break; 1903 default: 1904 break; 1905 } 1906 1907 return (revlock); 1908 } 1909 1910 /* 1911 * The state of an acquired lock is adjusted similarly to 1912 * the time of error generating. 1913 * flags: LK_RELEASE or LK_UPGRADE 1914 */ 1915 static void 1916 unionfs_revlock(struct vnode *vp, int flags) 1917 { 1918 if (flags & LK_RELEASE) 1919 VOP_UNLOCK_FLAGS(vp, flags); 1920 else { 1921 /* UPGRADE */ 1922 if (vn_lock(vp, flags) != 0) 1923 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 1924 } 1925 } 1926 1927 static int 1928 unionfs_lock(struct vop_lock1_args *ap) 1929 { 1930 struct unionfs_node *unp; 1931 struct vnode *vp; 1932 struct vnode *uvp; 1933 struct vnode *lvp; 1934 int error; 1935 int flags; 1936 int revlock; 1937 int interlock; 1938 int uhold; 1939 1940 /* 1941 * TODO: rework the unionfs locking scheme. 1942 * It's not guaranteed to be safe to blindly lock two vnodes on 1943 * different mounts as is done here. Further, the entanglement 1944 * of locking both vnodes with the various options that can be 1945 * passed to VOP_LOCK() makes this code hard to reason about. 1946 * Instead, consider locking only the upper vnode, or the lower 1947 * vnode is the upper is not present, and taking separate measures 1948 * to lock both vnodes in the few cases when that is needed. 1949 */ 1950 error = 0; 1951 interlock = 1; 1952 uhold = 0; 1953 flags = ap->a_flags; 1954 vp = ap->a_vp; 1955 1956 if (LK_RELEASE == (flags & LK_TYPE_MASK) || !(flags & LK_TYPE_MASK)) 1957 return (VOP_UNLOCK_FLAGS(vp, flags | LK_RELEASE)); 1958 1959 if ((flags & LK_INTERLOCK) == 0) 1960 VI_LOCK(vp); 1961 1962 unp = VTOUNIONFS(vp); 1963 if (unp == NULL) 1964 goto unionfs_lock_null_vnode; 1965 1966 KASSERT_UNIONFS_VNODE(ap->a_vp); 1967 1968 lvp = unp->un_lowervp; 1969 uvp = unp->un_uppervp; 1970 1971 if ((revlock = unionfs_get_llt_revlock(vp, flags)) == 0) 1972 panic("unknown lock type: 0x%x", flags & LK_TYPE_MASK); 1973 1974 /* 1975 * During unmount, the root vnode lock may be taken recursively, 1976 * because it may share the same v_vnlock field as the vnode covered by 1977 * the unionfs mount. The covered vnode is locked across VFS_UNMOUNT(), 1978 * and the same lock may be taken recursively here during vflush() 1979 * issued by unionfs_unmount(). 1980 */ 1981 if ((flags & LK_TYPE_MASK) == LK_EXCLUSIVE && 1982 (vp->v_vflag & VV_ROOT) != 0) 1983 flags |= LK_CANRECURSE; 1984 1985 if (lvp != NULLVP) { 1986 if (uvp != NULLVP && flags & LK_UPGRADE) { 1987 /* 1988 * Share Lock is once released and a deadlock is 1989 * avoided. 1990 */ 1991 vholdnz(uvp); 1992 uhold = 1; 1993 VOP_UNLOCK(uvp); 1994 unp = VTOUNIONFS(vp); 1995 if (unp == NULL) { 1996 /* vnode is released. */ 1997 VI_UNLOCK(vp); 1998 VOP_UNLOCK(lvp); 1999 vdrop(uvp); 2000 return (EBUSY); 2001 } 2002 } 2003 VI_LOCK_FLAGS(lvp, MTX_DUPOK); 2004 flags |= LK_INTERLOCK; 2005 vholdl(lvp); 2006 2007 VI_UNLOCK(vp); 2008 ap->a_flags &= ~LK_INTERLOCK; 2009 2010 error = VOP_LOCK(lvp, flags); 2011 2012 VI_LOCK(vp); 2013 unp = VTOUNIONFS(vp); 2014 if (unp == NULL) { 2015 /* vnode is released. */ 2016 VI_UNLOCK(vp); 2017 if (error == 0) 2018 VOP_UNLOCK(lvp); 2019 vdrop(lvp); 2020 if (uhold != 0) 2021 vdrop(uvp); 2022 return (vop_stdlock(ap)); 2023 } 2024 } 2025 2026 if (error == 0 && uvp != NULLVP) { 2027 if (uhold && flags & LK_UPGRADE) { 2028 flags &= ~LK_TYPE_MASK; 2029 flags |= LK_EXCLUSIVE; 2030 } 2031 VI_LOCK_FLAGS(uvp, MTX_DUPOK); 2032 flags |= LK_INTERLOCK; 2033 if (uhold == 0) { 2034 vholdl(uvp); 2035 uhold = 1; 2036 } 2037 2038 VI_UNLOCK(vp); 2039 ap->a_flags &= ~LK_INTERLOCK; 2040 2041 error = VOP_LOCK(uvp, flags); 2042 2043 VI_LOCK(vp); 2044 unp = VTOUNIONFS(vp); 2045 if (unp == NULL) { 2046 /* vnode is released. */ 2047 VI_UNLOCK(vp); 2048 if (error == 0) 2049 VOP_UNLOCK(uvp); 2050 vdrop(uvp); 2051 if (lvp != NULLVP) { 2052 VOP_UNLOCK(lvp); 2053 vdrop(lvp); 2054 } 2055 return (vop_stdlock(ap)); 2056 } 2057 if (error != 0 && lvp != NULLVP) { 2058 /* rollback */ 2059 VI_UNLOCK(vp); 2060 unionfs_revlock(lvp, revlock); 2061 interlock = 0; 2062 } 2063 } 2064 2065 if (interlock) 2066 VI_UNLOCK(vp); 2067 if (lvp != NULLVP) 2068 vdrop(lvp); 2069 if (uhold != 0) 2070 vdrop(uvp); 2071 2072 return (error); 2073 2074 unionfs_lock_null_vnode: 2075 ap->a_flags |= LK_INTERLOCK; 2076 return (vop_stdlock(ap)); 2077 } 2078 2079 static int 2080 unionfs_unlock(struct vop_unlock_args *ap) 2081 { 2082 struct vnode *vp; 2083 struct vnode *lvp; 2084 struct vnode *uvp; 2085 struct unionfs_node *unp; 2086 int error; 2087 int uhold; 2088 2089 KASSERT_UNIONFS_VNODE(ap->a_vp); 2090 2091 error = 0; 2092 uhold = 0; 2093 vp = ap->a_vp; 2094 2095 unp = VTOUNIONFS(vp); 2096 if (unp == NULL) 2097 goto unionfs_unlock_null_vnode; 2098 lvp = unp->un_lowervp; 2099 uvp = unp->un_uppervp; 2100 2101 if (lvp != NULLVP) { 2102 vholdnz(lvp); 2103 error = VOP_UNLOCK(lvp); 2104 } 2105 2106 if (error == 0 && uvp != NULLVP) { 2107 vholdnz(uvp); 2108 uhold = 1; 2109 error = VOP_UNLOCK(uvp); 2110 } 2111 2112 if (lvp != NULLVP) 2113 vdrop(lvp); 2114 if (uhold != 0) 2115 vdrop(uvp); 2116 2117 return error; 2118 2119 unionfs_unlock_null_vnode: 2120 return (vop_stdunlock(ap)); 2121 } 2122 2123 static int 2124 unionfs_pathconf(struct vop_pathconf_args *ap) 2125 { 2126 struct unionfs_node *unp; 2127 struct vnode *vp; 2128 2129 KASSERT_UNIONFS_VNODE(ap->a_vp); 2130 2131 unp = VTOUNIONFS(ap->a_vp); 2132 vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); 2133 2134 return (VOP_PATHCONF(vp, ap->a_name, ap->a_retval)); 2135 } 2136 2137 static int 2138 unionfs_advlock(struct vop_advlock_args *ap) 2139 { 2140 struct unionfs_node *unp; 2141 struct unionfs_node_status *unsp; 2142 struct vnode *vp; 2143 struct vnode *uvp; 2144 struct thread *td; 2145 int error; 2146 2147 UNIONFS_INTERNAL_DEBUG("unionfs_advlock: enter\n"); 2148 2149 KASSERT_UNIONFS_VNODE(ap->a_vp); 2150 2151 vp = ap->a_vp; 2152 td = curthread; 2153 2154 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2155 2156 unp = VTOUNIONFS(ap->a_vp); 2157 uvp = unp->un_uppervp; 2158 2159 if (uvp == NULLVP) { 2160 error = unionfs_copyfile(unp, 1, td->td_ucred, td); 2161 if (error != 0) 2162 goto unionfs_advlock_abort; 2163 uvp = unp->un_uppervp; 2164 2165 unionfs_get_node_status(unp, td, &unsp); 2166 if (unsp->uns_lower_opencnt > 0) { 2167 /* try reopen the vnode */ 2168 error = VOP_OPEN(uvp, unsp->uns_lower_openmode, 2169 td->td_ucred, td, NULL); 2170 if (error) 2171 goto unionfs_advlock_abort; 2172 unsp->uns_upper_opencnt++; 2173 VOP_CLOSE(unp->un_lowervp, unsp->uns_lower_openmode, 2174 td->td_ucred, td); 2175 unsp->uns_lower_opencnt--; 2176 } else 2177 unionfs_tryrem_node_status(unp, unsp); 2178 } 2179 2180 VOP_UNLOCK(vp); 2181 2182 error = VOP_ADVLOCK(uvp, ap->a_id, ap->a_op, ap->a_fl, ap->a_flags); 2183 2184 UNIONFS_INTERNAL_DEBUG("unionfs_advlock: leave (%d)\n", error); 2185 2186 return error; 2187 2188 unionfs_advlock_abort: 2189 VOP_UNLOCK(vp); 2190 2191 UNIONFS_INTERNAL_DEBUG("unionfs_advlock: leave (%d)\n", error); 2192 2193 return error; 2194 } 2195 2196 static int 2197 unionfs_strategy(struct vop_strategy_args *ap) 2198 { 2199 struct unionfs_node *unp; 2200 struct vnode *vp; 2201 2202 KASSERT_UNIONFS_VNODE(ap->a_vp); 2203 2204 unp = VTOUNIONFS(ap->a_vp); 2205 vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); 2206 2207 #ifdef DIAGNOSTIC 2208 if (vp == NULLVP) 2209 panic("unionfs_strategy: nullvp"); 2210 2211 if (ap->a_bp->b_iocmd == BIO_WRITE && vp == unp->un_lowervp) 2212 panic("unionfs_strategy: writing to lowervp"); 2213 #endif 2214 2215 return (VOP_STRATEGY(vp, ap->a_bp)); 2216 } 2217 2218 static int 2219 unionfs_getacl(struct vop_getacl_args *ap) 2220 { 2221 struct unionfs_node *unp; 2222 struct vnode *vp; 2223 int error; 2224 2225 KASSERT_UNIONFS_VNODE(ap->a_vp); 2226 2227 unp = VTOUNIONFS(ap->a_vp); 2228 vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); 2229 2230 UNIONFS_INTERNAL_DEBUG("unionfs_getacl: enter\n"); 2231 2232 error = VOP_GETACL(vp, ap->a_type, ap->a_aclp, ap->a_cred, ap->a_td); 2233 2234 UNIONFS_INTERNAL_DEBUG("unionfs_getacl: leave (%d)\n", error); 2235 2236 return (error); 2237 } 2238 2239 static int 2240 unionfs_setacl(struct vop_setacl_args *ap) 2241 { 2242 struct unionfs_node *unp; 2243 struct vnode *uvp; 2244 struct vnode *lvp; 2245 struct thread *td; 2246 int error; 2247 2248 UNIONFS_INTERNAL_DEBUG("unionfs_setacl: enter\n"); 2249 2250 KASSERT_UNIONFS_VNODE(ap->a_vp); 2251 2252 error = EROFS; 2253 unp = VTOUNIONFS(ap->a_vp); 2254 uvp = unp->un_uppervp; 2255 lvp = unp->un_lowervp; 2256 td = ap->a_td; 2257 2258 if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY) 2259 return (EROFS); 2260 2261 if (uvp == NULLVP && lvp->v_type == VREG) { 2262 if ((error = unionfs_copyfile(unp, 1, ap->a_cred, td)) != 0) 2263 return (error); 2264 uvp = unp->un_uppervp; 2265 } 2266 2267 if (uvp != NULLVP) 2268 error = VOP_SETACL(uvp, ap->a_type, ap->a_aclp, ap->a_cred, td); 2269 2270 UNIONFS_INTERNAL_DEBUG("unionfs_setacl: leave (%d)\n", error); 2271 2272 return (error); 2273 } 2274 2275 static int 2276 unionfs_aclcheck(struct vop_aclcheck_args *ap) 2277 { 2278 struct unionfs_node *unp; 2279 struct vnode *vp; 2280 int error; 2281 2282 UNIONFS_INTERNAL_DEBUG("unionfs_aclcheck: enter\n"); 2283 2284 KASSERT_UNIONFS_VNODE(ap->a_vp); 2285 2286 unp = VTOUNIONFS(ap->a_vp); 2287 vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); 2288 2289 error = VOP_ACLCHECK(vp, ap->a_type, ap->a_aclp, ap->a_cred, ap->a_td); 2290 2291 UNIONFS_INTERNAL_DEBUG("unionfs_aclcheck: leave (%d)\n", error); 2292 2293 return (error); 2294 } 2295 2296 static int 2297 unionfs_openextattr(struct vop_openextattr_args *ap) 2298 { 2299 struct unionfs_node *unp; 2300 struct vnode *vp; 2301 struct vnode *tvp; 2302 int error; 2303 2304 KASSERT_UNIONFS_VNODE(ap->a_vp); 2305 2306 vp = ap->a_vp; 2307 unp = VTOUNIONFS(vp); 2308 tvp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); 2309 2310 if ((tvp == unp->un_uppervp && (unp->un_flag & UNIONFS_OPENEXTU)) || 2311 (tvp == unp->un_lowervp && (unp->un_flag & UNIONFS_OPENEXTL))) 2312 return (EBUSY); 2313 2314 error = VOP_OPENEXTATTR(tvp, ap->a_cred, ap->a_td); 2315 2316 if (error == 0) { 2317 if (vn_lock(vp, LK_UPGRADE) != 0) 2318 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2319 if (!VN_IS_DOOMED(vp)) { 2320 if (tvp == unp->un_uppervp) 2321 unp->un_flag |= UNIONFS_OPENEXTU; 2322 else 2323 unp->un_flag |= UNIONFS_OPENEXTL; 2324 } 2325 vn_lock(vp, LK_DOWNGRADE | LK_RETRY); 2326 } 2327 2328 return (error); 2329 } 2330 2331 static int 2332 unionfs_closeextattr(struct vop_closeextattr_args *ap) 2333 { 2334 struct unionfs_node *unp; 2335 struct vnode *vp; 2336 struct vnode *tvp; 2337 int error; 2338 2339 KASSERT_UNIONFS_VNODE(ap->a_vp); 2340 2341 vp = ap->a_vp; 2342 unp = VTOUNIONFS(vp); 2343 tvp = NULLVP; 2344 2345 if (unp->un_flag & UNIONFS_OPENEXTU) 2346 tvp = unp->un_uppervp; 2347 else if (unp->un_flag & UNIONFS_OPENEXTL) 2348 tvp = unp->un_lowervp; 2349 2350 if (tvp == NULLVP) 2351 return (EOPNOTSUPP); 2352 2353 error = VOP_CLOSEEXTATTR(tvp, ap->a_commit, ap->a_cred, ap->a_td); 2354 2355 if (error == 0) { 2356 if (vn_lock(vp, LK_UPGRADE) != 0) 2357 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2358 if (!VN_IS_DOOMED(vp)) { 2359 if (tvp == unp->un_uppervp) 2360 unp->un_flag &= ~UNIONFS_OPENEXTU; 2361 else 2362 unp->un_flag &= ~UNIONFS_OPENEXTL; 2363 } 2364 vn_lock(vp, LK_DOWNGRADE | LK_RETRY); 2365 } 2366 2367 return (error); 2368 } 2369 2370 static int 2371 unionfs_getextattr(struct vop_getextattr_args *ap) 2372 { 2373 struct unionfs_node *unp; 2374 struct vnode *vp; 2375 2376 KASSERT_UNIONFS_VNODE(ap->a_vp); 2377 2378 unp = VTOUNIONFS(ap->a_vp); 2379 vp = NULLVP; 2380 2381 if (unp->un_flag & UNIONFS_OPENEXTU) 2382 vp = unp->un_uppervp; 2383 else if (unp->un_flag & UNIONFS_OPENEXTL) 2384 vp = unp->un_lowervp; 2385 2386 if (vp == NULLVP) 2387 return (EOPNOTSUPP); 2388 2389 return (VOP_GETEXTATTR(vp, ap->a_attrnamespace, ap->a_name, 2390 ap->a_uio, ap->a_size, ap->a_cred, ap->a_td)); 2391 } 2392 2393 static int 2394 unionfs_setextattr(struct vop_setextattr_args *ap) 2395 { 2396 struct unionfs_node *unp; 2397 struct vnode *uvp; 2398 struct vnode *lvp; 2399 struct vnode *ovp; 2400 struct ucred *cred; 2401 struct thread *td; 2402 int error; 2403 2404 KASSERT_UNIONFS_VNODE(ap->a_vp); 2405 2406 error = EROFS; 2407 unp = VTOUNIONFS(ap->a_vp); 2408 uvp = unp->un_uppervp; 2409 lvp = unp->un_lowervp; 2410 ovp = NULLVP; 2411 cred = ap->a_cred; 2412 td = ap->a_td; 2413 2414 UNIONFS_INTERNAL_DEBUG("unionfs_setextattr: enter (un_flag=%x)\n", 2415 unp->un_flag); 2416 2417 if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY) 2418 return (EROFS); 2419 2420 if (unp->un_flag & UNIONFS_OPENEXTU) 2421 ovp = unp->un_uppervp; 2422 else if (unp->un_flag & UNIONFS_OPENEXTL) 2423 ovp = unp->un_lowervp; 2424 2425 if (ovp == NULLVP) 2426 return (EOPNOTSUPP); 2427 2428 if (ovp == lvp && lvp->v_type == VREG) { 2429 VOP_CLOSEEXTATTR(lvp, 0, cred, td); 2430 if (uvp == NULLVP && 2431 (error = unionfs_copyfile(unp, 1, cred, td)) != 0) { 2432 unionfs_setextattr_reopen: 2433 if ((unp->un_flag & UNIONFS_OPENEXTL) && 2434 VOP_OPENEXTATTR(lvp, cred, td)) { 2435 #ifdef DIAGNOSTIC 2436 panic("unionfs: VOP_OPENEXTATTR failed"); 2437 #endif 2438 unp->un_flag &= ~UNIONFS_OPENEXTL; 2439 } 2440 goto unionfs_setextattr_abort; 2441 } 2442 uvp = unp->un_uppervp; 2443 if ((error = VOP_OPENEXTATTR(uvp, cred, td)) != 0) 2444 goto unionfs_setextattr_reopen; 2445 unp->un_flag &= ~UNIONFS_OPENEXTL; 2446 unp->un_flag |= UNIONFS_OPENEXTU; 2447 ovp = uvp; 2448 } 2449 2450 if (ovp == uvp) 2451 error = VOP_SETEXTATTR(ovp, ap->a_attrnamespace, ap->a_name, 2452 ap->a_uio, cred, td); 2453 2454 unionfs_setextattr_abort: 2455 UNIONFS_INTERNAL_DEBUG("unionfs_setextattr: leave (%d)\n", error); 2456 2457 return (error); 2458 } 2459 2460 static int 2461 unionfs_listextattr(struct vop_listextattr_args *ap) 2462 { 2463 struct unionfs_node *unp; 2464 struct vnode *vp; 2465 2466 KASSERT_UNIONFS_VNODE(ap->a_vp); 2467 2468 unp = VTOUNIONFS(ap->a_vp); 2469 vp = NULLVP; 2470 2471 if (unp->un_flag & UNIONFS_OPENEXTU) 2472 vp = unp->un_uppervp; 2473 else if (unp->un_flag & UNIONFS_OPENEXTL) 2474 vp = unp->un_lowervp; 2475 2476 if (vp == NULLVP) 2477 return (EOPNOTSUPP); 2478 2479 return (VOP_LISTEXTATTR(vp, ap->a_attrnamespace, ap->a_uio, 2480 ap->a_size, ap->a_cred, ap->a_td)); 2481 } 2482 2483 static int 2484 unionfs_deleteextattr(struct vop_deleteextattr_args *ap) 2485 { 2486 struct unionfs_node *unp; 2487 struct vnode *uvp; 2488 struct vnode *lvp; 2489 struct vnode *ovp; 2490 struct ucred *cred; 2491 struct thread *td; 2492 int error; 2493 2494 KASSERT_UNIONFS_VNODE(ap->a_vp); 2495 2496 error = EROFS; 2497 unp = VTOUNIONFS(ap->a_vp); 2498 uvp = unp->un_uppervp; 2499 lvp = unp->un_lowervp; 2500 ovp = NULLVP; 2501 cred = ap->a_cred; 2502 td = ap->a_td; 2503 2504 UNIONFS_INTERNAL_DEBUG("unionfs_deleteextattr: enter (un_flag=%x)\n", 2505 unp->un_flag); 2506 2507 if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY) 2508 return (EROFS); 2509 2510 if (unp->un_flag & UNIONFS_OPENEXTU) 2511 ovp = unp->un_uppervp; 2512 else if (unp->un_flag & UNIONFS_OPENEXTL) 2513 ovp = unp->un_lowervp; 2514 2515 if (ovp == NULLVP) 2516 return (EOPNOTSUPP); 2517 2518 if (ovp == lvp && lvp->v_type == VREG) { 2519 VOP_CLOSEEXTATTR(lvp, 0, cred, td); 2520 if (uvp == NULLVP && 2521 (error = unionfs_copyfile(unp, 1, cred, td)) != 0) { 2522 unionfs_deleteextattr_reopen: 2523 if ((unp->un_flag & UNIONFS_OPENEXTL) && 2524 VOP_OPENEXTATTR(lvp, cred, td)) { 2525 #ifdef DIAGNOSTIC 2526 panic("unionfs: VOP_OPENEXTATTR failed"); 2527 #endif 2528 unp->un_flag &= ~UNIONFS_OPENEXTL; 2529 } 2530 goto unionfs_deleteextattr_abort; 2531 } 2532 uvp = unp->un_uppervp; 2533 if ((error = VOP_OPENEXTATTR(uvp, cred, td)) != 0) 2534 goto unionfs_deleteextattr_reopen; 2535 unp->un_flag &= ~UNIONFS_OPENEXTL; 2536 unp->un_flag |= UNIONFS_OPENEXTU; 2537 ovp = uvp; 2538 } 2539 2540 if (ovp == uvp) 2541 error = VOP_DELETEEXTATTR(ovp, ap->a_attrnamespace, ap->a_name, 2542 ap->a_cred, ap->a_td); 2543 2544 unionfs_deleteextattr_abort: 2545 UNIONFS_INTERNAL_DEBUG("unionfs_deleteextattr: leave (%d)\n", error); 2546 2547 return (error); 2548 } 2549 2550 static int 2551 unionfs_setlabel(struct vop_setlabel_args *ap) 2552 { 2553 struct unionfs_node *unp; 2554 struct vnode *uvp; 2555 struct vnode *lvp; 2556 struct thread *td; 2557 int error; 2558 2559 UNIONFS_INTERNAL_DEBUG("unionfs_setlabel: enter\n"); 2560 2561 KASSERT_UNIONFS_VNODE(ap->a_vp); 2562 2563 error = EROFS; 2564 unp = VTOUNIONFS(ap->a_vp); 2565 uvp = unp->un_uppervp; 2566 lvp = unp->un_lowervp; 2567 td = ap->a_td; 2568 2569 if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY) 2570 return (EROFS); 2571 2572 if (uvp == NULLVP && lvp->v_type == VREG) { 2573 if ((error = unionfs_copyfile(unp, 1, ap->a_cred, td)) != 0) 2574 return (error); 2575 uvp = unp->un_uppervp; 2576 } 2577 2578 if (uvp != NULLVP) 2579 error = VOP_SETLABEL(uvp, ap->a_label, ap->a_cred, td); 2580 2581 UNIONFS_INTERNAL_DEBUG("unionfs_setlabel: leave (%d)\n", error); 2582 2583 return (error); 2584 } 2585 2586 static int 2587 unionfs_vptofh(struct vop_vptofh_args *ap) 2588 { 2589 return (EOPNOTSUPP); 2590 } 2591 2592 static int 2593 unionfs_add_writecount(struct vop_add_writecount_args *ap) 2594 { 2595 struct vnode *tvp, *vp; 2596 struct unionfs_node *unp; 2597 int error, writerefs __diagused; 2598 2599 vp = ap->a_vp; 2600 unp = VTOUNIONFS(vp); 2601 tvp = unp->un_uppervp; 2602 KASSERT(tvp != NULL, 2603 ("%s: adding write ref without upper vnode", __func__)); 2604 error = VOP_ADD_WRITECOUNT(tvp, ap->a_inc); 2605 if (error != 0) 2606 return (error); 2607 /* 2608 * We need to track the write refs we've passed to the underlying 2609 * vnodes so that we can undo them in case we are forcibly unmounted. 2610 */ 2611 writerefs = atomic_fetchadd_int(&vp->v_writecount, ap->a_inc); 2612 /* text refs are bypassed to lowervp */ 2613 VNASSERT(writerefs >= 0, vp, 2614 ("%s: invalid write count %d", __func__, writerefs)); 2615 VNASSERT(writerefs + ap->a_inc >= 0, vp, 2616 ("%s: invalid write count inc %d + %d", __func__, 2617 writerefs, ap->a_inc)); 2618 return (0); 2619 } 2620 2621 static int 2622 unionfs_vput_pair(struct vop_vput_pair_args *ap) 2623 { 2624 struct mount *mp; 2625 struct vnode *dvp, *vp, **vpp, *lvp, *ldvp, *uvp, *udvp, *tempvp; 2626 struct unionfs_node *dunp, *unp; 2627 int error, res; 2628 2629 dvp = ap->a_dvp; 2630 vpp = ap->a_vpp; 2631 vp = NULLVP; 2632 lvp = NULLVP; 2633 uvp = NULLVP; 2634 unp = NULL; 2635 2636 dunp = VTOUNIONFS(dvp); 2637 udvp = dunp->un_uppervp; 2638 ldvp = dunp->un_lowervp; 2639 2640 /* 2641 * Underlying vnodes should be locked because the encompassing unionfs 2642 * node is locked, but will not be referenced, as the reference will 2643 * only be on the unionfs node. Reference them now so that the vput()s 2644 * performed by VOP_VPUT_PAIR() will have a reference to drop. 2645 */ 2646 if (udvp != NULLVP) 2647 vref(udvp); 2648 if (ldvp != NULLVP) 2649 vref(ldvp); 2650 2651 if (vpp != NULL) 2652 vp = *vpp; 2653 2654 if (vp != NULLVP) { 2655 unp = VTOUNIONFS(vp); 2656 uvp = unp->un_uppervp; 2657 lvp = unp->un_lowervp; 2658 if (uvp != NULLVP) 2659 vref(uvp); 2660 if (lvp != NULLVP) 2661 vref(lvp); 2662 2663 /* 2664 * If we're being asked to return a locked child vnode, then 2665 * we may need to create a replacement vnode in case the 2666 * original is reclaimed while the lock is dropped. In that 2667 * case we'll need to ensure the mount and the underlying 2668 * vnodes aren't also recycled during that window. 2669 */ 2670 if (!ap->a_unlock_vp) { 2671 vhold(vp); 2672 if (uvp != NULLVP) 2673 vhold(uvp); 2674 if (lvp != NULLVP) 2675 vhold(lvp); 2676 mp = vp->v_mount; 2677 vfs_ref(mp); 2678 } 2679 } 2680 2681 /* 2682 * TODO: Because unionfs_lock() locks both the lower and upper vnodes 2683 * (if available), we must also call VOP_VPUT_PAIR() on both the lower 2684 * and upper parent/child pairs. If unionfs_lock() is reworked to lock 2685 * only a single vnode, this code will need to change to also only 2686 * operate on one vnode pair. 2687 */ 2688 ASSERT_VOP_LOCKED(ldvp, __func__); 2689 ASSERT_VOP_LOCKED(udvp, __func__); 2690 ASSERT_VOP_LOCKED(lvp, __func__); 2691 ASSERT_VOP_LOCKED(uvp, __func__); 2692 2693 KASSERT(lvp == NULLVP || ldvp != NULLVP, 2694 ("%s: NULL ldvp with non-NULL lvp", __func__)); 2695 if (ldvp != NULLVP) 2696 res = VOP_VPUT_PAIR(ldvp, lvp != NULLVP ? &lvp : NULL, true); 2697 KASSERT(uvp == NULLVP || udvp != NULLVP, 2698 ("%s: NULL udvp with non-NULL uvp", __func__)); 2699 if (udvp != NULLVP) 2700 res = VOP_VPUT_PAIR(udvp, uvp != NULLVP ? &uvp : NULL, true); 2701 2702 ASSERT_VOP_UNLOCKED(ldvp, __func__); 2703 ASSERT_VOP_UNLOCKED(udvp, __func__); 2704 ASSERT_VOP_UNLOCKED(lvp, __func__); 2705 ASSERT_VOP_UNLOCKED(uvp, __func__); 2706 2707 /* 2708 * VOP_VPUT_PAIR() dropped the references we added to the underlying 2709 * vnodes, now drop the caller's reference to the unionfs vnodes. 2710 */ 2711 if (vp != NULLVP && ap->a_unlock_vp) 2712 vrele(vp); 2713 vrele(dvp); 2714 2715 if (vp == NULLVP || ap->a_unlock_vp) 2716 return (res); 2717 2718 /* 2719 * We're being asked to return a locked vnode. At this point, the 2720 * underlying vnodes have been unlocked, so vp may have been reclaimed. 2721 */ 2722 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2723 if (vp->v_data == NULL && vfs_busy(mp, MBF_NOWAIT) == 0) { 2724 vput(vp); 2725 error = unionfs_nodeget(mp, uvp, lvp, dvp, &tempvp, NULL); 2726 if (error == 0) { 2727 vn_lock(tempvp, LK_EXCLUSIVE | LK_RETRY); 2728 *vpp = tempvp; 2729 } else 2730 vget(vp, LK_EXCLUSIVE | LK_RETRY); 2731 vfs_unbusy(mp); 2732 } 2733 if (lvp != NULLVP) 2734 vdrop(lvp); 2735 if (uvp != NULLVP) 2736 vdrop(uvp); 2737 vdrop(vp); 2738 vfs_rel(mp); 2739 2740 return (res); 2741 } 2742 2743 static int 2744 unionfs_set_text(struct vop_set_text_args *ap) 2745 { 2746 struct vnode *tvp; 2747 struct unionfs_node *unp; 2748 int error; 2749 2750 /* 2751 * We assume text refs are managed against lvp/uvp through the 2752 * executable mapping backed by its VM object. We therefore don't 2753 * need to track leased text refs in the case of a forcible unmount. 2754 */ 2755 unp = VTOUNIONFS(ap->a_vp); 2756 ASSERT_VOP_LOCKED(ap->a_vp, __func__); 2757 tvp = unp->un_uppervp != NULL ? unp->un_uppervp : unp->un_lowervp; 2758 error = VOP_SET_TEXT(tvp); 2759 return (error); 2760 } 2761 2762 static int 2763 unionfs_unset_text(struct vop_unset_text_args *ap) 2764 { 2765 struct vnode *tvp; 2766 struct unionfs_node *unp; 2767 2768 ASSERT_VOP_LOCKED(ap->a_vp, __func__); 2769 unp = VTOUNIONFS(ap->a_vp); 2770 tvp = unp->un_uppervp != NULL ? unp->un_uppervp : unp->un_lowervp; 2771 VOP_UNSET_TEXT_CHECKED(tvp); 2772 return (0); 2773 } 2774 2775 struct vop_vector unionfs_vnodeops = { 2776 .vop_default = &default_vnodeops, 2777 2778 .vop_access = unionfs_access, 2779 .vop_aclcheck = unionfs_aclcheck, 2780 .vop_advlock = unionfs_advlock, 2781 .vop_bmap = VOP_EOPNOTSUPP, 2782 .vop_cachedlookup = unionfs_lookup, 2783 .vop_close = unionfs_close, 2784 .vop_closeextattr = unionfs_closeextattr, 2785 .vop_create = unionfs_create, 2786 .vop_deleteextattr = unionfs_deleteextattr, 2787 .vop_fsync = unionfs_fsync, 2788 .vop_getacl = unionfs_getacl, 2789 .vop_getattr = unionfs_getattr, 2790 .vop_getextattr = unionfs_getextattr, 2791 .vop_getwritemount = unionfs_getwritemount, 2792 .vop_inactive = unionfs_inactive, 2793 .vop_need_inactive = vop_stdneed_inactive, 2794 .vop_islocked = unionfs_islocked, 2795 .vop_ioctl = unionfs_ioctl, 2796 .vop_link = unionfs_link, 2797 .vop_listextattr = unionfs_listextattr, 2798 .vop_lock1 = unionfs_lock, 2799 .vop_lookup = vfs_cache_lookup, 2800 .vop_mkdir = unionfs_mkdir, 2801 .vop_mknod = unionfs_mknod, 2802 .vop_open = unionfs_open, 2803 .vop_openextattr = unionfs_openextattr, 2804 .vop_pathconf = unionfs_pathconf, 2805 .vop_poll = unionfs_poll, 2806 .vop_print = unionfs_print, 2807 .vop_read = unionfs_read, 2808 .vop_readdir = unionfs_readdir, 2809 .vop_readlink = unionfs_readlink, 2810 .vop_reclaim = unionfs_reclaim, 2811 .vop_remove = unionfs_remove, 2812 .vop_rename = unionfs_rename, 2813 .vop_rmdir = unionfs_rmdir, 2814 .vop_setacl = unionfs_setacl, 2815 .vop_setattr = unionfs_setattr, 2816 .vop_setextattr = unionfs_setextattr, 2817 .vop_setlabel = unionfs_setlabel, 2818 .vop_strategy = unionfs_strategy, 2819 .vop_symlink = unionfs_symlink, 2820 .vop_unlock = unionfs_unlock, 2821 .vop_whiteout = unionfs_whiteout, 2822 .vop_write = unionfs_write, 2823 .vop_vptofh = unionfs_vptofh, 2824 .vop_add_writecount = unionfs_add_writecount, 2825 .vop_vput_pair = unionfs_vput_pair, 2826 .vop_set_text = unionfs_set_text, 2827 .vop_unset_text = unionfs_unset_text, 2828 }; 2829 VFS_VOP_VECTOR_REGISTER(unionfs_vnodeops); 2830