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