|
Lines 275-280
Link Here
|
| 275 |
return (0); |
275 |
return (0); |
| 276 |
} |
276 |
} |
| 277 |
|
277 |
|
|
|
278 |
#define NOOPEN_LOWER 0 |
| 279 |
|
| 278 |
static int |
280 |
static int |
| 279 |
union_lookup(ap) |
281 |
union_lookup(ap) |
| 280 |
struct vop_lookup_args /* { |
282 |
struct vop_lookup_args /* { |
|
Lines 300-305
Link Here
|
| 300 |
|
302 |
|
| 301 |
*ap->a_vpp = NULLVP; |
303 |
*ap->a_vpp = NULLVP; |
| 302 |
|
304 |
|
|
|
305 |
/*if ((cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) { |
| 306 |
printf("lookup: [%.*s] for %d\ncnp->cn_consume = %d\n",cnp->cn_namelen,cnp->cn_nameptr,cnp->cn_nameiop,cnp->cn_consume); |
| 307 |
}*/ |
| 303 |
/* |
308 |
/* |
| 304 |
* Disallow write attemps to the filesystem mounted read-only. |
309 |
* Disallow write attemps to the filesystem mounted read-only. |
| 305 |
*/ |
310 |
*/ |
|
Lines 367-373
Link Here
|
| 367 |
(uppervp ? uppervp->v_usecount : -99), |
372 |
(uppervp ? uppervp->v_usecount : -99), |
| 368 |
(uppervp ? VOP_ISLOCKED(uppervp, NULL) : -99) |
373 |
(uppervp ? VOP_ISLOCKED(uppervp, NULL) : -99) |
| 369 |
)); |
374 |
)); |
| 370 |
|
375 |
/* |
|
|
376 |
if(uerror == EACCES) { |
| 377 |
error = uerror; |
| 378 |
goto out; |
| 379 |
} |
| 380 |
*/ |
| 371 |
/* |
381 |
/* |
| 372 |
* Disallow write attemps to the filesystem mounted read-only. |
382 |
* Disallow write attemps to the filesystem mounted read-only. |
| 373 |
*/ |
383 |
*/ |
|
Lines 538-546
Link Here
|
| 538 |
VOP_UNLOCK(lowervp, 0, p); |
548 |
VOP_UNLOCK(lowervp, 0, p); |
| 539 |
if (upperdvp) |
549 |
if (upperdvp) |
| 540 |
VOP_UNLOCK(upperdvp, 0, p); |
550 |
VOP_UNLOCK(upperdvp, 0, p); |
| 541 |
|
551 |
/* |
| 542 |
error = union_allocvp(ap->a_vpp, dvp->v_mount, dvp, upperdvp, cnp, |
552 |
printf("lookup_end: [%.*s] for %d\n",cnp->cn_namelen,cnp->cn_nameptr,cnp->cn_nameiop); |
| 543 |
uppervp, lowervp, 1); |
553 |
*/ |
|
|
554 |
{ |
| 555 |
struct vnode *tmp; |
| 556 |
tmp = (uppervp != NULL) ? uppervp : lowervp; |
| 557 |
/* |
| 558 |
printf("vnode = %p\ncnp->cn_nameiop = %d, cnp->cn_name = %.*s, type = %d\nv_usecount = %d\n", |
| 559 |
tmp, |
| 560 |
cnp->cn_nameiop, cnp->cn_namelen, cnp->cn_nameptr, tmp->v_type, |
| 561 |
tmp->v_usecount); |
| 562 |
*/ |
| 563 |
if( (cnp->cn_nameiop == LOOKUP && |
| 564 |
( |
| 565 |
#if NOOPEN_LOWER |
| 566 |
tmp->v_type != VREG && |
| 567 |
#endif |
| 568 |
tmp->v_type != VDIR && |
| 569 |
tmp->v_type != VLNK) |
| 570 |
) |
| 571 |
#if NOOPEN_LOWER |
| 572 |
|| |
| 573 |
(tmp->v_type == VREG && (uppervp != NULL) && ( |
| 574 |
cnp->cn_nameiop == LOOKUP || cnp->cn_nameiop == CREATE)) |
| 575 |
#endif |
| 576 |
){ |
| 577 |
*(ap->a_vpp) = tmp; |
| 578 |
if(uppervp && lowervp) { |
| 579 |
vput(lowervp); |
| 580 |
lowervp = 0; |
| 581 |
} |
| 582 |
if (upperdvp) { |
| 583 |
if (upperdvp == tmp) { |
| 584 |
vrele(upperdvp); |
| 585 |
} else { |
| 586 |
vput(upperdvp); |
| 587 |
} |
| 588 |
upperdvp = NULL; |
| 589 |
} |
| 590 |
error = 0; |
| 591 |
}else{ |
| 592 |
error = union_allocvp(ap->a_vpp, dvp->v_mount, |
| 593 |
dvp, upperdvp, cnp, |
| 594 |
uppervp, lowervp, 1); |
| 595 |
} |
| 596 |
} |
| 544 |
|
597 |
|
| 545 |
UDEBUG(("Create %p = %p %p refs=%d\n", *ap->a_vpp, uppervp, lowervp, (*ap->a_vpp) ? ((*ap->a_vpp)->v_usecount) : -99)); |
598 |
UDEBUG(("Create %p = %p %p refs=%d\n", *ap->a_vpp, uppervp, lowervp, (*ap->a_vpp) ? ((*ap->a_vpp)->v_usecount) : -99)); |
| 546 |
|
599 |
|
|
Lines 612-618
Link Here
|
| 612 |
if (cnp->cn_namelen == 1 && |
665 |
if (cnp->cn_namelen == 1 && |
| 613 |
cnp->cn_nameptr[0] == '.' && |
666 |
cnp->cn_nameptr[0] == '.' && |
| 614 |
*ap->a_vpp != dvp) { |
667 |
*ap->a_vpp != dvp) { |
| 615 |
panic("union_lookup returning . (%p) not same as startdir (%p)", ap->a_vpp, dvp); |
668 |
/*panic("union_lookup returning . (%p) not same as startdir (%p)", *ap->a_vpp, dvp);*/ |
|
|
669 |
printf("union_lookup returning . (%p) not same as startdir (%p). error = %d\n", *ap->a_vpp, dvp, error); |
| 616 |
} |
670 |
} |
| 617 |
#endif |
671 |
#endif |
| 618 |
|
672 |
|
|
Lines 642-647
Link Here
|
| 642 |
int error = EROFS; |
696 |
int error = EROFS; |
| 643 |
|
697 |
|
| 644 |
if ((dvp = union_lock_upper(dun, p)) != NULL) { |
698 |
if ((dvp = union_lock_upper(dun, p)) != NULL) { |
|
|
699 |
#if 1 |
| 700 |
error = VOP_CREATE(dvp, ap->a_vpp, cnp, ap->a_vap); |
| 701 |
#else |
| 645 |
struct vnode *vp; |
702 |
struct vnode *vp; |
| 646 |
struct mount *mp; |
703 |
struct mount *mp; |
| 647 |
|
704 |
|
|
Lines 654-659
Link Here
|
| 654 |
cnp, vp, NULLVP, 1); |
711 |
cnp, vp, NULLVP, 1); |
| 655 |
UDEBUG(("ALLOCVP-2B FROM %p REFS %d\n", *ap->a_vpp, vp->v_usecount)); |
712 |
UDEBUG(("ALLOCVP-2B FROM %p REFS %d\n", *ap->a_vpp, vp->v_usecount)); |
| 656 |
} |
713 |
} |
|
|
714 |
#endif |
| 657 |
union_unlock_upper(dvp, p); |
715 |
union_unlock_upper(dvp, p); |
| 658 |
} |
716 |
} |
| 659 |
return (error); |
717 |
return (error); |
|
Lines 672-677
Link Here
|
| 672 |
struct vnode *uppervp; |
730 |
struct vnode *uppervp; |
| 673 |
int error = EOPNOTSUPP; |
731 |
int error = EOPNOTSUPP; |
| 674 |
|
732 |
|
|
|
733 |
if (cnp == NULL) { |
| 734 |
return 0; |
| 735 |
} |
| 736 |
|
| 675 |
if ((uppervp = union_lock_upper(un, cnp->cn_proc)) != NULLVP) { |
737 |
if ((uppervp = union_lock_upper(un, cnp->cn_proc)) != NULLVP) { |
| 676 |
error = VOP_WHITEOUT(un->un_uppervp, cnp, ap->a_flags); |
738 |
error = VOP_WHITEOUT(un->un_uppervp, cnp, ap->a_flags); |
| 677 |
union_unlock_upper(uppervp, cnp->cn_proc); |
739 |
union_unlock_upper(uppervp, cnp->cn_proc); |
|
Lines 1101-1108
Link Here
|
| 1101 |
struct vnode *uppervp; |
1163 |
struct vnode *uppervp; |
| 1102 |
int error; |
1164 |
int error; |
| 1103 |
|
1165 |
|
| 1104 |
if ((uppervp = union_lock_upper(un, p)) == NULLVP) |
1166 |
if ((uppervp = union_lock_upper(un, p)) == NULLVP) { |
|
|
1167 |
printf("un_uppervp: %x\n", un->un_uppervp); |
| 1105 |
panic("union: missing upper layer in write"); |
1168 |
panic("union: missing upper layer in write"); |
|
|
1169 |
} |
| 1106 |
|
1170 |
|
| 1107 |
/* |
1171 |
/* |
| 1108 |
* Since our VM pages are associated with our vnode rather then |
1172 |
* Since our VM pages are associated with our vnode rather then |
|
Lines 1318-1324
Link Here
|
| 1318 |
|
1382 |
|
| 1319 |
if (tun->un_uppervp == NULLVP) { |
1383 |
if (tun->un_uppervp == NULLVP) { |
| 1320 |
vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, p); |
1384 |
vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, p); |
| 1321 |
#if 0 |
1385 |
#if UPPERLOCK |
| 1322 |
if (dun->un_uppervp == tun->un_dirvp) { |
1386 |
if (dun->un_uppervp == tun->un_dirvp) { |
| 1323 |
if (dun->un_flags & UN_ULOCK) { |
1387 |
if (dun->un_flags & UN_ULOCK) { |
| 1324 |
dun->un_flags &= ~UN_ULOCK; |
1388 |
dun->un_flags &= ~UN_ULOCK; |
|
Lines 1327-1333
Link Here
|
| 1327 |
} |
1391 |
} |
| 1328 |
#endif |
1392 |
#endif |
| 1329 |
error = union_copyup(tun, 1, cnp->cn_cred, p); |
1393 |
error = union_copyup(tun, 1, cnp->cn_cred, p); |
| 1330 |
#if 0 |
1394 |
#if UPPERLOCK |
| 1331 |
if (dun->un_uppervp == tun->un_dirvp) { |
1395 |
if (dun->un_uppervp == tun->un_dirvp) { |
| 1332 |
vn_lock(dun->un_uppervp, |
1396 |
vn_lock(dun->un_uppervp, |
| 1333 |
LK_EXCLUSIVE | LK_RETRY, p); |
1397 |
LK_EXCLUSIVE | LK_RETRY, p); |
|
Lines 1647-1658
Link Here
|
| 1647 |
struct proc *p = ap->a_uio->uio_procp; |
1711 |
struct proc *p = ap->a_uio->uio_procp; |
| 1648 |
struct vnode *uvp; |
1712 |
struct vnode *uvp; |
| 1649 |
int error = 0; |
1713 |
int error = 0; |
|
|
1714 |
int save_resid; |
| 1650 |
|
1715 |
|
| 1651 |
if ((uvp = union_lock_upper(un, p)) != NULLVP) { |
1716 |
if ((un->un_uppersz == VNOVAL || un->un_uppersz >= ap->a_uio->uio_offset) && (uvp = union_lock_upper(un, p)) != NULLVP) { |
|
|
1717 |
/*uprintf("readdir un->un_uppersz = %d ap->a_uio->uio_offset = %d\n", un->un_uppersz, ap->a_uio->uio_offset);*/ |
| 1652 |
ap->a_vp = uvp; |
1718 |
ap->a_vp = uvp; |
|
|
1719 |
save_resid = ap->a_uio->uio_resid; |
| 1653 |
error = VCALL(uvp, VOFFSET(vop_readdir), ap); |
1720 |
error = VCALL(uvp, VOFFSET(vop_readdir), ap); |
|
|
1721 |
if(error) { |
| 1722 |
return(error); |
| 1723 |
} |
| 1654 |
union_unlock_upper(uvp, p); |
1724 |
union_unlock_upper(uvp, p); |
|
|
1725 |
if(un->un_uppersz == VNOVAL || ap->a_uio->uio_offset > un->un_uppersz) { |
| 1726 |
un->un_uppersz = ap->a_uio->uio_offset; |
| 1727 |
} |
| 1728 |
if(ap->a_uio->uio_resid == save_resid) { |
| 1729 |
un->un_uppersz = ap->a_uio->uio_offset; |
| 1730 |
} else { |
| 1731 |
return(0); |
| 1732 |
} |
| 1655 |
} |
1733 |
} |
|
|
1734 |
if ((uvp = un->un_lowervp)) { |
| 1735 |
ap->a_uio->uio_offset -= un->un_uppersz; |
| 1736 |
ap->a_vp = uvp; |
| 1737 |
VREF(uvp); |
| 1738 |
vn_lock(uvp, LK_EXCLUSIVE | LK_CANRECURSE | LK_RETRY, p); |
| 1739 |
error = VCALL(uvp, VOFFSET(vop_readdir), ap); |
| 1740 |
vput(uvp); |
| 1741 |
ap->a_uio->uio_offset += un->un_uppersz; |
| 1742 |
} |
| 1656 |
return(error); |
1743 |
return(error); |
| 1657 |
} |
1744 |
} |
| 1658 |
|
1745 |
|
|
Lines 1718-1724
Link Here
|
| 1718 |
un->un_dircache = 0; |
1805 |
un->un_dircache = 0; |
| 1719 |
} |
1806 |
} |
| 1720 |
|
1807 |
|
| 1721 |
#if 0 |
1808 |
#if UPPERLOCK |
| 1722 |
if ((un->un_flags & UN_ULOCK) && un->un_uppervp) { |
1809 |
if ((un->un_flags & UN_ULOCK) && un->un_uppervp) { |
| 1723 |
un->un_flags &= ~UN_ULOCK; |
1810 |
un->un_flags &= ~UN_ULOCK; |
| 1724 |
VOP_UNLOCK(un->un_uppervp, 0, p); |
1811 |
VOP_UNLOCK(un->un_uppervp, 0, p); |
|
Lines 1748-1754
Link Here
|
| 1748 |
union_lock(ap) |
1835 |
union_lock(ap) |
| 1749 |
struct vop_lock_args *ap; |
1836 |
struct vop_lock_args *ap; |
| 1750 |
{ |
1837 |
{ |
| 1751 |
#if 0 |
1838 |
#if UPPERLOCK |
| 1752 |
struct vnode *vp = ap->a_vp; |
1839 |
struct vnode *vp = ap->a_vp; |
| 1753 |
struct proc *p = ap->a_p; |
1840 |
struct proc *p = ap->a_p; |
| 1754 |
int flags = ap->a_flags; |
1841 |
int flags = ap->a_flags; |
|
Lines 1757-1763
Link Here
|
| 1757 |
int error; |
1844 |
int error; |
| 1758 |
|
1845 |
|
| 1759 |
error = vop_stdlock(ap); |
1846 |
error = vop_stdlock(ap); |
| 1760 |
#if 0 |
1847 |
#if UPPERLOCK |
| 1761 |
un = VTOUNION(vp); |
1848 |
un = VTOUNION(vp); |
| 1762 |
|
1849 |
|
| 1763 |
if (error == 0) { |
1850 |
if (error == 0) { |
|
Lines 1800-1810
Link Here
|
| 1800 |
{ |
1887 |
{ |
| 1801 |
struct union_node *un = VTOUNION(ap->a_vp); |
1888 |
struct union_node *un = VTOUNION(ap->a_vp); |
| 1802 |
int error; |
1889 |
int error; |
|
|
1890 |
#if UPPERLOCK |
| 1891 |
struct proc *p = ap->a_p; |
| 1892 |
#endif |
| 1803 |
|
1893 |
|
| 1804 |
KASSERT((un->un_uppervp == NULL || un->un_uppervp->v_usecount > 0), ("uppervp usecount is 0")); |
1894 |
KASSERT((un->un_uppervp == NULL || un->un_uppervp->v_usecount > 0), ("uppervp usecount is 0")); |
| 1805 |
|
1895 |
|
| 1806 |
error = vop_stdunlock(ap); |
1896 |
error = vop_stdunlock(ap); |
| 1807 |
#if 0 |
1897 |
#if UPPERLOCK |
| 1808 |
|
1898 |
|
| 1809 |
/* |
1899 |
/* |
| 1810 |
* If no exclusive locks remain and we are holding an uppervp lock, |
1900 |
* If no exclusive locks remain and we are holding an uppervp lock, |