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, *unp; 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 dunp = VTOUNIONFS(dvp); 143 if (error == 0 && dunp == NULL) 144 error = ENOENT; 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 dtmpvp = dunp->un_dvp; 159 vref(dtmpvp); 160 VOP_UNLOCK(dvp); 161 *(ap->a_vpp) = dtmpvp; 162 163 if (nameiop == DELETE || nameiop == RENAME) 164 vn_lock(dtmpvp, LK_EXCLUSIVE | LK_RETRY); 165 else if (cnp->cn_lkflags & LK_TYPE_MASK) 166 vn_lock(dtmpvp, cnp->cn_lkflags | 167 LK_RETRY); 168 169 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); 170 } else if (error == ENOENT && (cnflags & MAKEENTRY) != 0) 171 cache_enter(dvp, NULLVP, cnp); 172 173 goto unionfs_lookup_return; 174 } 175 176 /* 177 * lookup upper layer 178 */ 179 if (udvp != NULLVP) { 180 uerror = VOP_LOOKUP(udvp, &uvp, cnp); 181 182 if (uerror == 0) { 183 if (udvp == uvp) { /* is dot */ 184 vrele(uvp); 185 *(ap->a_vpp) = dvp; 186 vref(dvp); 187 188 error = uerror; 189 goto unionfs_lookup_return; 190 } 191 if (nameiop == DELETE || nameiop == RENAME || 192 (cnp->cn_lkflags & LK_TYPE_MASK)) 193 VOP_UNLOCK(uvp); 194 } 195 196 /* check whiteout */ 197 if (uerror == ENOENT || uerror == EJUSTRETURN) 198 if (cnp->cn_flags & ISWHITEOUT) 199 iswhiteout = 1; /* don't lookup lower */ 200 if (iswhiteout == 0 && ldvp != NULLVP) 201 if (!VOP_GETATTR(udvp, &va, cnp->cn_cred) && 202 (va.va_flags & OPAQUE)) 203 iswhiteout = 1; /* don't lookup lower */ 204 #if 0 205 UNIONFS_INTERNAL_DEBUG( 206 "unionfs_lookup: debug: whiteout=%d, path=%s\n", 207 iswhiteout, cnp->cn_nameptr); 208 #endif 209 } 210 211 /* 212 * lookup lower layer 213 */ 214 if (ldvp != NULLVP && !(cnflags & DOWHITEOUT) && iswhiteout == 0) { 215 /* always op is LOOKUP */ 216 cnp->cn_nameiop = LOOKUP; 217 cnflagsbk = cnp->cn_flags; 218 cnp->cn_flags = cnflags; 219 220 lerror = VOP_LOOKUP(ldvp, &lvp, cnp); 221 222 cnp->cn_nameiop = nameiop; 223 if (udvp != NULLVP && (uerror == 0 || uerror == EJUSTRETURN)) 224 cnp->cn_flags = cnflagsbk; 225 226 if (lerror == 0) { 227 if (ldvp == lvp) { /* is dot */ 228 if (uvp != NULLVP) 229 vrele(uvp); /* no need? */ 230 vrele(lvp); 231 *(ap->a_vpp) = dvp; 232 vref(dvp); 233 234 UNIONFS_INTERNAL_DEBUG( 235 "unionfs_lookup: leave (%d)\n", lerror); 236 237 return (lerror); 238 } 239 if (cnp->cn_lkflags & LK_TYPE_MASK) 240 VOP_UNLOCK(lvp); 241 } 242 } 243 244 /* 245 * check lookup result 246 */ 247 if (uvp == NULLVP && lvp == NULLVP) { 248 error = (udvp != NULLVP ? uerror : lerror); 249 goto unionfs_lookup_return; 250 } 251 252 /* 253 * check vnode type 254 */ 255 if (uvp != NULLVP && lvp != NULLVP && uvp->v_type != lvp->v_type) { 256 vrele(lvp); 257 lvp = NULLVP; 258 } 259 260 /* 261 * check shadow dir 262 */ 263 if (uerror != 0 && uerror != EJUSTRETURN && udvp != NULLVP && 264 lerror == 0 && lvp != NULLVP && lvp->v_type == VDIR && 265 !(dvp->v_mount->mnt_flag & MNT_RDONLY) && 266 (1 < cnp->cn_namelen || '.' != *(cnp->cn_nameptr))) { 267 /* get unionfs vnode in order to create a new shadow dir. */ 268 error = unionfs_nodeget(dvp->v_mount, NULLVP, lvp, dvp, &vp, 269 cnp); 270 if (error != 0) 271 goto unionfs_lookup_cleanup; 272 273 if (LK_SHARED == (cnp->cn_lkflags & LK_TYPE_MASK)) 274 VOP_UNLOCK(vp); 275 if (LK_EXCLUSIVE != VOP_ISLOCKED(vp)) { 276 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 277 lockflag = 1; 278 } 279 unp = VTOUNIONFS(vp); 280 if (unp == NULL) 281 error = ENOENT; 282 else 283 error = unionfs_mkshadowdir(MOUNTTOUNIONFSMOUNT(dvp->v_mount), 284 udvp, unp, cnp, td); 285 if (lockflag != 0) 286 VOP_UNLOCK(vp); 287 if (error != 0) { 288 UNIONFSDEBUG( 289 "unionfs_lookup: Unable to create shadow dir."); 290 if ((cnp->cn_lkflags & LK_TYPE_MASK) == LK_EXCLUSIVE) 291 vput(vp); 292 else 293 vrele(vp); 294 goto unionfs_lookup_cleanup; 295 } 296 if ((cnp->cn_lkflags & LK_TYPE_MASK) == LK_SHARED) 297 vn_lock(vp, LK_SHARED | LK_RETRY); 298 } 299 /* 300 * get unionfs vnode. 301 */ 302 else { 303 if (uvp != NULLVP) 304 error = uerror; 305 else 306 error = lerror; 307 if (error != 0) 308 goto unionfs_lookup_cleanup; 309 error = unionfs_nodeget(dvp->v_mount, uvp, lvp, 310 dvp, &vp, cnp); 311 if (error != 0) { 312 UNIONFSDEBUG( 313 "unionfs_lookup: Unable to create unionfs vnode."); 314 goto unionfs_lookup_cleanup; 315 } 316 if ((nameiop == DELETE || nameiop == RENAME) && 317 (cnp->cn_lkflags & LK_TYPE_MASK) == 0) 318 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 319 } 320 321 *(ap->a_vpp) = vp; 322 323 if (cnflags & MAKEENTRY) 324 cache_enter(dvp, vp, cnp); 325 326 unionfs_lookup_cleanup: 327 if (uvp != NULLVP) 328 vrele(uvp); 329 if (lvp != NULLVP) 330 vrele(lvp); 331 332 if (error == ENOENT && (cnflags & MAKEENTRY) != 0) 333 cache_enter(dvp, NULLVP, cnp); 334 335 unionfs_lookup_return: 336 337 UNIONFS_INTERNAL_DEBUG("unionfs_lookup: leave (%d)\n", error); 338 339 return (error); 340 } 341 342 static int 343 unionfs_create(struct vop_create_args *ap) 344 { 345 struct unionfs_node *dunp; 346 struct componentname *cnp; 347 struct vnode *udvp; 348 struct vnode *vp; 349 int error; 350 351 UNIONFS_INTERNAL_DEBUG("unionfs_create: enter\n"); 352 353 KASSERT_UNIONFS_VNODE(ap->a_dvp); 354 355 dunp = VTOUNIONFS(ap->a_dvp); 356 cnp = ap->a_cnp; 357 udvp = dunp->un_uppervp; 358 error = EROFS; 359 360 if (udvp != NULLVP) { 361 int lkflags; 362 bool vp_created = false; 363 unionfs_forward_vop_start(udvp, &lkflags); 364 error = VOP_CREATE(udvp, &vp, cnp, ap->a_vap); 365 if (error == 0) 366 vp_created = true; 367 if (__predict_false(unionfs_forward_vop_finish(ap->a_dvp, udvp, 368 lkflags)) && error == 0) { 369 error = ENOENT; 370 } 371 if (error == 0) { 372 VOP_UNLOCK(vp); 373 error = unionfs_nodeget(ap->a_dvp->v_mount, vp, NULLVP, 374 ap->a_dvp, ap->a_vpp, cnp); 375 vrele(vp); 376 } else if (vp_created) 377 vput(vp); 378 } 379 380 UNIONFS_INTERNAL_DEBUG("unionfs_create: leave (%d)\n", error); 381 382 return (error); 383 } 384 385 static int 386 unionfs_whiteout(struct vop_whiteout_args *ap) 387 { 388 struct unionfs_node *dunp; 389 struct componentname *cnp; 390 struct vnode *udvp; 391 int error; 392 393 UNIONFS_INTERNAL_DEBUG("unionfs_whiteout: enter\n"); 394 395 KASSERT_UNIONFS_VNODE(ap->a_dvp); 396 397 dunp = VTOUNIONFS(ap->a_dvp); 398 cnp = ap->a_cnp; 399 udvp = dunp->un_uppervp; 400 error = EOPNOTSUPP; 401 402 if (udvp != NULLVP) { 403 int lkflags; 404 switch (ap->a_flags) { 405 case CREATE: 406 case DELETE: 407 case LOOKUP: 408 unionfs_forward_vop_start(udvp, &lkflags); 409 error = VOP_WHITEOUT(udvp, cnp, ap->a_flags); 410 unionfs_forward_vop_finish(ap->a_dvp, udvp, lkflags); 411 break; 412 default: 413 error = EINVAL; 414 break; 415 } 416 } 417 418 UNIONFS_INTERNAL_DEBUG("unionfs_whiteout: leave (%d)\n", error); 419 420 return (error); 421 } 422 423 static int 424 unionfs_mknod(struct vop_mknod_args *ap) 425 { 426 struct unionfs_node *dunp; 427 struct componentname *cnp; 428 struct vnode *udvp; 429 struct vnode *vp; 430 int error; 431 432 UNIONFS_INTERNAL_DEBUG("unionfs_mknod: enter\n"); 433 434 KASSERT_UNIONFS_VNODE(ap->a_dvp); 435 436 dunp = VTOUNIONFS(ap->a_dvp); 437 cnp = ap->a_cnp; 438 udvp = dunp->un_uppervp; 439 error = EROFS; 440 441 if (udvp != NULLVP) { 442 int lkflags; 443 bool vp_created = false; 444 unionfs_forward_vop_start(udvp, &lkflags); 445 error = VOP_MKNOD(udvp, &vp, cnp, ap->a_vap); 446 if (error == 0) 447 vp_created = true; 448 if (__predict_false(unionfs_forward_vop_finish(ap->a_dvp, udvp, 449 lkflags)) && error == 0) { 450 error = ENOENT; 451 } 452 if (error == 0) { 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 } else if (vp_created) 458 vput(vp); 459 } 460 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 int lkflags; 895 unionfs_forward_vop_start(uvp, &lkflags); 896 error = VOP_SETATTR(uvp, vap, ap->a_cred); 897 unionfs_forward_vop_finish(ap->a_vp, uvp, lkflags); 898 } 899 900 UNIONFS_INTERNAL_DEBUG("unionfs_setattr: leave (%d)\n", error); 901 902 return (error); 903 } 904 905 static int 906 unionfs_read(struct vop_read_args *ap) 907 { 908 struct unionfs_node *unp; 909 struct vnode *tvp; 910 int error; 911 912 /* UNIONFS_INTERNAL_DEBUG("unionfs_read: enter\n"); */ 913 914 KASSERT_UNIONFS_VNODE(ap->a_vp); 915 916 unp = VTOUNIONFS(ap->a_vp); 917 tvp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); 918 919 error = VOP_READ(tvp, ap->a_uio, ap->a_ioflag, ap->a_cred); 920 921 /* UNIONFS_INTERNAL_DEBUG("unionfs_read: leave (%d)\n", error); */ 922 923 return (error); 924 } 925 926 static int 927 unionfs_write(struct vop_write_args *ap) 928 { 929 struct unionfs_node *unp; 930 struct vnode *tvp; 931 int error; 932 int lkflags; 933 934 /* UNIONFS_INTERNAL_DEBUG("unionfs_write: enter\n"); */ 935 936 KASSERT_UNIONFS_VNODE(ap->a_vp); 937 938 unp = VTOUNIONFS(ap->a_vp); 939 tvp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); 940 941 unionfs_forward_vop_start(tvp, &lkflags); 942 error = VOP_WRITE(tvp, ap->a_uio, ap->a_ioflag, ap->a_cred); 943 unionfs_forward_vop_finish(ap->a_vp, tvp, lkflags); 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 enum unionfs_lkupgrade lkstatus; 1009 int error, lkflags; 1010 1011 KASSERT_UNIONFS_VNODE(ap->a_vp); 1012 1013 unp = VTOUNIONFS(ap->a_vp); 1014 lkstatus = unionfs_upgrade_lock(ap->a_vp); 1015 if (lkstatus == UNIONFS_LKUPGRADE_DOOMED) { 1016 unionfs_downgrade_lock(ap->a_vp, lkstatus); 1017 return (ENOENT); 1018 } 1019 unionfs_get_node_status(unp, ap->a_td, &unsp); 1020 ovp = (unsp->uns_upper_opencnt ? unp->un_uppervp : unp->un_lowervp); 1021 unionfs_tryrem_node_status(unp, unsp); 1022 1023 unionfs_downgrade_lock(ap->a_vp, lkstatus); 1024 1025 if (ovp == NULLVP) 1026 return (EBADF); 1027 1028 unionfs_forward_vop_start(ovp, &lkflags); 1029 error = VOP_FSYNC(ovp, ap->a_waitfor, ap->a_td); 1030 unionfs_forward_vop_finish(ap->a_vp, ovp, lkflags); 1031 1032 return (error); 1033 } 1034 1035 static int 1036 unionfs_remove(struct vop_remove_args *ap) 1037 { 1038 char *path; 1039 struct unionfs_node *dunp; 1040 struct unionfs_node *unp; 1041 struct unionfs_mount *ump; 1042 struct vnode *udvp; 1043 struct vnode *uvp; 1044 struct vnode *lvp; 1045 struct componentname *cnp; 1046 struct thread *td; 1047 int error; 1048 int pathlen; 1049 1050 UNIONFS_INTERNAL_DEBUG("unionfs_remove: enter\n"); 1051 1052 KASSERT_UNIONFS_VNODE(ap->a_dvp); 1053 KASSERT_UNIONFS_VNODE(ap->a_vp); 1054 1055 error = 0; 1056 dunp = VTOUNIONFS(ap->a_dvp); 1057 udvp = dunp->un_uppervp; 1058 cnp = ap->a_cnp; 1059 td = curthread; 1060 1061 ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount); 1062 unp = VTOUNIONFS(ap->a_vp); 1063 uvp = unp->un_uppervp; 1064 lvp = unp->un_lowervp; 1065 path = unp->un_path; 1066 pathlen = unp->un_pathlen; 1067 1068 if (udvp == NULLVP) 1069 return (EROFS); 1070 1071 if (uvp != NULLVP) { 1072 int udvp_lkflags, uvp_lkflags; 1073 if (ump == NULL || ump->um_whitemode == UNIONFS_WHITE_ALWAYS || 1074 lvp != NULLVP) 1075 cnp->cn_flags |= DOWHITEOUT; 1076 unionfs_forward_vop_start_pair(udvp, &udvp_lkflags, 1077 uvp, &uvp_lkflags); 1078 error = VOP_REMOVE(udvp, uvp, cnp); 1079 unionfs_forward_vop_finish_pair(ap->a_dvp, udvp, udvp_lkflags, 1080 ap->a_vp, uvp, uvp_lkflags); 1081 } else if (lvp != NULLVP) 1082 error = unionfs_mkwhiteout(ap->a_dvp, udvp, cnp, td, path, pathlen); 1083 1084 UNIONFS_INTERNAL_DEBUG("unionfs_remove: leave (%d)\n", error); 1085 1086 return (error); 1087 } 1088 1089 static int 1090 unionfs_link(struct vop_link_args *ap) 1091 { 1092 struct unionfs_node *dunp; 1093 struct unionfs_node *unp; 1094 struct vnode *udvp; 1095 struct vnode *uvp; 1096 struct componentname *cnp; 1097 struct thread *td; 1098 int error; 1099 int needrelookup; 1100 1101 UNIONFS_INTERNAL_DEBUG("unionfs_link: enter\n"); 1102 1103 KASSERT_UNIONFS_VNODE(ap->a_tdvp); 1104 KASSERT_UNIONFS_VNODE(ap->a_vp); 1105 1106 error = 0; 1107 needrelookup = 0; 1108 dunp = VTOUNIONFS(ap->a_tdvp); 1109 unp = NULL; 1110 udvp = dunp->un_uppervp; 1111 uvp = NULLVP; 1112 cnp = ap->a_cnp; 1113 td = curthread; 1114 1115 if (udvp == NULLVP) 1116 return (EROFS); 1117 1118 unp = VTOUNIONFS(ap->a_vp); 1119 1120 if (unp->un_uppervp == NULLVP) { 1121 if (ap->a_vp->v_type != VREG) 1122 return (EOPNOTSUPP); 1123 1124 error = unionfs_copyfile(unp, 1, cnp->cn_cred, td); 1125 if (error != 0) 1126 return (error); 1127 needrelookup = 1; 1128 } 1129 uvp = unp->un_uppervp; 1130 1131 if (needrelookup != 0) 1132 error = unionfs_relookup_for_create(ap->a_tdvp, cnp, td); 1133 1134 if (error == 0) { 1135 int udvp_lkflags, uvp_lkflags; 1136 unionfs_forward_vop_start_pair(udvp, &udvp_lkflags, 1137 uvp, &uvp_lkflags); 1138 error = VOP_LINK(udvp, uvp, cnp); 1139 unionfs_forward_vop_finish_pair(ap->a_tdvp, udvp, udvp_lkflags, 1140 ap->a_vp, uvp, uvp_lkflags); 1141 } 1142 1143 UNIONFS_INTERNAL_DEBUG("unionfs_link: leave (%d)\n", error); 1144 1145 return (error); 1146 } 1147 1148 static int 1149 unionfs_rename(struct vop_rename_args *ap) 1150 { 1151 struct vnode *fdvp; 1152 struct vnode *fvp; 1153 struct componentname *fcnp; 1154 struct vnode *tdvp; 1155 struct vnode *tvp; 1156 struct componentname *tcnp; 1157 struct vnode *ltdvp; 1158 struct vnode *ltvp; 1159 struct thread *td; 1160 1161 /* rename target vnodes */ 1162 struct vnode *rfdvp; 1163 struct vnode *rfvp; 1164 struct vnode *rtdvp; 1165 struct vnode *rtvp; 1166 1167 struct unionfs_mount *ump; 1168 struct unionfs_node *unp; 1169 int error; 1170 int needrelookup; 1171 1172 UNIONFS_INTERNAL_DEBUG("unionfs_rename: enter\n"); 1173 1174 error = 0; 1175 fdvp = ap->a_fdvp; 1176 fvp = ap->a_fvp; 1177 fcnp = ap->a_fcnp; 1178 tdvp = ap->a_tdvp; 1179 tvp = ap->a_tvp; 1180 tcnp = ap->a_tcnp; 1181 ltdvp = NULLVP; 1182 ltvp = NULLVP; 1183 td = curthread; 1184 rfdvp = fdvp; 1185 rfvp = fvp; 1186 rtdvp = tdvp; 1187 rtvp = tvp; 1188 needrelookup = 0; 1189 1190 /* check for cross device rename */ 1191 if (fvp->v_mount != tdvp->v_mount || 1192 (tvp != NULLVP && fvp->v_mount != tvp->v_mount)) { 1193 if (fvp->v_op != &unionfs_vnodeops) 1194 error = ENODEV; 1195 else 1196 error = EXDEV; 1197 goto unionfs_rename_abort; 1198 } 1199 1200 /* Renaming a file to itself has no effect. */ 1201 if (fvp == tvp) 1202 goto unionfs_rename_abort; 1203 1204 /* 1205 * from/to vnode is unionfs node. 1206 */ 1207 1208 KASSERT_UNIONFS_VNODE(fdvp); 1209 KASSERT_UNIONFS_VNODE(fvp); 1210 KASSERT_UNIONFS_VNODE(tdvp); 1211 if (tvp != NULLVP) 1212 KASSERT_UNIONFS_VNODE(tvp); 1213 1214 unp = VTOUNIONFS(fdvp); 1215 #ifdef UNIONFS_IDBG_RENAME 1216 UNIONFS_INTERNAL_DEBUG("fdvp=%p, ufdvp=%p, lfdvp=%p\n", 1217 fdvp, unp->un_uppervp, unp->un_lowervp); 1218 #endif 1219 if (unp->un_uppervp == NULLVP) { 1220 error = ENODEV; 1221 goto unionfs_rename_abort; 1222 } 1223 rfdvp = unp->un_uppervp; 1224 vref(rfdvp); 1225 1226 unp = VTOUNIONFS(fvp); 1227 #ifdef UNIONFS_IDBG_RENAME 1228 UNIONFS_INTERNAL_DEBUG("fvp=%p, ufvp=%p, lfvp=%p\n", 1229 fvp, unp->un_uppervp, unp->un_lowervp); 1230 #endif 1231 ump = MOUNTTOUNIONFSMOUNT(fvp->v_mount); 1232 if (unp->un_uppervp == NULLVP) { 1233 switch (fvp->v_type) { 1234 case VREG: 1235 if ((error = vn_lock(fvp, LK_EXCLUSIVE)) != 0) 1236 goto unionfs_rename_abort; 1237 error = unionfs_copyfile(unp, 1, fcnp->cn_cred, td); 1238 VOP_UNLOCK(fvp); 1239 if (error != 0) 1240 goto unionfs_rename_abort; 1241 break; 1242 case VDIR: 1243 if ((error = vn_lock(fvp, LK_EXCLUSIVE)) != 0) 1244 goto unionfs_rename_abort; 1245 error = unionfs_mkshadowdir(ump, rfdvp, unp, fcnp, td); 1246 VOP_UNLOCK(fvp); 1247 if (error != 0) 1248 goto unionfs_rename_abort; 1249 break; 1250 default: 1251 error = ENODEV; 1252 goto unionfs_rename_abort; 1253 } 1254 1255 needrelookup = 1; 1256 } 1257 1258 if (unp->un_lowervp != NULLVP) 1259 fcnp->cn_flags |= DOWHITEOUT; 1260 rfvp = unp->un_uppervp; 1261 vref(rfvp); 1262 1263 unp = VTOUNIONFS(tdvp); 1264 #ifdef UNIONFS_IDBG_RENAME 1265 UNIONFS_INTERNAL_DEBUG("tdvp=%p, utdvp=%p, ltdvp=%p\n", 1266 tdvp, unp->un_uppervp, unp->un_lowervp); 1267 #endif 1268 if (unp->un_uppervp == NULLVP) { 1269 error = ENODEV; 1270 goto unionfs_rename_abort; 1271 } 1272 rtdvp = unp->un_uppervp; 1273 ltdvp = unp->un_lowervp; 1274 vref(rtdvp); 1275 1276 if (tdvp == tvp) { 1277 rtvp = rtdvp; 1278 vref(rtvp); 1279 } else if (tvp != NULLVP) { 1280 unp = VTOUNIONFS(tvp); 1281 #ifdef UNIONFS_IDBG_RENAME 1282 UNIONFS_INTERNAL_DEBUG("tvp=%p, utvp=%p, ltvp=%p\n", 1283 tvp, unp->un_uppervp, unp->un_lowervp); 1284 #endif 1285 if (unp->un_uppervp == NULLVP) 1286 rtvp = NULLVP; 1287 else { 1288 if (tvp->v_type == VDIR) { 1289 error = EINVAL; 1290 goto unionfs_rename_abort; 1291 } 1292 rtvp = unp->un_uppervp; 1293 ltvp = unp->un_lowervp; 1294 vref(rtvp); 1295 } 1296 } 1297 1298 if (rfvp == rtvp) 1299 goto unionfs_rename_abort; 1300 1301 if (needrelookup != 0) { 1302 if ((error = vn_lock(fdvp, LK_EXCLUSIVE)) != 0) 1303 goto unionfs_rename_abort; 1304 error = unionfs_relookup_for_delete(fdvp, fcnp, td); 1305 VOP_UNLOCK(fdvp); 1306 if (error != 0) 1307 goto unionfs_rename_abort; 1308 1309 /* Lock of tvp is canceled in order to avoid recursive lock. */ 1310 if (tvp != NULLVP && tvp != tdvp) 1311 VOP_UNLOCK(tvp); 1312 error = unionfs_relookup_for_rename(tdvp, tcnp, td); 1313 if (tvp != NULLVP && tvp != tdvp) 1314 vn_lock(tvp, LK_EXCLUSIVE | LK_RETRY); 1315 if (error != 0) 1316 goto unionfs_rename_abort; 1317 } 1318 1319 error = VOP_RENAME(rfdvp, rfvp, fcnp, rtdvp, rtvp, tcnp); 1320 1321 if (error == 0) { 1322 if (rtvp != NULLVP && rtvp->v_type == VDIR) 1323 cache_purge(tdvp); 1324 if (fvp->v_type == VDIR && fdvp != tdvp) 1325 cache_purge(fdvp); 1326 } 1327 1328 if (ltdvp != NULLVP) 1329 VOP_UNLOCK(ltdvp); 1330 if (tdvp != rtdvp) 1331 vrele(tdvp); 1332 if (ltvp != NULLVP) 1333 VOP_UNLOCK(ltvp); 1334 if (tvp != rtvp && tvp != NULLVP) { 1335 if (rtvp == NULLVP) 1336 vput(tvp); 1337 else 1338 vrele(tvp); 1339 } 1340 if (fdvp != rfdvp) 1341 vrele(fdvp); 1342 if (fvp != rfvp) 1343 vrele(fvp); 1344 1345 UNIONFS_INTERNAL_DEBUG("unionfs_rename: leave (%d)\n", error); 1346 1347 return (error); 1348 1349 unionfs_rename_abort: 1350 vput(tdvp); 1351 if (tdvp != rtdvp) 1352 vrele(rtdvp); 1353 if (tvp != NULLVP) { 1354 if (tdvp != tvp) 1355 vput(tvp); 1356 else 1357 vrele(tvp); 1358 } 1359 if (tvp != rtvp && rtvp != NULLVP) 1360 vrele(rtvp); 1361 if (fdvp != rfdvp) 1362 vrele(rfdvp); 1363 if (fvp != rfvp) 1364 vrele(rfvp); 1365 vrele(fdvp); 1366 vrele(fvp); 1367 1368 UNIONFS_INTERNAL_DEBUG("unionfs_rename: leave (%d)\n", error); 1369 1370 return (error); 1371 } 1372 1373 static int 1374 unionfs_mkdir(struct vop_mkdir_args *ap) 1375 { 1376 struct unionfs_node *dunp; 1377 struct componentname *cnp; 1378 struct vnode *dvp; 1379 struct vnode *udvp; 1380 struct vnode *uvp; 1381 struct vattr va; 1382 int error; 1383 int lkflags; 1384 1385 UNIONFS_INTERNAL_DEBUG("unionfs_mkdir: enter\n"); 1386 1387 KASSERT_UNIONFS_VNODE(ap->a_dvp); 1388 1389 error = EROFS; 1390 dvp = ap->a_dvp; 1391 dunp = VTOUNIONFS(dvp); 1392 cnp = ap->a_cnp; 1393 lkflags = cnp->cn_lkflags; 1394 udvp = dunp->un_uppervp; 1395 1396 if (udvp != NULLVP) { 1397 /* check opaque */ 1398 if (!(cnp->cn_flags & ISWHITEOUT)) { 1399 error = VOP_GETATTR(udvp, &va, cnp->cn_cred); 1400 if (error != 0) 1401 goto unionfs_mkdir_cleanup; 1402 if ((va.va_flags & OPAQUE) != 0) 1403 cnp->cn_flags |= ISWHITEOUT; 1404 } 1405 1406 int udvp_lkflags; 1407 bool uvp_created = false; 1408 unionfs_forward_vop_start(udvp, &udvp_lkflags); 1409 error = VOP_MKDIR(udvp, &uvp, cnp, ap->a_vap); 1410 if (error == 0) 1411 uvp_created = true; 1412 if (__predict_false(unionfs_forward_vop_finish(dvp, udvp, 1413 udvp_lkflags)) && error == 0) 1414 error = ENOENT; 1415 if (error == 0) { 1416 VOP_UNLOCK(uvp); 1417 cnp->cn_lkflags = LK_EXCLUSIVE; 1418 error = unionfs_nodeget(dvp->v_mount, uvp, NULLVP, 1419 dvp, ap->a_vpp, cnp); 1420 vrele(uvp); 1421 cnp->cn_lkflags = lkflags; 1422 } else if (uvp_created) 1423 vput(uvp); 1424 } 1425 1426 unionfs_mkdir_cleanup: 1427 UNIONFS_INTERNAL_DEBUG("unionfs_mkdir: leave (%d)\n", error); 1428 1429 return (error); 1430 } 1431 1432 static int 1433 unionfs_rmdir(struct vop_rmdir_args *ap) 1434 { 1435 struct unionfs_node *dunp; 1436 struct unionfs_node *unp; 1437 struct unionfs_mount *ump; 1438 struct componentname *cnp; 1439 struct thread *td; 1440 struct vnode *udvp; 1441 struct vnode *uvp; 1442 struct vnode *lvp; 1443 int error; 1444 1445 UNIONFS_INTERNAL_DEBUG("unionfs_rmdir: enter\n"); 1446 1447 KASSERT_UNIONFS_VNODE(ap->a_dvp); 1448 KASSERT_UNIONFS_VNODE(ap->a_vp); 1449 1450 error = 0; 1451 dunp = VTOUNIONFS(ap->a_dvp); 1452 unp = VTOUNIONFS(ap->a_vp); 1453 cnp = ap->a_cnp; 1454 td = curthread; 1455 udvp = dunp->un_uppervp; 1456 uvp = unp->un_uppervp; 1457 lvp = unp->un_lowervp; 1458 1459 if (udvp == NULLVP) 1460 return (EROFS); 1461 1462 if (udvp == uvp) 1463 return (EOPNOTSUPP); 1464 1465 if (uvp != NULLVP) { 1466 if (lvp != NULLVP) { 1467 error = unionfs_check_rmdir(ap->a_vp, cnp->cn_cred, td); 1468 if (error != 0) 1469 return (error); 1470 } 1471 ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount); 1472 if (ump->um_whitemode == UNIONFS_WHITE_ALWAYS || lvp != NULLVP) 1473 cnp->cn_flags |= DOWHITEOUT; 1474 /* 1475 * The relookup path will need to relock the parent dvp and 1476 * possibly the vp as well. Locking is expected to be done 1477 * in parent->child order; drop the lock on vp to avoid LOR 1478 * and potential recursion on vp's lock. 1479 * vp is expected to remain referenced during VOP_RMDIR(), 1480 * so vref/vrele should not be necessary here. 1481 */ 1482 VOP_UNLOCK(ap->a_vp); 1483 VNPASS(vrefcnt(ap->a_vp) > 0, ap->a_vp); 1484 error = unionfs_relookup_for_delete(ap->a_dvp, cnp, td); 1485 vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY); 1486 /* 1487 * VOP_RMDIR is dispatched against udvp, so if uvp became 1488 * doomed while the lock was dropped above the target 1489 * filesystem may not be able to cope. 1490 */ 1491 if (error == 0 && VN_IS_DOOMED(uvp)) 1492 error = ENOENT; 1493 if (error == 0) { 1494 int udvp_lkflags, uvp_lkflags; 1495 unionfs_forward_vop_start_pair(udvp, &udvp_lkflags, 1496 uvp, &uvp_lkflags); 1497 error = VOP_RMDIR(udvp, uvp, cnp); 1498 unionfs_forward_vop_finish_pair(ap->a_dvp, udvp, udvp_lkflags, 1499 ap->a_vp, uvp, uvp_lkflags); 1500 } 1501 } else if (lvp != NULLVP) 1502 error = unionfs_mkwhiteout(ap->a_dvp, udvp, cnp, td, 1503 unp->un_path, unp->un_pathlen); 1504 1505 if (error == 0) { 1506 cache_purge(ap->a_dvp); 1507 cache_purge(ap->a_vp); 1508 } 1509 1510 UNIONFS_INTERNAL_DEBUG("unionfs_rmdir: leave (%d)\n", error); 1511 1512 return (error); 1513 } 1514 1515 static int 1516 unionfs_symlink(struct vop_symlink_args *ap) 1517 { 1518 struct unionfs_node *dunp; 1519 struct componentname *cnp; 1520 struct vnode *udvp; 1521 struct vnode *uvp; 1522 int error; 1523 int lkflags; 1524 1525 UNIONFS_INTERNAL_DEBUG("unionfs_symlink: enter\n"); 1526 1527 KASSERT_UNIONFS_VNODE(ap->a_dvp); 1528 1529 error = EROFS; 1530 dunp = VTOUNIONFS(ap->a_dvp); 1531 cnp = ap->a_cnp; 1532 lkflags = cnp->cn_lkflags; 1533 udvp = dunp->un_uppervp; 1534 1535 if (udvp != NULLVP) { 1536 int udvp_lkflags; 1537 bool uvp_created = false; 1538 unionfs_forward_vop_start(udvp, &udvp_lkflags); 1539 error = VOP_SYMLINK(udvp, &uvp, cnp, ap->a_vap, ap->a_target); 1540 if (error == 0) 1541 uvp_created = true; 1542 if (__predict_false(unionfs_forward_vop_finish(ap->a_dvp, udvp, 1543 udvp_lkflags)) && error == 0) 1544 error = ENOENT; 1545 if (error == 0) { 1546 VOP_UNLOCK(uvp); 1547 cnp->cn_lkflags = LK_EXCLUSIVE; 1548 error = unionfs_nodeget(ap->a_dvp->v_mount, uvp, NULLVP, 1549 ap->a_dvp, ap->a_vpp, cnp); 1550 vrele(uvp); 1551 cnp->cn_lkflags = lkflags; 1552 } else if (uvp_created) 1553 vput(uvp); 1554 } 1555 1556 UNIONFS_INTERNAL_DEBUG("unionfs_symlink: leave (%d)\n", error); 1557 1558 return (error); 1559 } 1560 1561 static int 1562 unionfs_readdir(struct vop_readdir_args *ap) 1563 { 1564 struct unionfs_node *unp; 1565 struct unionfs_node_status *unsp; 1566 struct uio *uio; 1567 struct vnode *vp; 1568 struct vnode *uvp; 1569 struct vnode *lvp; 1570 struct thread *td; 1571 struct vattr va; 1572 1573 uint64_t *cookies_bk; 1574 int error; 1575 int eofflag; 1576 int ncookies_bk; 1577 int uio_offset_bk; 1578 enum unionfs_lkupgrade lkstatus; 1579 1580 UNIONFS_INTERNAL_DEBUG("unionfs_readdir: enter\n"); 1581 1582 KASSERT_UNIONFS_VNODE(ap->a_vp); 1583 1584 error = 0; 1585 eofflag = 0; 1586 uio_offset_bk = 0; 1587 uio = ap->a_uio; 1588 uvp = NULLVP; 1589 lvp = NULLVP; 1590 td = uio->uio_td; 1591 ncookies_bk = 0; 1592 cookies_bk = NULL; 1593 1594 vp = ap->a_vp; 1595 if (vp->v_type != VDIR) 1596 return (ENOTDIR); 1597 1598 /* 1599 * If the vnode is reclaimed while upgrading, we can't safely use unp 1600 * or do anything else unionfs- specific. 1601 */ 1602 lkstatus = unionfs_upgrade_lock(vp); 1603 if (lkstatus == UNIONFS_LKUPGRADE_DOOMED) 1604 error = EBADF; 1605 if (error == 0) { 1606 unp = VTOUNIONFS(vp); 1607 uvp = unp->un_uppervp; 1608 lvp = unp->un_lowervp; 1609 /* check the open count. unionfs needs open before readdir. */ 1610 unionfs_get_node_status(unp, td, &unsp); 1611 if ((uvp != NULLVP && unsp->uns_upper_opencnt <= 0) || 1612 (lvp != NULLVP && unsp->uns_lower_opencnt <= 0)) { 1613 unionfs_tryrem_node_status(unp, unsp); 1614 error = EBADF; 1615 } 1616 } 1617 unionfs_downgrade_lock(vp, lkstatus); 1618 if (error != 0) 1619 goto unionfs_readdir_exit; 1620 1621 /* check opaque */ 1622 if (uvp != NULLVP && lvp != NULLVP) { 1623 if ((error = VOP_GETATTR(uvp, &va, ap->a_cred)) != 0) 1624 goto unionfs_readdir_exit; 1625 if (va.va_flags & OPAQUE) 1626 lvp = NULLVP; 1627 } 1628 1629 /* upper only */ 1630 if (uvp != NULLVP && lvp == NULLVP) { 1631 error = VOP_READDIR(uvp, uio, ap->a_cred, ap->a_eofflag, 1632 ap->a_ncookies, ap->a_cookies); 1633 unsp->uns_readdir_status = 0; 1634 1635 goto unionfs_readdir_exit; 1636 } 1637 1638 /* lower only */ 1639 if (uvp == NULLVP && lvp != NULLVP) { 1640 error = VOP_READDIR(lvp, uio, ap->a_cred, ap->a_eofflag, 1641 ap->a_ncookies, ap->a_cookies); 1642 unsp->uns_readdir_status = 2; 1643 1644 goto unionfs_readdir_exit; 1645 } 1646 1647 /* 1648 * readdir upper and lower 1649 */ 1650 KASSERT(uvp != NULLVP, ("unionfs_readdir: null upper vp")); 1651 KASSERT(lvp != NULLVP, ("unionfs_readdir: null lower vp")); 1652 if (uio->uio_offset == 0) 1653 unsp->uns_readdir_status = 0; 1654 1655 if (unsp->uns_readdir_status == 0) { 1656 /* read upper */ 1657 error = VOP_READDIR(uvp, uio, ap->a_cred, &eofflag, 1658 ap->a_ncookies, ap->a_cookies); 1659 1660 if (error != 0 || eofflag == 0) 1661 goto unionfs_readdir_exit; 1662 unsp->uns_readdir_status = 1; 1663 1664 /* 1665 * UFS(and other FS) needs size of uio_resid larger than 1666 * DIRBLKSIZ. 1667 * size of DIRBLKSIZ equals DEV_BSIZE. 1668 * (see: ufs/ufs/ufs_vnops.c ufs_readdir func , ufs/ufs/dir.h) 1669 */ 1670 if (uio->uio_resid <= (uio->uio_resid & (DEV_BSIZE -1))) 1671 goto unionfs_readdir_exit; 1672 1673 /* 1674 * Backup cookies. 1675 * It prepares to readdir in lower. 1676 */ 1677 if (ap->a_ncookies != NULL) { 1678 ncookies_bk = *(ap->a_ncookies); 1679 *(ap->a_ncookies) = 0; 1680 } 1681 if (ap->a_cookies != NULL) { 1682 cookies_bk = *(ap->a_cookies); 1683 *(ap->a_cookies) = NULL; 1684 } 1685 } 1686 1687 /* initialize for readdir in lower */ 1688 if (unsp->uns_readdir_status == 1) { 1689 unsp->uns_readdir_status = 2; 1690 /* 1691 * Backup uio_offset. See the comment after the 1692 * VOP_READDIR call on the lower layer. 1693 */ 1694 uio_offset_bk = uio->uio_offset; 1695 uio->uio_offset = 0; 1696 } 1697 1698 if (lvp == NULLVP) { 1699 error = EBADF; 1700 goto unionfs_readdir_exit; 1701 } 1702 /* read lower */ 1703 error = VOP_READDIR(lvp, uio, ap->a_cred, ap->a_eofflag, 1704 ap->a_ncookies, ap->a_cookies); 1705 1706 /* 1707 * We can't return an uio_offset of 0: this would trigger an 1708 * infinite loop, because the next call to unionfs_readdir would 1709 * always restart with the upper layer (uio_offset == 0) and 1710 * always return some data. 1711 * 1712 * This happens when the lower layer root directory is removed. 1713 * (A root directory deleting of unionfs should not be permitted. 1714 * But current VFS can not do it.) 1715 */ 1716 if (uio->uio_offset == 0) 1717 uio->uio_offset = uio_offset_bk; 1718 1719 if (cookies_bk != NULL) { 1720 /* merge cookies */ 1721 int size; 1722 uint64_t *newcookies, *pos; 1723 1724 size = *(ap->a_ncookies) + ncookies_bk; 1725 newcookies = (uint64_t *) malloc(size * sizeof(*newcookies), 1726 M_TEMP, M_WAITOK); 1727 pos = newcookies; 1728 1729 memcpy(pos, cookies_bk, ncookies_bk * sizeof(*newcookies)); 1730 pos += ncookies_bk; 1731 memcpy(pos, *(ap->a_cookies), 1732 *(ap->a_ncookies) * sizeof(*newcookies)); 1733 free(cookies_bk, M_TEMP); 1734 free(*(ap->a_cookies), M_TEMP); 1735 *(ap->a_ncookies) = size; 1736 *(ap->a_cookies) = newcookies; 1737 } 1738 1739 unionfs_readdir_exit: 1740 if (error != 0 && ap->a_eofflag != NULL) 1741 *(ap->a_eofflag) = 1; 1742 1743 UNIONFS_INTERNAL_DEBUG("unionfs_readdir: leave (%d)\n", error); 1744 1745 return (error); 1746 } 1747 1748 static int 1749 unionfs_readlink(struct vop_readlink_args *ap) 1750 { 1751 struct unionfs_node *unp; 1752 struct vnode *vp; 1753 int error; 1754 1755 UNIONFS_INTERNAL_DEBUG("unionfs_readlink: enter\n"); 1756 1757 KASSERT_UNIONFS_VNODE(ap->a_vp); 1758 1759 unp = VTOUNIONFS(ap->a_vp); 1760 vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); 1761 1762 error = VOP_READLINK(vp, ap->a_uio, ap->a_cred); 1763 1764 UNIONFS_INTERNAL_DEBUG("unionfs_readlink: leave (%d)\n", error); 1765 1766 return (error); 1767 } 1768 1769 static int 1770 unionfs_getwritemount(struct vop_getwritemount_args *ap) 1771 { 1772 struct unionfs_node *unp; 1773 struct vnode *uvp; 1774 struct vnode *vp, *ovp; 1775 int error; 1776 1777 UNIONFS_INTERNAL_DEBUG("unionfs_getwritemount: enter\n"); 1778 1779 error = 0; 1780 vp = ap->a_vp; 1781 uvp = NULLVP; 1782 1783 VI_LOCK(vp); 1784 unp = VTOUNIONFS(vp); 1785 if (unp != NULL) 1786 uvp = unp->un_uppervp; 1787 1788 /* 1789 * If our node has no upper vnode, check the parent directory. 1790 * We may be initiating a write operation that will produce a 1791 * new upper vnode through CoW. 1792 */ 1793 if (uvp == NULLVP && unp != NULL) { 1794 ovp = vp; 1795 vp = unp->un_dvp; 1796 /* 1797 * Only the root vnode should have an empty parent, but it 1798 * should not have an empty uppervp, so we shouldn't get here. 1799 */ 1800 VNASSERT(vp != NULL, ovp, ("%s: NULL parent vnode", __func__)); 1801 VI_UNLOCK(ovp); 1802 VI_LOCK(vp); 1803 unp = VTOUNIONFS(vp); 1804 if (unp != NULL) 1805 uvp = unp->un_uppervp; 1806 if (uvp == NULLVP) 1807 error = EACCES; 1808 } 1809 1810 if (uvp != NULLVP) { 1811 vholdnz(uvp); 1812 VI_UNLOCK(vp); 1813 error = VOP_GETWRITEMOUNT(uvp, ap->a_mpp); 1814 vdrop(uvp); 1815 } else { 1816 VI_UNLOCK(vp); 1817 *(ap->a_mpp) = NULL; 1818 } 1819 1820 UNIONFS_INTERNAL_DEBUG("unionfs_getwritemount: leave (%d)\n", error); 1821 1822 return (error); 1823 } 1824 1825 static int 1826 unionfs_inactive(struct vop_inactive_args *ap) 1827 { 1828 ap->a_vp->v_object = NULL; 1829 vrecycle(ap->a_vp); 1830 return (0); 1831 } 1832 1833 static int 1834 unionfs_reclaim(struct vop_reclaim_args *ap) 1835 { 1836 /* UNIONFS_INTERNAL_DEBUG("unionfs_reclaim: enter\n"); */ 1837 1838 unionfs_noderem(ap->a_vp); 1839 1840 /* UNIONFS_INTERNAL_DEBUG("unionfs_reclaim: leave\n"); */ 1841 1842 return (0); 1843 } 1844 1845 static int 1846 unionfs_print(struct vop_print_args *ap) 1847 { 1848 struct unionfs_node *unp; 1849 /* struct unionfs_node_status *unsp; */ 1850 1851 unp = VTOUNIONFS(ap->a_vp); 1852 /* unionfs_get_node_status(unp, curthread, &unsp); */ 1853 1854 printf("unionfs_vp=%p, uppervp=%p, lowervp=%p\n", 1855 ap->a_vp, unp->un_uppervp, unp->un_lowervp); 1856 /* 1857 printf("unionfs opencnt: uppervp=%d, lowervp=%d\n", 1858 unsp->uns_upper_opencnt, unsp->uns_lower_opencnt); 1859 */ 1860 1861 if (unp->un_uppervp != NULLVP) 1862 vn_printf(unp->un_uppervp, "unionfs: upper "); 1863 if (unp->un_lowervp != NULLVP) 1864 vn_printf(unp->un_lowervp, "unionfs: lower "); 1865 1866 return (0); 1867 } 1868 1869 static int 1870 unionfs_get_llt_revlock(struct vnode *vp, int flags) 1871 { 1872 int revlock; 1873 1874 revlock = 0; 1875 1876 switch (flags & LK_TYPE_MASK) { 1877 case LK_SHARED: 1878 if (VOP_ISLOCKED(vp) == LK_EXCLUSIVE) 1879 revlock = LK_UPGRADE; 1880 else 1881 revlock = LK_RELEASE; 1882 break; 1883 case LK_EXCLUSIVE: 1884 case LK_UPGRADE: 1885 revlock = LK_RELEASE; 1886 break; 1887 case LK_DOWNGRADE: 1888 revlock = LK_UPGRADE; 1889 break; 1890 default: 1891 break; 1892 } 1893 1894 return (revlock); 1895 } 1896 1897 /* 1898 * The state of an acquired lock is adjusted similarly to 1899 * the time of error generating. 1900 * flags: LK_RELEASE or LK_UPGRADE 1901 */ 1902 static void 1903 unionfs_revlock(struct vnode *vp, int flags) 1904 { 1905 if (flags & LK_RELEASE) 1906 VOP_UNLOCK_FLAGS(vp, flags); 1907 else { 1908 /* UPGRADE */ 1909 if (vn_lock(vp, flags) != 0) 1910 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 1911 } 1912 } 1913 1914 static int 1915 unionfs_lock(struct vop_lock1_args *ap) 1916 { 1917 struct unionfs_node *unp; 1918 struct vnode *vp; 1919 struct vnode *uvp; 1920 struct vnode *lvp; 1921 int error; 1922 int flags; 1923 int revlock; 1924 int interlock; 1925 int uhold; 1926 1927 /* 1928 * TODO: rework the unionfs locking scheme. 1929 * It's not guaranteed to be safe to blindly lock two vnodes on 1930 * different mounts as is done here. Further, the entanglement 1931 * of locking both vnodes with the various options that can be 1932 * passed to VOP_LOCK() makes this code hard to reason about. 1933 * Instead, consider locking only the upper vnode, or the lower 1934 * vnode is the upper is not present, and taking separate measures 1935 * to lock both vnodes in the few cases when that is needed. 1936 */ 1937 error = 0; 1938 interlock = 1; 1939 uhold = 0; 1940 flags = ap->a_flags; 1941 vp = ap->a_vp; 1942 1943 if (LK_RELEASE == (flags & LK_TYPE_MASK) || !(flags & LK_TYPE_MASK)) 1944 return (VOP_UNLOCK_FLAGS(vp, flags | LK_RELEASE)); 1945 1946 if ((flags & LK_INTERLOCK) == 0) 1947 VI_LOCK(vp); 1948 1949 unp = VTOUNIONFS(vp); 1950 if (unp == NULL) 1951 goto unionfs_lock_null_vnode; 1952 1953 KASSERT_UNIONFS_VNODE(ap->a_vp); 1954 1955 lvp = unp->un_lowervp; 1956 uvp = unp->un_uppervp; 1957 1958 if ((revlock = unionfs_get_llt_revlock(vp, flags)) == 0) 1959 panic("unknown lock type: 0x%x", flags & LK_TYPE_MASK); 1960 1961 /* 1962 * During unmount, the root vnode lock may be taken recursively, 1963 * because it may share the same v_vnlock field as the vnode covered by 1964 * the unionfs mount. The covered vnode is locked across VFS_UNMOUNT(), 1965 * and the same lock may be taken recursively here during vflush() 1966 * issued by unionfs_unmount(). 1967 */ 1968 if ((flags & LK_TYPE_MASK) == LK_EXCLUSIVE && 1969 (vp->v_vflag & VV_ROOT) != 0) 1970 flags |= LK_CANRECURSE; 1971 1972 if (lvp != NULLVP) { 1973 if (uvp != NULLVP && flags & LK_UPGRADE) { 1974 /* 1975 * Share Lock is once released and a deadlock is 1976 * avoided. 1977 */ 1978 vholdnz(uvp); 1979 uhold = 1; 1980 VOP_UNLOCK(uvp); 1981 } 1982 VI_LOCK_FLAGS(lvp, MTX_DUPOK); 1983 flags |= LK_INTERLOCK; 1984 vholdl(lvp); 1985 1986 VI_UNLOCK(vp); 1987 ap->a_flags &= ~LK_INTERLOCK; 1988 1989 error = VOP_LOCK(lvp, flags); 1990 1991 VI_LOCK(vp); 1992 unp = VTOUNIONFS(vp); 1993 if (unp == NULL) { 1994 /* vnode is released. */ 1995 VI_UNLOCK(vp); 1996 if (error == 0) 1997 VOP_UNLOCK(lvp); 1998 vdrop(lvp); 1999 if (uhold != 0) 2000 vdrop(uvp); 2001 goto unionfs_lock_fallback; 2002 } 2003 } 2004 2005 if (error == 0 && uvp != NULLVP) { 2006 if (uhold && flags & LK_UPGRADE) { 2007 flags &= ~LK_TYPE_MASK; 2008 flags |= LK_EXCLUSIVE; 2009 } 2010 VI_LOCK_FLAGS(uvp, MTX_DUPOK); 2011 flags |= LK_INTERLOCK; 2012 if (uhold == 0) { 2013 vholdl(uvp); 2014 uhold = 1; 2015 } 2016 2017 VI_UNLOCK(vp); 2018 ap->a_flags &= ~LK_INTERLOCK; 2019 2020 error = VOP_LOCK(uvp, flags); 2021 2022 VI_LOCK(vp); 2023 unp = VTOUNIONFS(vp); 2024 if (unp == NULL) { 2025 /* vnode is released. */ 2026 VI_UNLOCK(vp); 2027 if (error == 0) 2028 VOP_UNLOCK(uvp); 2029 vdrop(uvp); 2030 if (lvp != NULLVP) { 2031 VOP_UNLOCK(lvp); 2032 vdrop(lvp); 2033 } 2034 goto unionfs_lock_fallback; 2035 } 2036 if (error != 0 && lvp != NULLVP) { 2037 /* rollback */ 2038 VI_UNLOCK(vp); 2039 unionfs_revlock(lvp, revlock); 2040 interlock = 0; 2041 } 2042 } 2043 2044 if (interlock) 2045 VI_UNLOCK(vp); 2046 if (lvp != NULLVP) 2047 vdrop(lvp); 2048 if (uhold != 0) 2049 vdrop(uvp); 2050 2051 return (error); 2052 2053 unionfs_lock_null_vnode: 2054 ap->a_flags |= LK_INTERLOCK; 2055 return (vop_stdlock(ap)); 2056 2057 unionfs_lock_fallback: 2058 /* 2059 * If we reach this point, we've discovered the unionfs vnode 2060 * has been reclaimed while the upper/lower vnode locks were 2061 * temporarily dropped. Such temporary droppage may happen 2062 * during the course of an LK_UPGRADE operation itself, and in 2063 * that case LK_UPGRADE must be cleared as the unionfs vnode's 2064 * lock has been reset to point to the standard v_lock field, 2065 * which has not previously been held. 2066 */ 2067 if (flags & LK_UPGRADE) { 2068 ap->a_flags &= ~LK_TYPE_MASK; 2069 ap->a_flags |= LK_EXCLUSIVE; 2070 } 2071 return (vop_stdlock(ap)); 2072 } 2073 2074 static int 2075 unionfs_unlock(struct vop_unlock_args *ap) 2076 { 2077 struct vnode *vp; 2078 struct vnode *lvp; 2079 struct vnode *uvp; 2080 struct unionfs_node *unp; 2081 int error; 2082 int uhold; 2083 2084 KASSERT_UNIONFS_VNODE(ap->a_vp); 2085 2086 error = 0; 2087 uhold = 0; 2088 vp = ap->a_vp; 2089 2090 unp = VTOUNIONFS(vp); 2091 if (unp == NULL) 2092 goto unionfs_unlock_null_vnode; 2093 lvp = unp->un_lowervp; 2094 uvp = unp->un_uppervp; 2095 2096 if (lvp != NULLVP) { 2097 vholdnz(lvp); 2098 error = VOP_UNLOCK(lvp); 2099 } 2100 2101 if (error == 0 && uvp != NULLVP) { 2102 vholdnz(uvp); 2103 uhold = 1; 2104 error = VOP_UNLOCK(uvp); 2105 } 2106 2107 if (lvp != NULLVP) 2108 vdrop(lvp); 2109 if (uhold != 0) 2110 vdrop(uvp); 2111 2112 return error; 2113 2114 unionfs_unlock_null_vnode: 2115 return (vop_stdunlock(ap)); 2116 } 2117 2118 static int 2119 unionfs_pathconf(struct vop_pathconf_args *ap) 2120 { 2121 struct unionfs_node *unp; 2122 struct vnode *vp; 2123 2124 KASSERT_UNIONFS_VNODE(ap->a_vp); 2125 2126 unp = VTOUNIONFS(ap->a_vp); 2127 vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); 2128 2129 return (VOP_PATHCONF(vp, ap->a_name, ap->a_retval)); 2130 } 2131 2132 static int 2133 unionfs_advlock(struct vop_advlock_args *ap) 2134 { 2135 struct unionfs_node *unp; 2136 struct unionfs_node_status *unsp; 2137 struct vnode *vp; 2138 struct vnode *uvp; 2139 struct thread *td; 2140 int error; 2141 2142 UNIONFS_INTERNAL_DEBUG("unionfs_advlock: enter\n"); 2143 2144 KASSERT_UNIONFS_VNODE(ap->a_vp); 2145 2146 vp = ap->a_vp; 2147 td = curthread; 2148 2149 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2150 2151 unp = VTOUNIONFS(ap->a_vp); 2152 uvp = unp->un_uppervp; 2153 2154 if (uvp == NULLVP) { 2155 error = unionfs_copyfile(unp, 1, td->td_ucred, td); 2156 if (error != 0) 2157 goto unionfs_advlock_abort; 2158 uvp = unp->un_uppervp; 2159 2160 unionfs_get_node_status(unp, td, &unsp); 2161 if (unsp->uns_lower_opencnt > 0) { 2162 /* try reopen the vnode */ 2163 error = VOP_OPEN(uvp, unsp->uns_lower_openmode, 2164 td->td_ucred, td, NULL); 2165 if (error) 2166 goto unionfs_advlock_abort; 2167 unsp->uns_upper_opencnt++; 2168 VOP_CLOSE(unp->un_lowervp, unsp->uns_lower_openmode, 2169 td->td_ucred, td); 2170 unsp->uns_lower_opencnt--; 2171 } else 2172 unionfs_tryrem_node_status(unp, unsp); 2173 } 2174 2175 VOP_UNLOCK(vp); 2176 2177 error = VOP_ADVLOCK(uvp, ap->a_id, ap->a_op, ap->a_fl, ap->a_flags); 2178 2179 UNIONFS_INTERNAL_DEBUG("unionfs_advlock: leave (%d)\n", error); 2180 2181 return error; 2182 2183 unionfs_advlock_abort: 2184 VOP_UNLOCK(vp); 2185 2186 UNIONFS_INTERNAL_DEBUG("unionfs_advlock: leave (%d)\n", error); 2187 2188 return error; 2189 } 2190 2191 static int 2192 unionfs_strategy(struct vop_strategy_args *ap) 2193 { 2194 struct unionfs_node *unp; 2195 struct vnode *vp; 2196 2197 KASSERT_UNIONFS_VNODE(ap->a_vp); 2198 2199 unp = VTOUNIONFS(ap->a_vp); 2200 vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); 2201 2202 #ifdef DIAGNOSTIC 2203 if (vp == NULLVP) 2204 panic("unionfs_strategy: nullvp"); 2205 2206 if (ap->a_bp->b_iocmd == BIO_WRITE && vp == unp->un_lowervp) 2207 panic("unionfs_strategy: writing to lowervp"); 2208 #endif 2209 2210 return (VOP_STRATEGY(vp, ap->a_bp)); 2211 } 2212 2213 static int 2214 unionfs_getacl(struct vop_getacl_args *ap) 2215 { 2216 struct unionfs_node *unp; 2217 struct vnode *vp; 2218 int error; 2219 2220 KASSERT_UNIONFS_VNODE(ap->a_vp); 2221 2222 unp = VTOUNIONFS(ap->a_vp); 2223 vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); 2224 2225 UNIONFS_INTERNAL_DEBUG("unionfs_getacl: enter\n"); 2226 2227 error = VOP_GETACL(vp, ap->a_type, ap->a_aclp, ap->a_cred, ap->a_td); 2228 2229 UNIONFS_INTERNAL_DEBUG("unionfs_getacl: leave (%d)\n", error); 2230 2231 return (error); 2232 } 2233 2234 static int 2235 unionfs_setacl(struct vop_setacl_args *ap) 2236 { 2237 struct unionfs_node *unp; 2238 struct vnode *uvp; 2239 struct vnode *lvp; 2240 struct thread *td; 2241 int error; 2242 2243 UNIONFS_INTERNAL_DEBUG("unionfs_setacl: enter\n"); 2244 2245 KASSERT_UNIONFS_VNODE(ap->a_vp); 2246 2247 error = EROFS; 2248 unp = VTOUNIONFS(ap->a_vp); 2249 uvp = unp->un_uppervp; 2250 lvp = unp->un_lowervp; 2251 td = ap->a_td; 2252 2253 if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY) 2254 return (EROFS); 2255 2256 if (uvp == NULLVP && lvp->v_type == VREG) { 2257 if ((error = unionfs_copyfile(unp, 1, ap->a_cred, td)) != 0) 2258 return (error); 2259 uvp = unp->un_uppervp; 2260 } 2261 2262 if (uvp != NULLVP) { 2263 int lkflags; 2264 unionfs_forward_vop_start(uvp, &lkflags); 2265 error = VOP_SETACL(uvp, ap->a_type, ap->a_aclp, ap->a_cred, td); 2266 unionfs_forward_vop_finish(ap->a_vp, uvp, lkflags); 2267 } 2268 2269 UNIONFS_INTERNAL_DEBUG("unionfs_setacl: leave (%d)\n", error); 2270 2271 return (error); 2272 } 2273 2274 static int 2275 unionfs_aclcheck(struct vop_aclcheck_args *ap) 2276 { 2277 struct unionfs_node *unp; 2278 struct vnode *vp; 2279 int error; 2280 2281 UNIONFS_INTERNAL_DEBUG("unionfs_aclcheck: enter\n"); 2282 2283 KASSERT_UNIONFS_VNODE(ap->a_vp); 2284 2285 unp = VTOUNIONFS(ap->a_vp); 2286 vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); 2287 2288 error = VOP_ACLCHECK(vp, ap->a_type, ap->a_aclp, ap->a_cred, ap->a_td); 2289 2290 UNIONFS_INTERNAL_DEBUG("unionfs_aclcheck: leave (%d)\n", error); 2291 2292 return (error); 2293 } 2294 2295 static int 2296 unionfs_openextattr(struct vop_openextattr_args *ap) 2297 { 2298 struct unionfs_node *unp; 2299 struct vnode *vp; 2300 struct vnode *tvp; 2301 int error; 2302 2303 KASSERT_UNIONFS_VNODE(ap->a_vp); 2304 2305 vp = ap->a_vp; 2306 unp = VTOUNIONFS(vp); 2307 tvp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); 2308 2309 if ((tvp == unp->un_uppervp && (unp->un_flag & UNIONFS_OPENEXTU)) || 2310 (tvp == unp->un_lowervp && (unp->un_flag & UNIONFS_OPENEXTL))) 2311 return (EBUSY); 2312 2313 error = VOP_OPENEXTATTR(tvp, ap->a_cred, ap->a_td); 2314 2315 if (error == 0) { 2316 if (vn_lock(vp, LK_UPGRADE) != 0) 2317 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2318 if (!VN_IS_DOOMED(vp)) { 2319 if (tvp == unp->un_uppervp) 2320 unp->un_flag |= UNIONFS_OPENEXTU; 2321 else 2322 unp->un_flag |= UNIONFS_OPENEXTL; 2323 } 2324 vn_lock(vp, LK_DOWNGRADE | LK_RETRY); 2325 } 2326 2327 return (error); 2328 } 2329 2330 static int 2331 unionfs_closeextattr(struct vop_closeextattr_args *ap) 2332 { 2333 struct unionfs_node *unp; 2334 struct vnode *vp; 2335 struct vnode *tvp; 2336 int error; 2337 2338 KASSERT_UNIONFS_VNODE(ap->a_vp); 2339 2340 vp = ap->a_vp; 2341 unp = VTOUNIONFS(vp); 2342 tvp = NULLVP; 2343 2344 if (unp->un_flag & UNIONFS_OPENEXTU) 2345 tvp = unp->un_uppervp; 2346 else if (unp->un_flag & UNIONFS_OPENEXTL) 2347 tvp = unp->un_lowervp; 2348 2349 if (tvp == NULLVP) 2350 return (EOPNOTSUPP); 2351 2352 error = VOP_CLOSEEXTATTR(tvp, ap->a_commit, ap->a_cred, ap->a_td); 2353 2354 if (error == 0) { 2355 if (vn_lock(vp, LK_UPGRADE) != 0) 2356 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2357 if (!VN_IS_DOOMED(vp)) { 2358 if (tvp == unp->un_uppervp) 2359 unp->un_flag &= ~UNIONFS_OPENEXTU; 2360 else 2361 unp->un_flag &= ~UNIONFS_OPENEXTL; 2362 } 2363 vn_lock(vp, LK_DOWNGRADE | LK_RETRY); 2364 } 2365 2366 return (error); 2367 } 2368 2369 static int 2370 unionfs_getextattr(struct vop_getextattr_args *ap) 2371 { 2372 struct unionfs_node *unp; 2373 struct vnode *vp; 2374 2375 KASSERT_UNIONFS_VNODE(ap->a_vp); 2376 2377 unp = VTOUNIONFS(ap->a_vp); 2378 vp = NULLVP; 2379 2380 if (unp->un_flag & UNIONFS_OPENEXTU) 2381 vp = unp->un_uppervp; 2382 else if (unp->un_flag & UNIONFS_OPENEXTL) 2383 vp = unp->un_lowervp; 2384 2385 if (vp == NULLVP) 2386 return (EOPNOTSUPP); 2387 2388 return (VOP_GETEXTATTR(vp, ap->a_attrnamespace, ap->a_name, 2389 ap->a_uio, ap->a_size, ap->a_cred, ap->a_td)); 2390 } 2391 2392 static int 2393 unionfs_setextattr(struct vop_setextattr_args *ap) 2394 { 2395 struct unionfs_node *unp; 2396 struct vnode *uvp; 2397 struct vnode *lvp; 2398 struct vnode *ovp; 2399 struct ucred *cred; 2400 struct thread *td; 2401 int error; 2402 2403 KASSERT_UNIONFS_VNODE(ap->a_vp); 2404 2405 error = EROFS; 2406 unp = VTOUNIONFS(ap->a_vp); 2407 uvp = unp->un_uppervp; 2408 lvp = unp->un_lowervp; 2409 ovp = NULLVP; 2410 cred = ap->a_cred; 2411 td = ap->a_td; 2412 2413 UNIONFS_INTERNAL_DEBUG("unionfs_setextattr: enter (un_flag=%x)\n", 2414 unp->un_flag); 2415 2416 if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY) 2417 return (EROFS); 2418 2419 if (unp->un_flag & UNIONFS_OPENEXTU) 2420 ovp = unp->un_uppervp; 2421 else if (unp->un_flag & UNIONFS_OPENEXTL) 2422 ovp = unp->un_lowervp; 2423 2424 if (ovp == NULLVP) 2425 return (EOPNOTSUPP); 2426 2427 if (ovp == lvp && lvp->v_type == VREG) { 2428 VOP_CLOSEEXTATTR(lvp, 0, cred, td); 2429 if (uvp == NULLVP && 2430 (error = unionfs_copyfile(unp, 1, cred, td)) != 0) { 2431 unionfs_setextattr_reopen: 2432 if ((unp->un_flag & UNIONFS_OPENEXTL) && 2433 VOP_OPENEXTATTR(lvp, cred, td)) { 2434 #ifdef DIAGNOSTIC 2435 panic("unionfs: VOP_OPENEXTATTR failed"); 2436 #endif 2437 unp->un_flag &= ~UNIONFS_OPENEXTL; 2438 } 2439 goto unionfs_setextattr_abort; 2440 } 2441 uvp = unp->un_uppervp; 2442 if ((error = VOP_OPENEXTATTR(uvp, cred, td)) != 0) 2443 goto unionfs_setextattr_reopen; 2444 unp->un_flag &= ~UNIONFS_OPENEXTL; 2445 unp->un_flag |= UNIONFS_OPENEXTU; 2446 ovp = uvp; 2447 } 2448 2449 if (ovp == uvp) { 2450 int lkflags; 2451 unionfs_forward_vop_start(ovp, &lkflags); 2452 error = VOP_SETEXTATTR(ovp, ap->a_attrnamespace, ap->a_name, 2453 ap->a_uio, cred, td); 2454 unionfs_forward_vop_finish(ap->a_vp, ovp, lkflags); 2455 } 2456 2457 unionfs_setextattr_abort: 2458 UNIONFS_INTERNAL_DEBUG("unionfs_setextattr: leave (%d)\n", error); 2459 2460 return (error); 2461 } 2462 2463 static int 2464 unionfs_listextattr(struct vop_listextattr_args *ap) 2465 { 2466 struct unionfs_node *unp; 2467 struct vnode *vp; 2468 2469 KASSERT_UNIONFS_VNODE(ap->a_vp); 2470 2471 unp = VTOUNIONFS(ap->a_vp); 2472 vp = NULLVP; 2473 2474 if (unp->un_flag & UNIONFS_OPENEXTU) 2475 vp = unp->un_uppervp; 2476 else if (unp->un_flag & UNIONFS_OPENEXTL) 2477 vp = unp->un_lowervp; 2478 2479 if (vp == NULLVP) 2480 return (EOPNOTSUPP); 2481 2482 return (VOP_LISTEXTATTR(vp, ap->a_attrnamespace, ap->a_uio, 2483 ap->a_size, ap->a_cred, ap->a_td)); 2484 } 2485 2486 static int 2487 unionfs_deleteextattr(struct vop_deleteextattr_args *ap) 2488 { 2489 struct unionfs_node *unp; 2490 struct vnode *uvp; 2491 struct vnode *lvp; 2492 struct vnode *ovp; 2493 struct ucred *cred; 2494 struct thread *td; 2495 int error; 2496 2497 KASSERT_UNIONFS_VNODE(ap->a_vp); 2498 2499 error = EROFS; 2500 unp = VTOUNIONFS(ap->a_vp); 2501 uvp = unp->un_uppervp; 2502 lvp = unp->un_lowervp; 2503 ovp = NULLVP; 2504 cred = ap->a_cred; 2505 td = ap->a_td; 2506 2507 UNIONFS_INTERNAL_DEBUG("unionfs_deleteextattr: enter (un_flag=%x)\n", 2508 unp->un_flag); 2509 2510 if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY) 2511 return (EROFS); 2512 2513 if (unp->un_flag & UNIONFS_OPENEXTU) 2514 ovp = unp->un_uppervp; 2515 else if (unp->un_flag & UNIONFS_OPENEXTL) 2516 ovp = unp->un_lowervp; 2517 2518 if (ovp == NULLVP) 2519 return (EOPNOTSUPP); 2520 2521 if (ovp == lvp && lvp->v_type == VREG) { 2522 VOP_CLOSEEXTATTR(lvp, 0, cred, td); 2523 if (uvp == NULLVP && 2524 (error = unionfs_copyfile(unp, 1, cred, td)) != 0) { 2525 unionfs_deleteextattr_reopen: 2526 if ((unp->un_flag & UNIONFS_OPENEXTL) && 2527 VOP_OPENEXTATTR(lvp, cred, td)) { 2528 #ifdef DIAGNOSTIC 2529 panic("unionfs: VOP_OPENEXTATTR failed"); 2530 #endif 2531 unp->un_flag &= ~UNIONFS_OPENEXTL; 2532 } 2533 goto unionfs_deleteextattr_abort; 2534 } 2535 uvp = unp->un_uppervp; 2536 if ((error = VOP_OPENEXTATTR(uvp, cred, td)) != 0) 2537 goto unionfs_deleteextattr_reopen; 2538 unp->un_flag &= ~UNIONFS_OPENEXTL; 2539 unp->un_flag |= UNIONFS_OPENEXTU; 2540 ovp = uvp; 2541 } 2542 2543 if (ovp == uvp) 2544 error = VOP_DELETEEXTATTR(ovp, ap->a_attrnamespace, ap->a_name, 2545 ap->a_cred, ap->a_td); 2546 2547 unionfs_deleteextattr_abort: 2548 UNIONFS_INTERNAL_DEBUG("unionfs_deleteextattr: leave (%d)\n", error); 2549 2550 return (error); 2551 } 2552 2553 static int 2554 unionfs_setlabel(struct vop_setlabel_args *ap) 2555 { 2556 struct unionfs_node *unp; 2557 struct vnode *uvp; 2558 struct vnode *lvp; 2559 struct thread *td; 2560 int error; 2561 2562 UNIONFS_INTERNAL_DEBUG("unionfs_setlabel: enter\n"); 2563 2564 KASSERT_UNIONFS_VNODE(ap->a_vp); 2565 2566 error = EROFS; 2567 unp = VTOUNIONFS(ap->a_vp); 2568 uvp = unp->un_uppervp; 2569 lvp = unp->un_lowervp; 2570 td = ap->a_td; 2571 2572 if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY) 2573 return (EROFS); 2574 2575 if (uvp == NULLVP && lvp->v_type == VREG) { 2576 if ((error = unionfs_copyfile(unp, 1, ap->a_cred, td)) != 0) 2577 return (error); 2578 uvp = unp->un_uppervp; 2579 } 2580 2581 if (uvp != NULLVP) 2582 error = VOP_SETLABEL(uvp, ap->a_label, ap->a_cred, td); 2583 2584 UNIONFS_INTERNAL_DEBUG("unionfs_setlabel: leave (%d)\n", error); 2585 2586 return (error); 2587 } 2588 2589 static int 2590 unionfs_vptofh(struct vop_vptofh_args *ap) 2591 { 2592 return (EOPNOTSUPP); 2593 } 2594 2595 static int 2596 unionfs_add_writecount(struct vop_add_writecount_args *ap) 2597 { 2598 struct vnode *tvp, *vp; 2599 struct unionfs_node *unp; 2600 int error, writerefs __diagused; 2601 2602 vp = ap->a_vp; 2603 unp = VTOUNIONFS(vp); 2604 tvp = unp->un_uppervp; 2605 KASSERT(tvp != NULL, 2606 ("%s: adding write ref without upper vnode", __func__)); 2607 error = VOP_ADD_WRITECOUNT(tvp, ap->a_inc); 2608 if (error != 0) 2609 return (error); 2610 /* 2611 * We need to track the write refs we've passed to the underlying 2612 * vnodes so that we can undo them in case we are forcibly unmounted. 2613 */ 2614 writerefs = atomic_fetchadd_int(&vp->v_writecount, ap->a_inc); 2615 /* text refs are bypassed to lowervp */ 2616 VNASSERT(writerefs >= 0, vp, 2617 ("%s: invalid write count %d", __func__, writerefs)); 2618 VNASSERT(writerefs + ap->a_inc >= 0, vp, 2619 ("%s: invalid write count inc %d + %d", __func__, 2620 writerefs, ap->a_inc)); 2621 return (0); 2622 } 2623 2624 static int 2625 unionfs_vput_pair(struct vop_vput_pair_args *ap) 2626 { 2627 struct mount *mp; 2628 struct vnode *dvp, *vp, **vpp, *lvp, *ldvp, *uvp, *udvp, *tempvp; 2629 struct unionfs_node *dunp, *unp; 2630 int error, res; 2631 2632 dvp = ap->a_dvp; 2633 vpp = ap->a_vpp; 2634 vp = NULLVP; 2635 lvp = NULLVP; 2636 uvp = NULLVP; 2637 unp = NULL; 2638 2639 dunp = VTOUNIONFS(dvp); 2640 udvp = dunp->un_uppervp; 2641 ldvp = dunp->un_lowervp; 2642 2643 /* 2644 * Underlying vnodes should be locked because the encompassing unionfs 2645 * node is locked, but will not be referenced, as the reference will 2646 * only be on the unionfs node. Reference them now so that the vput()s 2647 * performed by VOP_VPUT_PAIR() will have a reference to drop. 2648 */ 2649 if (udvp != NULLVP) 2650 vref(udvp); 2651 if (ldvp != NULLVP) 2652 vref(ldvp); 2653 2654 if (vpp != NULL) 2655 vp = *vpp; 2656 2657 if (vp != NULLVP) { 2658 unp = VTOUNIONFS(vp); 2659 uvp = unp->un_uppervp; 2660 lvp = unp->un_lowervp; 2661 if (uvp != NULLVP) 2662 vref(uvp); 2663 if (lvp != NULLVP) 2664 vref(lvp); 2665 2666 /* 2667 * If we're being asked to return a locked child vnode, then 2668 * we may need to create a replacement vnode in case the 2669 * original is reclaimed while the lock is dropped. In that 2670 * case we'll need to ensure the mount and the underlying 2671 * vnodes aren't also recycled during that window. 2672 */ 2673 if (!ap->a_unlock_vp) { 2674 vhold(vp); 2675 if (uvp != NULLVP) 2676 vhold(uvp); 2677 if (lvp != NULLVP) 2678 vhold(lvp); 2679 mp = vp->v_mount; 2680 vfs_ref(mp); 2681 } 2682 } 2683 2684 /* 2685 * TODO: Because unionfs_lock() locks both the lower and upper vnodes 2686 * (if available), we must also call VOP_VPUT_PAIR() on both the lower 2687 * and upper parent/child pairs. If unionfs_lock() is reworked to lock 2688 * only a single vnode, this code will need to change to also only 2689 * operate on one vnode pair. 2690 */ 2691 ASSERT_VOP_LOCKED(ldvp, __func__); 2692 ASSERT_VOP_LOCKED(udvp, __func__); 2693 ASSERT_VOP_LOCKED(lvp, __func__); 2694 ASSERT_VOP_LOCKED(uvp, __func__); 2695 2696 KASSERT(lvp == NULLVP || ldvp != NULLVP, 2697 ("%s: NULL ldvp with non-NULL lvp", __func__)); 2698 if (ldvp != NULLVP) 2699 res = VOP_VPUT_PAIR(ldvp, lvp != NULLVP ? &lvp : NULL, true); 2700 KASSERT(uvp == NULLVP || udvp != NULLVP, 2701 ("%s: NULL udvp with non-NULL uvp", __func__)); 2702 if (udvp != NULLVP) 2703 res = VOP_VPUT_PAIR(udvp, uvp != NULLVP ? &uvp : NULL, true); 2704 2705 ASSERT_VOP_UNLOCKED(ldvp, __func__); 2706 ASSERT_VOP_UNLOCKED(udvp, __func__); 2707 ASSERT_VOP_UNLOCKED(lvp, __func__); 2708 ASSERT_VOP_UNLOCKED(uvp, __func__); 2709 2710 /* 2711 * VOP_VPUT_PAIR() dropped the references we added to the underlying 2712 * vnodes, now drop the caller's reference to the unionfs vnodes. 2713 */ 2714 if (vp != NULLVP && ap->a_unlock_vp) 2715 vrele(vp); 2716 vrele(dvp); 2717 2718 if (vp == NULLVP || ap->a_unlock_vp) 2719 return (res); 2720 2721 /* 2722 * We're being asked to return a locked vnode. At this point, the 2723 * underlying vnodes have been unlocked, so vp may have been reclaimed. 2724 */ 2725 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2726 if (vp->v_data == NULL && vfs_busy(mp, MBF_NOWAIT) == 0) { 2727 vput(vp); 2728 error = unionfs_nodeget(mp, uvp, lvp, dvp, &tempvp, NULL); 2729 if (error == 0) { 2730 vn_lock(tempvp, LK_EXCLUSIVE | LK_RETRY); 2731 *vpp = tempvp; 2732 } else 2733 vget(vp, LK_EXCLUSIVE | LK_RETRY); 2734 vfs_unbusy(mp); 2735 } 2736 if (lvp != NULLVP) 2737 vdrop(lvp); 2738 if (uvp != NULLVP) 2739 vdrop(uvp); 2740 vdrop(vp); 2741 vfs_rel(mp); 2742 2743 return (res); 2744 } 2745 2746 static int 2747 unionfs_set_text(struct vop_set_text_args *ap) 2748 { 2749 struct vnode *tvp; 2750 struct unionfs_node *unp; 2751 int error; 2752 2753 /* 2754 * We assume text refs are managed against lvp/uvp through the 2755 * executable mapping backed by its VM object. We therefore don't 2756 * need to track leased text refs in the case of a forcible unmount. 2757 */ 2758 unp = VTOUNIONFS(ap->a_vp); 2759 ASSERT_VOP_LOCKED(ap->a_vp, __func__); 2760 tvp = unp->un_uppervp != NULL ? unp->un_uppervp : unp->un_lowervp; 2761 error = VOP_SET_TEXT(tvp); 2762 return (error); 2763 } 2764 2765 static int 2766 unionfs_unset_text(struct vop_unset_text_args *ap) 2767 { 2768 struct vnode *tvp; 2769 struct unionfs_node *unp; 2770 2771 ASSERT_VOP_LOCKED(ap->a_vp, __func__); 2772 unp = VTOUNIONFS(ap->a_vp); 2773 tvp = unp->un_uppervp != NULL ? unp->un_uppervp : unp->un_lowervp; 2774 VOP_UNSET_TEXT_CHECKED(tvp); 2775 return (0); 2776 } 2777 2778 static int 2779 unionfs_unp_bind(struct vop_unp_bind_args *ap) 2780 { 2781 struct vnode *tvp; 2782 struct unionfs_node *unp; 2783 2784 ASSERT_VOP_LOCKED(ap->a_vp, __func__); 2785 unp = VTOUNIONFS(ap->a_vp); 2786 tvp = unp->un_uppervp != NULL ? unp->un_uppervp : unp->un_lowervp; 2787 VOP_UNP_BIND(tvp, ap->a_unpcb); 2788 return (0); 2789 } 2790 2791 static int 2792 unionfs_unp_connect(struct vop_unp_connect_args *ap) 2793 { 2794 struct vnode *tvp; 2795 struct unionfs_node *unp; 2796 2797 ASSERT_VOP_LOCKED(ap->a_vp, __func__); 2798 unp = VTOUNIONFS(ap->a_vp); 2799 tvp = unp->un_uppervp != NULL ? unp->un_uppervp : unp->un_lowervp; 2800 VOP_UNP_CONNECT(tvp, ap->a_unpcb); 2801 return (0); 2802 } 2803 2804 static int 2805 unionfs_unp_detach(struct vop_unp_detach_args *ap) 2806 { 2807 struct vnode *tvp; 2808 struct unionfs_node *unp; 2809 2810 tvp = NULL; 2811 /* 2812 * VOP_UNP_DETACH() is not guaranteed to be called with the unionfs 2813 * vnode locked, so we take the interlock to prevent a concurrent 2814 * unmount from freeing the unionfs private data. 2815 */ 2816 VI_LOCK(ap->a_vp); 2817 unp = VTOUNIONFS(ap->a_vp); 2818 if (unp != NULL) { 2819 tvp = unp->un_uppervp != NULL ? 2820 unp->un_uppervp : unp->un_lowervp; 2821 /* 2822 * Hold the target vnode to prevent a concurrent unionfs 2823 * unmount from causing it to be recycled once the interlock 2824 * is dropped. 2825 */ 2826 vholdnz(tvp); 2827 } 2828 VI_UNLOCK(ap->a_vp); 2829 if (tvp != NULL) { 2830 VOP_UNP_DETACH(tvp); 2831 vdrop(tvp); 2832 } 2833 return (0); 2834 } 2835 2836 struct vop_vector unionfs_vnodeops = { 2837 .vop_default = &default_vnodeops, 2838 2839 .vop_access = unionfs_access, 2840 .vop_aclcheck = unionfs_aclcheck, 2841 .vop_advlock = unionfs_advlock, 2842 .vop_bmap = VOP_EOPNOTSUPP, 2843 .vop_cachedlookup = unionfs_lookup, 2844 .vop_close = unionfs_close, 2845 .vop_closeextattr = unionfs_closeextattr, 2846 .vop_create = unionfs_create, 2847 .vop_deleteextattr = unionfs_deleteextattr, 2848 .vop_fsync = unionfs_fsync, 2849 .vop_getacl = unionfs_getacl, 2850 .vop_getattr = unionfs_getattr, 2851 .vop_getextattr = unionfs_getextattr, 2852 .vop_getwritemount = unionfs_getwritemount, 2853 .vop_inactive = unionfs_inactive, 2854 .vop_need_inactive = vop_stdneed_inactive, 2855 .vop_islocked = vop_stdislocked, 2856 .vop_ioctl = unionfs_ioctl, 2857 .vop_link = unionfs_link, 2858 .vop_listextattr = unionfs_listextattr, 2859 .vop_lock1 = unionfs_lock, 2860 .vop_lookup = vfs_cache_lookup, 2861 .vop_mkdir = unionfs_mkdir, 2862 .vop_mknod = unionfs_mknod, 2863 .vop_open = unionfs_open, 2864 .vop_openextattr = unionfs_openextattr, 2865 .vop_pathconf = unionfs_pathconf, 2866 .vop_poll = unionfs_poll, 2867 .vop_print = unionfs_print, 2868 .vop_read = unionfs_read, 2869 .vop_readdir = unionfs_readdir, 2870 .vop_readlink = unionfs_readlink, 2871 .vop_reclaim = unionfs_reclaim, 2872 .vop_remove = unionfs_remove, 2873 .vop_rename = unionfs_rename, 2874 .vop_rmdir = unionfs_rmdir, 2875 .vop_setacl = unionfs_setacl, 2876 .vop_setattr = unionfs_setattr, 2877 .vop_setextattr = unionfs_setextattr, 2878 .vop_setlabel = unionfs_setlabel, 2879 .vop_strategy = unionfs_strategy, 2880 .vop_symlink = unionfs_symlink, 2881 .vop_unlock = unionfs_unlock, 2882 .vop_whiteout = unionfs_whiteout, 2883 .vop_write = unionfs_write, 2884 .vop_vptofh = unionfs_vptofh, 2885 .vop_add_writecount = unionfs_add_writecount, 2886 .vop_vput_pair = unionfs_vput_pair, 2887 .vop_set_text = unionfs_set_text, 2888 .vop_unset_text = unionfs_unset_text, 2889 .vop_unp_bind = unionfs_unp_bind, 2890 .vop_unp_connect = unionfs_unp_connect, 2891 .vop_unp_detach = unionfs_unp_detach, 2892 }; 2893 VFS_VOP_VECTOR_REGISTER(unionfs_vnodeops); 2894