1 /* 2 * Copyright (c) 1994 Jan-Simon Pendry 3 * Copyright (c) 1994 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Jan-Simon Pendry. 8 * 9 * %sccs.include.redist.c% 10 * 11 * @(#)union_subr.c 8.17 (Berkeley) 03/11/95 12 */ 13 14 #include <sys/param.h> 15 #include <sys/systm.h> 16 #include <sys/time.h> 17 #include <sys/kernel.h> 18 #include <sys/vnode.h> 19 #include <sys/namei.h> 20 #include <sys/malloc.h> 21 #include <sys/file.h> 22 #include <sys/filedesc.h> 23 #include <sys/queue.h> 24 #include <sys/mount.h> 25 #include <sys/stat.h> 26 #include <vm/vm.h> /* for vnode_pager_setsize */ 27 #include <miscfs/union/union.h> 28 29 #ifdef DIAGNOSTIC 30 #include <sys/proc.h> 31 #endif 32 33 /* must be power of two, otherwise change UNION_HASH() */ 34 #define NHASH 32 35 36 /* unsigned int ... */ 37 #define UNION_HASH(u, l) \ 38 (((((unsigned long) (u)) + ((unsigned long) l)) >> 8) & (NHASH-1)) 39 40 static LIST_HEAD(unhead, union_node) unhead[NHASH]; 41 static int unvplock[NHASH]; 42 43 int 44 union_init() 45 { 46 int i; 47 48 for (i = 0; i < NHASH; i++) 49 LIST_INIT(&unhead[i]); 50 bzero((caddr_t) unvplock, sizeof(unvplock)); 51 } 52 53 static int 54 union_list_lock(ix) 55 int ix; 56 { 57 58 if (unvplock[ix] & UN_LOCKED) { 59 unvplock[ix] |= UN_WANT; 60 sleep((caddr_t) &unvplock[ix], PINOD); 61 return (1); 62 } 63 64 unvplock[ix] |= UN_LOCKED; 65 66 return (0); 67 } 68 69 static void 70 union_list_unlock(ix) 71 int ix; 72 { 73 74 unvplock[ix] &= ~UN_LOCKED; 75 76 if (unvplock[ix] & UN_WANT) { 77 unvplock[ix] &= ~UN_WANT; 78 wakeup((caddr_t) &unvplock[ix]); 79 } 80 } 81 82 void 83 union_updatevp(un, uppervp, lowervp) 84 struct union_node *un; 85 struct vnode *uppervp; 86 struct vnode *lowervp; 87 { 88 int ohash = UNION_HASH(un->un_uppervp, un->un_lowervp); 89 int nhash = UNION_HASH(uppervp, lowervp); 90 int docache = (lowervp != NULLVP || uppervp != NULLVP); 91 92 /* 93 * Ensure locking is ordered from lower to higher 94 * to avoid deadlocks. 95 */ 96 if (nhash < ohash) { 97 int t = ohash; 98 ohash = nhash; 99 nhash = t; 100 } 101 102 if (ohash != nhash) 103 while (union_list_lock(ohash)) 104 continue; 105 106 while (union_list_lock(nhash)) 107 continue; 108 109 if (ohash != nhash || !docache) { 110 if (un->un_flags & UN_CACHED) { 111 un->un_flags &= ~UN_CACHED; 112 LIST_REMOVE(un, un_cache); 113 } 114 } 115 116 if (ohash != nhash) 117 union_list_unlock(ohash); 118 119 if (un->un_lowervp != lowervp) { 120 if (un->un_lowervp) { 121 vrele(un->un_lowervp); 122 if (un->un_path) { 123 free(un->un_path, M_TEMP); 124 un->un_path = 0; 125 } 126 if (un->un_dirvp) { 127 vrele(un->un_dirvp); 128 un->un_dirvp = NULLVP; 129 } 130 } 131 un->un_lowervp = lowervp; 132 un->un_lowersz = VNOVAL; 133 } 134 135 if (un->un_uppervp != uppervp) { 136 if (un->un_uppervp) 137 vrele(un->un_uppervp); 138 139 un->un_uppervp = uppervp; 140 un->un_uppersz = VNOVAL; 141 } 142 143 if (docache && (ohash != nhash)) { 144 LIST_INSERT_HEAD(&unhead[nhash], un, un_cache); 145 un->un_flags |= UN_CACHED; 146 } 147 148 union_list_unlock(nhash); 149 } 150 151 void 152 union_newlower(un, lowervp) 153 struct union_node *un; 154 struct vnode *lowervp; 155 { 156 157 union_updatevp(un, un->un_uppervp, lowervp); 158 } 159 160 void 161 union_newupper(un, uppervp) 162 struct union_node *un; 163 struct vnode *uppervp; 164 { 165 166 union_updatevp(un, uppervp, un->un_lowervp); 167 } 168 169 /* 170 * Keep track of size changes in the underlying vnodes. 171 * If the size changes, then callback to the vm layer 172 * giving priority to the upper layer size. 173 */ 174 void 175 union_newsize(vp, uppersz, lowersz) 176 struct vnode *vp; 177 off_t uppersz, lowersz; 178 { 179 struct union_node *un; 180 off_t sz; 181 182 /* only interested in regular files */ 183 if (vp->v_type != VREG) 184 return; 185 186 un = VTOUNION(vp); 187 sz = VNOVAL; 188 189 if ((uppersz != VNOVAL) && (un->un_uppersz != uppersz)) { 190 un->un_uppersz = uppersz; 191 if (sz == VNOVAL) 192 sz = un->un_uppersz; 193 } 194 195 if ((lowersz != VNOVAL) && (un->un_lowersz != lowersz)) { 196 un->un_lowersz = lowersz; 197 if (sz == VNOVAL) 198 sz = un->un_lowersz; 199 } 200 201 if (sz != VNOVAL) { 202 #ifdef UNION_DIAGNOSTIC 203 printf("union: %s size now %ld\n", 204 uppersz != VNOVAL ? "upper" : "lower", (long) sz); 205 #endif 206 vnode_pager_setsize(vp, sz); 207 } 208 } 209 210 /* 211 * allocate a union_node/vnode pair. the vnode is 212 * referenced and locked. the new vnode is returned 213 * via (vpp). (mp) is the mountpoint of the union filesystem, 214 * (dvp) is the parent directory where the upper layer object 215 * should exist (but doesn't) and (cnp) is the componentname 216 * information which is partially copied to allow the upper 217 * layer object to be created at a later time. (uppervp) 218 * and (lowervp) reference the upper and lower layer objects 219 * being mapped. either, but not both, can be nil. 220 * if supplied, (uppervp) is locked. 221 * the reference is either maintained in the new union_node 222 * object which is allocated, or they are vrele'd. 223 * 224 * all union_nodes are maintained on a singly-linked 225 * list. new nodes are only allocated when they cannot 226 * be found on this list. entries on the list are 227 * removed when the vfs reclaim entry is called. 228 * 229 * a single lock is kept for the entire list. this is 230 * needed because the getnewvnode() function can block 231 * waiting for a vnode to become free, in which case there 232 * may be more than one process trying to get the same 233 * vnode. this lock is only taken if we are going to 234 * call getnewvnode, since the kernel itself is single-threaded. 235 * 236 * if an entry is found on the list, then call vget() to 237 * take a reference. this is done because there may be 238 * zero references to it and so it needs to removed from 239 * the vnode free list. 240 */ 241 int 242 union_allocvp(vpp, mp, undvp, dvp, cnp, uppervp, lowervp, docache) 243 struct vnode **vpp; 244 struct mount *mp; 245 struct vnode *undvp; /* parent union vnode */ 246 struct vnode *dvp; /* may be null */ 247 struct componentname *cnp; /* may be null */ 248 struct vnode *uppervp; /* may be null */ 249 struct vnode *lowervp; /* may be null */ 250 int docache; 251 { 252 int error; 253 struct union_node *un; 254 struct union_node **pp; 255 struct vnode *xlowervp = NULLVP; 256 struct union_mount *um = MOUNTTOUNIONMOUNT(mp); 257 int hash; 258 int vflag; 259 int try; 260 261 if (uppervp == NULLVP && lowervp == NULLVP) 262 panic("union: unidentifiable allocation"); 263 264 if (uppervp && lowervp && (uppervp->v_type != lowervp->v_type)) { 265 xlowervp = lowervp; 266 lowervp = NULLVP; 267 } 268 269 /* detect the root vnode (and aliases) */ 270 vflag = 0; 271 if ((uppervp == um->um_uppervp) && 272 ((lowervp == NULLVP) || lowervp == um->um_lowervp)) { 273 if (lowervp == NULLVP) { 274 lowervp = um->um_lowervp; 275 if (lowervp != NULLVP) 276 VREF(lowervp); 277 } 278 vflag = VROOT; 279 } 280 281 loop: 282 if (!docache) { 283 un = 0; 284 } else for (try = 0; try < 3; try++) { 285 switch (try) { 286 case 0: 287 if (lowervp == NULLVP) 288 continue; 289 hash = UNION_HASH(uppervp, lowervp); 290 break; 291 292 case 1: 293 if (uppervp == NULLVP) 294 continue; 295 hash = UNION_HASH(uppervp, NULLVP); 296 break; 297 298 case 2: 299 if (lowervp == NULLVP) 300 continue; 301 hash = UNION_HASH(NULLVP, lowervp); 302 break; 303 } 304 305 while (union_list_lock(hash)) 306 continue; 307 308 for (un = unhead[hash].lh_first; un != 0; 309 un = un->un_cache.le_next) { 310 if ((un->un_lowervp == lowervp || 311 un->un_lowervp == NULLVP) && 312 (un->un_uppervp == uppervp || 313 un->un_uppervp == NULLVP) && 314 (UNIONTOV(un)->v_mount == mp)) { 315 if (vget(UNIONTOV(un), 0)) { 316 union_list_unlock(hash); 317 goto loop; 318 } 319 break; 320 } 321 } 322 323 union_list_unlock(hash); 324 325 if (un) 326 break; 327 } 328 329 if (un) { 330 /* 331 * Obtain a lock on the union_node. 332 * uppervp is locked, though un->un_uppervp 333 * may not be. this doesn't break the locking 334 * hierarchy since in the case that un->un_uppervp 335 * is not yet locked it will be vrele'd and replaced 336 * with uppervp. 337 */ 338 339 if ((dvp != NULLVP) && (uppervp == dvp)) { 340 /* 341 * Access ``.'', so (un) will already 342 * be locked. Since this process has 343 * the lock on (uppervp) no other 344 * process can hold the lock on (un). 345 */ 346 #ifdef DIAGNOSTIC 347 if ((un->un_flags & UN_LOCKED) == 0) 348 panic("union: . not locked"); 349 else if (curproc && un->un_pid != curproc->p_pid && 350 un->un_pid > -1 && curproc->p_pid > -1) 351 panic("union: allocvp not lock owner"); 352 #endif 353 } else { 354 if (un->un_flags & UN_LOCKED) { 355 vrele(UNIONTOV(un)); 356 un->un_flags |= UN_WANT; 357 sleep((caddr_t) &un->un_flags, PINOD); 358 goto loop; 359 } 360 un->un_flags |= UN_LOCKED; 361 362 #ifdef DIAGNOSTIC 363 if (curproc) 364 un->un_pid = curproc->p_pid; 365 else 366 un->un_pid = -1; 367 #endif 368 } 369 370 /* 371 * At this point, the union_node is locked, 372 * un->un_uppervp may not be locked, and uppervp 373 * is locked or nil. 374 */ 375 376 /* 377 * Save information about the upper layer. 378 */ 379 if (uppervp != un->un_uppervp) { 380 union_newupper(un, uppervp); 381 } else if (uppervp) { 382 vrele(uppervp); 383 } 384 385 if (un->un_uppervp) { 386 un->un_flags |= UN_ULOCK; 387 un->un_flags &= ~UN_KLOCK; 388 } 389 390 /* 391 * Save information about the lower layer. 392 * This needs to keep track of pathname 393 * and directory information which union_vn_create 394 * might need. 395 */ 396 if (lowervp != un->un_lowervp) { 397 union_newlower(un, lowervp); 398 if (cnp && (lowervp != NULLVP)) { 399 un->un_hash = cnp->cn_hash; 400 un->un_path = malloc(cnp->cn_namelen+1, 401 M_TEMP, M_WAITOK); 402 bcopy(cnp->cn_nameptr, un->un_path, 403 cnp->cn_namelen); 404 un->un_path[cnp->cn_namelen] = '\0'; 405 VREF(dvp); 406 un->un_dirvp = dvp; 407 } 408 } else if (lowervp) { 409 vrele(lowervp); 410 } 411 *vpp = UNIONTOV(un); 412 return (0); 413 } 414 415 if (docache) { 416 /* 417 * otherwise lock the vp list while we call getnewvnode 418 * since that can block. 419 */ 420 hash = UNION_HASH(uppervp, lowervp); 421 422 if (union_list_lock(hash)) 423 goto loop; 424 } 425 426 error = getnewvnode(VT_UNION, mp, union_vnodeop_p, vpp); 427 if (error) { 428 if (uppervp) { 429 if (dvp == uppervp) 430 vrele(uppervp); 431 else 432 vput(uppervp); 433 } 434 if (lowervp) 435 vrele(lowervp); 436 437 goto out; 438 } 439 440 MALLOC((*vpp)->v_data, void *, sizeof(struct union_node), 441 M_TEMP, M_WAITOK); 442 443 (*vpp)->v_flag |= vflag; 444 if (uppervp) 445 (*vpp)->v_type = uppervp->v_type; 446 else 447 (*vpp)->v_type = lowervp->v_type; 448 un = VTOUNION(*vpp); 449 un->un_vnode = *vpp; 450 un->un_uppervp = uppervp; 451 un->un_uppersz = VNOVAL; 452 un->un_lowervp = lowervp; 453 un->un_lowersz = VNOVAL; 454 un->un_pvp = undvp; 455 if (undvp != NULLVP) 456 VREF(undvp); 457 un->un_dircache = 0; 458 un->un_openl = 0; 459 un->un_flags = UN_LOCKED; 460 if (un->un_uppervp) 461 un->un_flags |= UN_ULOCK; 462 #ifdef DIAGNOSTIC 463 if (curproc) 464 un->un_pid = curproc->p_pid; 465 else 466 un->un_pid = -1; 467 #endif 468 if (cnp && (lowervp != NULLVP)) { 469 un->un_hash = cnp->cn_hash; 470 un->un_path = malloc(cnp->cn_namelen+1, M_TEMP, M_WAITOK); 471 bcopy(cnp->cn_nameptr, un->un_path, cnp->cn_namelen); 472 un->un_path[cnp->cn_namelen] = '\0'; 473 VREF(dvp); 474 un->un_dirvp = dvp; 475 } else { 476 un->un_hash = 0; 477 un->un_path = 0; 478 un->un_dirvp = 0; 479 } 480 481 if (docache) { 482 LIST_INSERT_HEAD(&unhead[hash], un, un_cache); 483 un->un_flags |= UN_CACHED; 484 } 485 486 if (xlowervp) 487 vrele(xlowervp); 488 489 out: 490 if (docache) 491 union_list_unlock(hash); 492 493 return (error); 494 } 495 496 int 497 union_freevp(vp) 498 struct vnode *vp; 499 { 500 struct union_node *un = VTOUNION(vp); 501 502 if (un->un_flags & UN_CACHED) { 503 un->un_flags &= ~UN_CACHED; 504 LIST_REMOVE(un, un_cache); 505 } 506 507 if (un->un_pvp != NULLVP) 508 vrele(un->un_pvp); 509 if (un->un_uppervp != NULLVP) 510 vrele(un->un_uppervp); 511 if (un->un_lowervp != NULLVP) 512 vrele(un->un_lowervp); 513 if (un->un_dirvp != NULLVP) 514 vrele(un->un_dirvp); 515 if (un->un_path) 516 free(un->un_path, M_TEMP); 517 518 FREE(vp->v_data, M_TEMP); 519 vp->v_data = 0; 520 521 return (0); 522 } 523 524 /* 525 * copyfile. copy the vnode (fvp) to the vnode (tvp) 526 * using a sequence of reads and writes. both (fvp) 527 * and (tvp) are locked on entry and exit. 528 */ 529 int 530 union_copyfile(fvp, tvp, cred, p) 531 struct vnode *fvp; 532 struct vnode *tvp; 533 struct ucred *cred; 534 struct proc *p; 535 { 536 char *buf; 537 struct uio uio; 538 struct iovec iov; 539 int error = 0; 540 541 /* 542 * strategy: 543 * allocate a buffer of size MAXBSIZE. 544 * loop doing reads and writes, keeping track 545 * of the current uio offset. 546 * give up at the first sign of trouble. 547 */ 548 549 uio.uio_procp = p; 550 uio.uio_segflg = UIO_SYSSPACE; 551 uio.uio_offset = 0; 552 553 VOP_UNLOCK(fvp); /* XXX */ 554 VOP_LEASE(fvp, p, cred, LEASE_READ); 555 VOP_LOCK(fvp); /* XXX */ 556 VOP_UNLOCK(tvp); /* XXX */ 557 VOP_LEASE(tvp, p, cred, LEASE_WRITE); 558 VOP_LOCK(tvp); /* XXX */ 559 560 buf = malloc(MAXBSIZE, M_TEMP, M_WAITOK); 561 562 /* ugly loop follows... */ 563 do { 564 off_t offset = uio.uio_offset; 565 566 uio.uio_iov = &iov; 567 uio.uio_iovcnt = 1; 568 iov.iov_base = buf; 569 iov.iov_len = MAXBSIZE; 570 uio.uio_resid = iov.iov_len; 571 uio.uio_rw = UIO_READ; 572 error = VOP_READ(fvp, &uio, 0, cred); 573 574 if (error == 0) { 575 uio.uio_iov = &iov; 576 uio.uio_iovcnt = 1; 577 iov.iov_base = buf; 578 iov.iov_len = MAXBSIZE - uio.uio_resid; 579 uio.uio_offset = offset; 580 uio.uio_rw = UIO_WRITE; 581 uio.uio_resid = iov.iov_len; 582 583 if (uio.uio_resid == 0) 584 break; 585 586 do { 587 error = VOP_WRITE(tvp, &uio, 0, cred); 588 } while ((uio.uio_resid > 0) && (error == 0)); 589 } 590 591 } while (error == 0); 592 593 free(buf, M_TEMP); 594 return (error); 595 } 596 597 /* 598 * (un) is assumed to be locked on entry and remains 599 * locked on exit. 600 */ 601 int 602 union_copyup(un, docopy, cred, p) 603 struct union_node *un; 604 int docopy; 605 struct ucred *cred; 606 struct proc *p; 607 { 608 int error; 609 struct vnode *lvp, *uvp; 610 611 error = union_vn_create(&uvp, un, p); 612 if (error) 613 return (error); 614 615 /* at this point, uppervp is locked */ 616 union_newupper(un, uvp); 617 un->un_flags |= UN_ULOCK; 618 619 lvp = un->un_lowervp; 620 621 if (docopy) { 622 /* 623 * XX - should not ignore errors 624 * from VOP_CLOSE 625 */ 626 VOP_LOCK(lvp); 627 error = VOP_OPEN(lvp, FREAD, cred, p); 628 if (error == 0) { 629 error = union_copyfile(lvp, uvp, cred, p); 630 VOP_UNLOCK(lvp); 631 (void) VOP_CLOSE(lvp, FREAD, cred, p); 632 } 633 #ifdef UNION_DIAGNOSTIC 634 if (error == 0) 635 uprintf("union: copied up %s\n", un->un_path); 636 #endif 637 638 } 639 un->un_flags &= ~UN_ULOCK; 640 VOP_UNLOCK(uvp); 641 union_vn_close(uvp, FWRITE, cred, p); 642 VOP_LOCK(uvp); 643 un->un_flags |= UN_ULOCK; 644 645 /* 646 * Subsequent IOs will go to the top layer, so 647 * call close on the lower vnode and open on the 648 * upper vnode to ensure that the filesystem keeps 649 * its references counts right. This doesn't do 650 * the right thing with (cred) and (FREAD) though. 651 * Ignoring error returns is not right, either. 652 */ 653 if (error == 0) { 654 int i; 655 656 for (i = 0; i < un->un_openl; i++) { 657 (void) VOP_CLOSE(lvp, FREAD, cred, p); 658 (void) VOP_OPEN(uvp, FREAD, cred, p); 659 } 660 un->un_openl = 0; 661 } 662 663 return (error); 664 665 } 666 667 static int 668 union_relookup(um, dvp, vpp, cnp, cn, path, pathlen) 669 struct union_mount *um; 670 struct vnode *dvp; 671 struct vnode **vpp; 672 struct componentname *cnp; 673 struct componentname *cn; 674 char *path; 675 int pathlen; 676 { 677 int error; 678 679 /* 680 * A new componentname structure must be faked up because 681 * there is no way to know where the upper level cnp came 682 * from or what it is being used for. This must duplicate 683 * some of the work done by NDINIT, some of the work done 684 * by namei, some of the work done by lookup and some of 685 * the work done by VOP_LOOKUP when given a CREATE flag. 686 * Conclusion: Horrible. 687 * 688 * The pathname buffer will be FREEed by VOP_MKDIR. 689 */ 690 cn->cn_namelen = pathlen; 691 cn->cn_pnbuf = malloc(cn->cn_namelen+1, M_NAMEI, M_WAITOK); 692 bcopy(path, cn->cn_pnbuf, cn->cn_namelen); 693 cn->cn_pnbuf[cn->cn_namelen] = '\0'; 694 695 cn->cn_nameiop = CREATE; 696 cn->cn_flags = (LOCKPARENT|HASBUF|SAVENAME|SAVESTART|ISLASTCN); 697 cn->cn_proc = cnp->cn_proc; 698 if (um->um_op == UNMNT_ABOVE) 699 cn->cn_cred = cnp->cn_cred; 700 else 701 cn->cn_cred = um->um_cred; 702 cn->cn_nameptr = cn->cn_pnbuf; 703 cn->cn_hash = cnp->cn_hash; 704 cn->cn_consume = cnp->cn_consume; 705 706 VREF(dvp); 707 error = relookup(dvp, vpp, cn); 708 if (!error) 709 vrele(dvp); 710 711 return (error); 712 } 713 714 /* 715 * Create a shadow directory in the upper layer. 716 * The new vnode is returned locked. 717 * 718 * (um) points to the union mount structure for access to the 719 * the mounting process's credentials. 720 * (dvp) is the directory in which to create the shadow directory. 721 * it is unlocked on entry and exit. 722 * (cnp) is the componentname to be created. 723 * (vpp) is the returned newly created shadow directory, which 724 * is returned locked. 725 */ 726 int 727 union_mkshadow(um, dvp, cnp, vpp) 728 struct union_mount *um; 729 struct vnode *dvp; 730 struct componentname *cnp; 731 struct vnode **vpp; 732 { 733 int error; 734 struct vattr va; 735 struct proc *p = cnp->cn_proc; 736 struct componentname cn; 737 738 error = union_relookup(um, dvp, vpp, cnp, &cn, 739 cnp->cn_nameptr, cnp->cn_namelen); 740 if (error) 741 return (error); 742 743 if (*vpp) { 744 VOP_ABORTOP(dvp, &cn); 745 VOP_UNLOCK(dvp); 746 vrele(*vpp); 747 *vpp = NULLVP; 748 return (EEXIST); 749 } 750 751 /* 752 * policy: when creating the shadow directory in the 753 * upper layer, create it owned by the user who did 754 * the mount, group from parent directory, and mode 755 * 777 modified by umask (ie mostly identical to the 756 * mkdir syscall). (jsp, kb) 757 */ 758 759 VATTR_NULL(&va); 760 va.va_type = VDIR; 761 va.va_mode = um->um_cmode; 762 763 /* VOP_LEASE: dvp is locked */ 764 VOP_LEASE(dvp, p, cn.cn_cred, LEASE_WRITE); 765 766 error = VOP_MKDIR(dvp, vpp, &cn, &va); 767 return (error); 768 } 769 770 /* 771 * Create a whiteout entry in the upper layer. 772 * 773 * (um) points to the union mount structure for access to the 774 * the mounting process's credentials. 775 * (dvp) is the directory in which to create the whiteout. 776 * it is locked on entry and exit. 777 * (cnp) is the componentname to be created. 778 */ 779 int 780 union_mkwhiteout(um, dvp, cnp, path) 781 struct union_mount *um; 782 struct vnode *dvp; 783 struct componentname *cnp; 784 char *path; 785 { 786 int error; 787 struct vattr va; 788 struct proc *p = cnp->cn_proc; 789 struct vnode *wvp; 790 struct componentname cn; 791 792 VOP_UNLOCK(dvp); 793 error = union_relookup(um, dvp, &wvp, cnp, &cn, path, strlen(path)); 794 if (error) { 795 VOP_LOCK(dvp); 796 return (error); 797 } 798 799 if (wvp) { 800 VOP_ABORTOP(dvp, &cn); 801 vrele(dvp); 802 vrele(wvp); 803 return (EEXIST); 804 } 805 806 /* VOP_LEASE: dvp is locked */ 807 VOP_LEASE(dvp, p, p->p_ucred, LEASE_WRITE); 808 809 error = VOP_WHITEOUT(dvp, &cn, CREATE); 810 if (error) 811 VOP_ABORTOP(dvp, &cn); 812 813 vrele(dvp); 814 815 return (error); 816 } 817 818 /* 819 * union_vn_create: creates and opens a new shadow file 820 * on the upper union layer. this function is similar 821 * in spirit to calling vn_open but it avoids calling namei(). 822 * the problem with calling namei is that a) it locks too many 823 * things, and b) it doesn't start at the "right" directory, 824 * whereas relookup is told where to start. 825 */ 826 int 827 union_vn_create(vpp, un, p) 828 struct vnode **vpp; 829 struct union_node *un; 830 struct proc *p; 831 { 832 struct vnode *vp; 833 struct ucred *cred = p->p_ucred; 834 struct vattr vat; 835 struct vattr *vap = &vat; 836 int fmode = FFLAGS(O_WRONLY|O_CREAT|O_TRUNC|O_EXCL); 837 int error; 838 int cmode = UN_FILEMODE & ~p->p_fd->fd_cmask; 839 char *cp; 840 struct componentname cn; 841 842 *vpp = NULLVP; 843 844 /* 845 * Build a new componentname structure (for the same 846 * reasons outlines in union_mkshadow). 847 * The difference here is that the file is owned by 848 * the current user, rather than by the person who 849 * did the mount, since the current user needs to be 850 * able to write the file (that's why it is being 851 * copied in the first place). 852 */ 853 cn.cn_namelen = strlen(un->un_path); 854 cn.cn_pnbuf = (caddr_t) malloc(cn.cn_namelen, M_NAMEI, M_WAITOK); 855 bcopy(un->un_path, cn.cn_pnbuf, cn.cn_namelen+1); 856 cn.cn_nameiop = CREATE; 857 cn.cn_flags = (LOCKPARENT|HASBUF|SAVENAME|SAVESTART|ISLASTCN); 858 cn.cn_proc = p; 859 cn.cn_cred = p->p_ucred; 860 cn.cn_nameptr = cn.cn_pnbuf; 861 cn.cn_hash = un->un_hash; 862 cn.cn_consume = 0; 863 864 VREF(un->un_dirvp); 865 if (error = relookup(un->un_dirvp, &vp, &cn)) 866 return (error); 867 vrele(un->un_dirvp); 868 869 if (vp) { 870 VOP_ABORTOP(un->un_dirvp, &cn); 871 if (un->un_dirvp == vp) 872 vrele(un->un_dirvp); 873 else 874 vput(un->un_dirvp); 875 vrele(vp); 876 return (EEXIST); 877 } 878 879 /* 880 * Good - there was no race to create the file 881 * so go ahead and create it. The permissions 882 * on the file will be 0666 modified by the 883 * current user's umask. Access to the file, while 884 * it is unioned, will require access to the top *and* 885 * bottom files. Access when not unioned will simply 886 * require access to the top-level file. 887 * TODO: confirm choice of access permissions. 888 */ 889 VATTR_NULL(vap); 890 vap->va_type = VREG; 891 vap->va_mode = cmode; 892 VOP_LEASE(un->un_dirvp, p, cred, LEASE_WRITE); 893 if (error = VOP_CREATE(un->un_dirvp, &vp, &cn, vap)) 894 return (error); 895 896 if (error = VOP_OPEN(vp, fmode, cred, p)) { 897 vput(vp); 898 return (error); 899 } 900 901 vp->v_writecount++; 902 *vpp = vp; 903 return (0); 904 } 905 906 int 907 union_vn_close(vp, fmode, cred, p) 908 struct vnode *vp; 909 int fmode; 910 struct ucred *cred; 911 struct proc *p; 912 { 913 914 if (fmode & FWRITE) 915 --vp->v_writecount; 916 return (VOP_CLOSE(vp, fmode, cred, p)); 917 } 918 919 void 920 union_removed_upper(un) 921 struct union_node *un; 922 { 923 924 if (un->un_flags & UN_ULOCK) { 925 un->un_flags &= ~UN_ULOCK; 926 VOP_UNLOCK(un->un_uppervp); 927 } 928 929 if (un->un_flags & UN_CACHED) { 930 un->un_flags &= ~UN_CACHED; 931 LIST_REMOVE(un, un_cache); 932 } 933 } 934 935 #if 0 936 struct vnode * 937 union_lowervp(vp) 938 struct vnode *vp; 939 { 940 struct union_node *un = VTOUNION(vp); 941 942 if ((un->un_lowervp != NULLVP) && 943 (vp->v_type == un->un_lowervp->v_type)) { 944 if (vget(un->un_lowervp, 0) == 0) 945 return (un->un_lowervp); 946 } 947 948 return (NULLVP); 949 } 950 #endif 951 952 /* 953 * determine whether a whiteout is needed 954 * during a remove/rmdir operation. 955 */ 956 int 957 union_dowhiteout(un, cred, p) 958 struct union_node *un; 959 struct ucred *cred; 960 struct proc *p; 961 { 962 struct vattr va; 963 964 if (un->un_lowervp != NULLVP) 965 return (1); 966 967 if (VOP_GETATTR(un->un_uppervp, &va, cred, p) == 0 && 968 (va.va_flags & OPAQUE)) 969 return (1); 970 971 return (0); 972 } 973 974 static void 975 union_dircache_r(vp, vppp, cntp) 976 struct vnode *vp; 977 struct vnode ***vppp; 978 int *cntp; 979 { 980 struct union_node *un; 981 982 if (vp->v_op != union_vnodeop_p) { 983 if (vppp) { 984 VREF(vp); 985 *(*vppp)++ = vp; 986 if (--(*cntp) == 0) 987 panic("union: dircache table too small"); 988 } else { 989 (*cntp)++; 990 } 991 992 return; 993 } 994 995 un = VTOUNION(vp); 996 if (un->un_uppervp != NULLVP) 997 union_dircache_r(un->un_uppervp, vppp, cntp); 998 if (un->un_lowervp != NULLVP) 999 union_dircache_r(un->un_lowervp, vppp, cntp); 1000 } 1001 1002 struct vnode * 1003 union_dircache(vp) 1004 struct vnode *vp; 1005 { 1006 int cnt; 1007 struct vnode *nvp; 1008 struct vnode **vpp; 1009 struct vnode **dircache = VTOUNION(vp)->un_dircache; 1010 struct union_node *un; 1011 int error; 1012 1013 if (dircache == 0) { 1014 cnt = 0; 1015 union_dircache_r(vp, 0, &cnt); 1016 cnt++; 1017 dircache = (struct vnode **) 1018 malloc(cnt * sizeof(struct vnode *), 1019 M_TEMP, M_WAITOK); 1020 vpp = dircache; 1021 union_dircache_r(vp, &vpp, &cnt); 1022 *vpp = NULLVP; 1023 vpp = dircache + 1; 1024 } else { 1025 vpp = dircache; 1026 do { 1027 if (*vpp++ == VTOUNION(vp)->un_uppervp) 1028 break; 1029 } while (*vpp != NULLVP); 1030 } 1031 1032 if (*vpp == NULLVP) 1033 return (NULLVP); 1034 1035 VOP_LOCK(*vpp); 1036 VREF(*vpp); 1037 error = union_allocvp(&nvp, vp->v_mount, NULLVP, NULLVP, 0, *vpp, NULLVP, 0); 1038 if (error) 1039 return (NULLVP); 1040 VTOUNION(vp)->un_dircache = 0; 1041 un = VTOUNION(nvp); 1042 un->un_dircache = dircache; 1043 1044 return (nvp); 1045 } 1046