*
* %sccs.include.redist.c%
*
- * @(#)union_vnops.c 8.8 (Berkeley) %G%
+ * @(#)union_vnops.c 8.10 (Berkeley) %G%
*/
#include <sys/param.h>
* 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);
* back from the upper layer and return the lower vnode
* instead.
*/
- if (lowerdvp) {
+ if (lowerdvp != NULLVP) {
int nameiop;
VOP_LOCK(lowerdvp);
VOP_UNLOCK(lowerdvp);
if (cnp->cn_consume != 0) {
- if (uppervp) {
+ if (uppervp != NULLVP) {
if (uppervp == upperdvp)
vrele(uppervp);
else
dun->un_flags |= UN_ULOCK;
if (uerror) {
- if (lowervp) {
+ if (lowervp != NULLVP) {
vput(lowervp);
lowervp = NULLVP;
}
}
}
- 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)
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 union_node *un = VTOUNION(ap->a_dvp);
struct vnode *dvp = un->un_uppervp;
- if (dvp) {
+ if (dvp != NULLVP) {
int error;
struct vnode *vp;
if (error)
return (error);
- if (vp) {
+ if (vp != NULLVP) {
error = union_allocvp(
ap->a_vpp,
ap->a_dvp->v_mount,
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
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) {
}
/*
- * We handle getattr only to change the fsid.
+ * We handle getattr only to change the fsid and
+ * track object sizes
*/
int
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) {
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))
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;
}
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);
}
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);
}
int error = 0;
struct vnode *targetvp = OTHERVP(ap->a_vp);
- if (targetvp) {
+ if (targetvp != NULLVP) {
int dolock = (targetvp == LOWERVP(ap->a_vp));
if (dolock)
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;
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;
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);
goto bad;
}
- FIXUP(un);
fdvp = un->un_uppervp;
VREF(fdvp);
vrele(ap->a_fdvp);
goto bad;
}
- FIXUP(un);
fvp = un->un_uppervp;
VREF(fvp);
vrele(ap->a_fvp);
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;
}
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);
}
vrele(fdvp);
vrele(fvp);
vput(tdvp);
- if (tvp)
+ if (tvp != NULLVP)
vput(tvp);
return (error);
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 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;
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;
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);
}
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);