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