X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/463c036020700bb67f65444d76e23497c9c4ced6..8a9c17f60a0e7f32fa5b6a8e64ec861e61a5246e:/usr/src/sys/miscfs/union/union_vnops.c diff --git a/usr/src/sys/miscfs/union/union_vnops.c b/usr/src/sys/miscfs/union/union_vnops.c index 22cbdf50f7..f165b98132 100644 --- a/usr/src/sys/miscfs/union/union_vnops.c +++ b/usr/src/sys/miscfs/union/union_vnops.c @@ -8,7 +8,7 @@ * * %sccs.include.redist.c% * - * @(#)union_vnops.c 8.8 (Berkeley) %G% + * @(#)union_vnops.c 8.10 (Berkeley) %G% */ #include @@ -151,7 +151,7 @@ union_lookup(ap) * then assume that something special is going * on and just return that vnode. */ - if (upperdvp) { + if (upperdvp != NULLVP) { FIXUP(dun); uerror = union_lookup1(um->um_uppervp, &upperdvp, &uppervp, cnp); @@ -175,7 +175,7 @@ union_lookup(ap) * back from the upper layer and return the lower vnode * instead. */ - if (lowerdvp) { + if (lowerdvp != NULLVP) { int nameiop; VOP_LOCK(lowerdvp); @@ -200,7 +200,7 @@ union_lookup(ap) VOP_UNLOCK(lowerdvp); if (cnp->cn_consume != 0) { - if (uppervp) { + if (uppervp != NULLVP) { if (uppervp == upperdvp) vrele(uppervp); else @@ -260,7 +260,7 @@ union_lookup(ap) dun->un_flags |= UN_ULOCK; if (uerror) { - if (lowervp) { + if (lowervp != NULLVP) { vput(lowervp); lowervp = NULLVP; } @@ -269,16 +269,16 @@ union_lookup(ap) } } - if (lowervp) + if (lowervp != NULLVP) VOP_UNLOCK(lowervp); error = union_allocvp(ap->a_vpp, dvp->v_mount, dvp, upperdvp, cnp, uppervp, lowervp); if (error) { - if (uppervp) + if (uppervp != NULLVP) vput(uppervp); - if (lowervp) + if (lowervp != NULLVP) vrele(lowervp); } else { if (*ap->a_vpp != dvp) @@ -301,7 +301,7 @@ union_create(ap) struct union_node *un = VTOUNION(ap->a_dvp); struct vnode *dvp = un->un_uppervp; - if (dvp) { + if (dvp != NULLVP) { int error; struct vnode *vp; @@ -343,7 +343,7 @@ union_mknod(ap) struct union_node *un = VTOUNION(ap->a_dvp); struct vnode *dvp = un->un_uppervp; - if (dvp) { + if (dvp != NULLVP) { int error; struct vnode *vp; @@ -356,7 +356,7 @@ union_mknod(ap) if (error) return (error); - if (vp) { + if (vp != NULLVP) { error = union_allocvp( ap->a_vpp, ap->a_dvp->v_mount, @@ -510,7 +510,7 @@ union_close(ap) struct union_node *un = VTOUNION(ap->a_vp); struct vnode *vp; - if (un->un_uppervp) { + if (un->un_uppervp != NULLVP) { vp = un->un_uppervp; } else { #ifdef UNION_DIAGNOSTIC @@ -546,12 +546,12 @@ union_access(ap) int error = EACCES; struct vnode *vp; - if (vp = un->un_uppervp) { + if ((vp = un->un_uppervp) != NULLVP) { FIXUP(un); return (VOP_ACCESS(vp, ap->a_mode, ap->a_cred, ap->a_p)); } - if (vp = un->un_lowervp) { + if ((vp = un->un_lowervp) != NULLVP) { VOP_LOCK(vp); error = VOP_ACCESS(vp, ap->a_mode, ap->a_cred, ap->a_p); if (error == 0) { @@ -570,7 +570,8 @@ union_access(ap) } /* - * We handle getattr only to change the fsid. + * We handle getattr only to change the fsid and + * track object sizes */ int union_getattr(ap) @@ -615,6 +616,7 @@ union_getattr(ap) error = VOP_GETATTR(vp, vap, ap->a_cred, ap->a_p); if (error) return (error); + union_newsize(ap->a_vp, vap->va_size, VNOVAL); } if (vp == NULLVP) { @@ -632,6 +634,7 @@ union_getattr(ap) VOP_UNLOCK(vp); if (error) return (error); + union_newsize(ap->a_vp, VNOVAL, vap->va_size); } if ((vap != ap->a_vap) && (vap->va_type == VDIR)) @@ -685,6 +688,8 @@ union_setattr(ap) FIXUP(un); error = VOP_SETATTR(un->un_uppervp, ap->a_vap, ap->a_cred, ap->a_p); + if ((error == 0) && (ap->a_vap->va_size != VNOVAL)) + union_newsize(ap->a_vp, ap->a_vap->va_size, VNOVAL); } else { error = EROFS; } @@ -713,6 +718,25 @@ union_read(ap) if (dolock) VOP_UNLOCK(vp); + /* + * XXX + * perhaps the size of the underlying object has changed under + * our feet. take advantage of the offset information present + * in the uio structure. + */ + if (error == 0) { + struct union_node *un = VTOUNION(ap->a_vp); + off_t cur = ap->a_uio->uio_offset; + + if (vp == un->un_uppervp) { + if (cur > un->un_uppersz) + union_newsize(ap->a_vp, cur, VNOVAL); + } else { + if (cur > un->un_lowersz) + union_newsize(ap->a_vp, VNOVAL, cur); + } + } + return (error); } @@ -737,6 +761,23 @@ union_write(ap) if (dolock) VOP_UNLOCK(vp); + /* + * the size of the underlying object may be changed by the + * write. + */ + if (error == 0) { + struct union_node *un = VTOUNION(ap->a_vp); + off_t cur = ap->a_uio->uio_offset; + + if (vp == un->un_uppervp) { + if (cur > un->un_uppersz) + union_newsize(ap->a_vp, cur, VNOVAL); + } else { + if (cur > un->un_lowersz) + union_newsize(ap->a_vp, VNOVAL, cur); + } + } + return (error); } @@ -797,7 +838,7 @@ union_fsync(ap) int error = 0; struct vnode *targetvp = OTHERVP(ap->a_vp); - if (targetvp) { + if (targetvp != NULLVP) { int dolock = (targetvp == LOWERVP(ap->a_vp)); if (dolock) @@ -838,7 +879,7 @@ union_remove(ap) struct union_node *dun = VTOUNION(ap->a_dvp); struct union_node *un = VTOUNION(ap->a_vp); - if (dun->un_uppervp && un->un_uppervp) { + if (dun->un_uppervp != NULLVP && un->un_uppervp != NULLVP) { struct vnode *dvp = dun->un_uppervp; struct vnode *vp = un->un_uppervp; @@ -882,7 +923,7 @@ union_link(ap) struct union_node *dun = VTOUNION(ap->a_vp); struct union_node *un = VTOUNION(ap->a_tdvp); - if (dun->un_uppervp && un->un_uppervp) { + if (dun->un_uppervp != NULLVP && un->un_uppervp != NULLVP) { struct vnode *dvp = dun->un_uppervp; struct vnode *vp = un->un_uppervp; @@ -897,7 +938,7 @@ union_link(ap) error = VOP_LINK(dvp, vp, ap->a_cnp); } else { /* - * XXX: need to copy to upper layer + * XXX: perhaps could copy to upper layer * and do the link there. */ vput(ap->a_vp); @@ -933,7 +974,6 @@ union_rename(ap) goto bad; } - FIXUP(un); fdvp = un->un_uppervp; VREF(fdvp); vrele(ap->a_fdvp); @@ -946,7 +986,6 @@ union_rename(ap) goto bad; } - FIXUP(un); fvp = un->un_uppervp; VREF(fvp); vrele(ap->a_fvp); @@ -955,6 +994,12 @@ union_rename(ap) if (tdvp->v_op == union_vnodeop_p) { struct union_node *un = VTOUNION(tdvp); if (un->un_uppervp == NULLVP) { + /* + * this should never happen in normal + * operation but might if there was + * a problem creating the top-level shadow + * directory. + */ error = EROFS; goto bad; } @@ -965,16 +1010,14 @@ union_rename(ap) vput(ap->a_tdvp); } - if (tvp && tvp->v_op == union_vnodeop_p) { + if (tvp != NULLVP && tvp->v_op == union_vnodeop_p) { struct union_node *un = VTOUNION(tvp); - if (un->un_uppervp == NULLVP) { - error = EROFS; - goto bad; - } tvp = un->un_uppervp; - VREF(tvp); - un->un_flags |= UN_KLOCK; + if (tvp != NULLVP) { + VREF(tvp); + un->un_flags |= UN_KLOCK; + } vput(ap->a_tvp); } @@ -984,7 +1027,7 @@ bad: vrele(fdvp); vrele(fvp); vput(tdvp); - if (tvp) + if (tvp != NULLVP) vput(tvp); return (error); @@ -1002,7 +1045,7 @@ union_mkdir(ap) struct union_node *un = VTOUNION(ap->a_dvp); struct vnode *dvp = un->un_uppervp; - if (dvp) { + if (dvp != NULLVP) { int error; struct vnode *vp; @@ -1043,7 +1086,7 @@ union_rmdir(ap) struct union_node *dun = VTOUNION(ap->a_dvp); struct union_node *un = VTOUNION(ap->a_vp); - if (dun->un_uppervp && un->un_uppervp) { + if (dun->un_uppervp != NULLVP && un->un_uppervp != NULLVP) { struct vnode *dvp = dun->un_uppervp; struct vnode *vp = un->un_uppervp; @@ -1088,7 +1131,7 @@ union_symlink(ap) struct union_node *un = VTOUNION(ap->a_dvp); struct vnode *dvp = un->un_uppervp; - if (dvp) { + if (dvp != NULLVP) { int error; struct vnode *vp; struct mount *mp = ap->a_dvp->v_mount; @@ -1126,7 +1169,7 @@ union_readdir(ap) int error = 0; struct union_node *un = VTOUNION(ap->a_vp); - if (un->un_uppervp) { + if (un->un_uppervp != NULLVP) { FIXUP(un); error = VOP_READDIR(un->un_uppervp, ap->a_uio, ap->a_cred); } @@ -1244,7 +1287,7 @@ start: un = VTOUNION(vp); - if (un->un_uppervp) { + if (un->un_uppervp != NULLVP) { if ((un->un_flags & UN_ULOCK) == 0) { un->un_flags |= UN_ULOCK; VOP_LOCK(un->un_uppervp);