Fixes Unionfs socket issue reported as kern/118346.

PR:		118346
Submitted by:	Masanori OZAWA <ozawa@ongs.co.jp>
Discussed at:	devsummit Strassburg, EuroBSDCon2008
Discussed with:	rwatson, gnn, hrs
MFC after:	2 week
This commit is contained in:
Daichi GOTO 2008-11-25 03:18:35 +00:00
parent c3d6943244
commit 1e5da15a63
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=185283
3 changed files with 191 additions and 39 deletions

View file

@ -117,6 +117,7 @@ void unionfs_create_uppervattr_core(struct unionfs_mount *ump, struct vattr *lva
int unionfs_create_uppervattr(struct unionfs_mount *ump, struct vnode *lvp, struct vattr *uva, struct ucred *cred, struct thread *td); int unionfs_create_uppervattr(struct unionfs_mount *ump, struct vnode *lvp, struct vattr *uva, struct ucred *cred, struct thread *td);
int unionfs_mkshadowdir(struct unionfs_mount *ump, struct vnode *duvp, struct unionfs_node *unp, struct componentname *cnp, struct thread *td); int unionfs_mkshadowdir(struct unionfs_mount *ump, struct vnode *duvp, struct unionfs_node *unp, struct componentname *cnp, struct thread *td);
int unionfs_mkwhiteout(struct vnode *dvp, struct componentname *cnp, struct thread *td, char *path); int unionfs_mkwhiteout(struct vnode *dvp, struct componentname *cnp, struct thread *td, char *path);
int unionfs_relookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, struct componentname *cn, struct thread *td, char *path, int pathlen, u_long nameiop);
int unionfs_relookup_for_create(struct vnode *dvp, struct componentname *cnp, struct thread *td); int unionfs_relookup_for_create(struct vnode *dvp, struct componentname *cnp, struct thread *td);
int unionfs_relookup_for_delete(struct vnode *dvp, struct componentname *cnp, struct thread *td); int unionfs_relookup_for_delete(struct vnode *dvp, struct componentname *cnp, struct thread *td);
int unionfs_relookup_for_rename(struct vnode *dvp, struct componentname *cnp, struct thread *td); int unionfs_relookup_for_rename(struct vnode *dvp, struct componentname *cnp, struct thread *td);

View file

@ -113,10 +113,10 @@ unionfs_get_cached_vnode(struct vnode *uvp, struct vnode *lvp,
struct unionfs_node *unp; struct unionfs_node *unp;
struct vnode *vp; struct vnode *vp;
KASSERT((uvp == NULLVP || uvp->v_type == VDIR || uvp->v_type == VSOCK), KASSERT((uvp == NULLVP || uvp->v_type == VDIR),
("unionfs_get_cached_vnode: v_type != VDIR/VSOCK")); ("unionfs_get_cached_vnode: v_type != VDIR"));
KASSERT((lvp == NULLVP || lvp->v_type == VDIR || lvp->v_type == VSOCK), KASSERT((lvp == NULLVP || lvp->v_type == VDIR),
("unionfs_get_cached_vnode: v_type != VDIR/VSOCK")); ("unionfs_get_cached_vnode: v_type != VDIR"));
VI_LOCK(dvp); VI_LOCK(dvp);
hd = unionfs_get_hashhead(dvp, path); hd = unionfs_get_hashhead(dvp, path);
@ -150,12 +150,10 @@ unionfs_ins_cached_vnode(struct unionfs_node *uncp,
struct unionfs_node *unp; struct unionfs_node *unp;
struct vnode *vp; struct vnode *vp;
KASSERT((uncp->un_uppervp==NULLVP || uncp->un_uppervp->v_type==VDIR || KASSERT((uncp->un_uppervp==NULLVP || uncp->un_uppervp->v_type==VDIR),
uncp->un_uppervp->v_type==VSOCK), ("unionfs_ins_cached_vnode: v_type != VDIR"));
("unionfs_ins_cached_vnode: v_type != VDIR/VSOCK")); KASSERT((uncp->un_lowervp==NULLVP || uncp->un_lowervp->v_type==VDIR),
KASSERT((uncp->un_lowervp==NULLVP || uncp->un_lowervp->v_type==VDIR || ("unionfs_ins_cached_vnode: v_type != VDIR"));
uncp->un_lowervp->v_type==VSOCK),
("unionfs_ins_cached_vnode: v_type != VDIR/VSOCK"));
VI_LOCK(dvp); VI_LOCK(dvp);
hd = unionfs_get_hashhead(dvp, path); hd = unionfs_get_hashhead(dvp, path);
@ -236,7 +234,7 @@ unionfs_nodeget(struct mount *mp, struct vnode *uppervp,
path = NULL; path = NULL;
/* check the cache */ /* check the cache */
if (path != NULL && dvp != NULLVP && (vt == VDIR || vt == VSOCK)) { if (path != NULL && dvp != NULLVP && vt == VDIR) {
vp = unionfs_get_cached_vnode(uppervp, lowervp, dvp, path); vp = unionfs_get_cached_vnode(uppervp, lowervp, dvp, path);
if (vp != NULLVP) { if (vp != NULLVP) {
vref(vp); vref(vp);
@ -277,20 +275,9 @@ unionfs_nodeget(struct mount *mp, struct vnode *uppervp,
if (lowervp != NULLVP) if (lowervp != NULLVP)
vref(lowervp); vref(lowervp);
switch (vt) { if (vt == VDIR)
case VDIR:
unp->un_hashtbl = hashinit(NUNIONFSNODECACHE, M_UNIONFSHASH, unp->un_hashtbl = hashinit(NUNIONFSNODECACHE, M_UNIONFSHASH,
&(unp->un_hashmask)); &(unp->un_hashmask));
break;
case VSOCK:
if (uppervp != NULLVP)
vp->v_socket = uppervp->v_socket;
else
vp->v_socket = lowervp->v_socket;
break;
default:
break;
}
unp->un_vnode = vp; unp->un_vnode = vp;
unp->un_uppervp = uppervp; unp->un_uppervp = uppervp;
@ -314,7 +301,7 @@ unionfs_nodeget(struct mount *mp, struct vnode *uppervp,
(lowervp != NULLVP && ump->um_lowervp == lowervp)) (lowervp != NULLVP && ump->um_lowervp == lowervp))
vp->v_vflag |= VV_ROOT; vp->v_vflag |= VV_ROOT;
if (path != NULL && dvp != NULLVP && (vt == VDIR || vt == VSOCK)) if (path != NULL && dvp != NULLVP && vt == VDIR)
*vpp = unionfs_ins_cached_vnode(unp, dvp, path); *vpp = unionfs_ins_cached_vnode(unp, dvp, path);
if ((*vpp) != NULLVP) { if ((*vpp) != NULLVP) {
if (dvp != NULLVP) if (dvp != NULLVP)
@ -540,7 +527,7 @@ unionfs_create_uppervattr(struct unionfs_mount *ump,
* locked, referenced vnode. If *vpp == dvp then remember that only one * locked, referenced vnode. If *vpp == dvp then remember that only one
* LK_EXCLUSIVE lock is held. * LK_EXCLUSIVE lock is held.
*/ */
static int int
unionfs_relookup(struct vnode *dvp, struct vnode **vpp, unionfs_relookup(struct vnode *dvp, struct vnode **vpp,
struct componentname *cnp, struct componentname *cn, struct componentname *cnp, struct componentname *cn,
struct thread *td, char *path, int pathlen, u_long nameiop) struct thread *td, char *path, int pathlen, u_long nameiop)
@ -748,8 +735,7 @@ unionfs_node_update(struct unionfs_node *unp, struct vnode *uvp,
/* /*
* cache update * cache update
*/ */
if (unp->un_path != NULL && dvp != NULLVP && if (unp->un_path != NULL && dvp != NULLVP && vp->v_type == VDIR) {
(vp->v_type == VDIR || vp->v_type == VSOCK)) {
static struct unionfs_node_hashhead *hd; static struct unionfs_node_hashhead *hd;
VI_LOCK(dvp); VI_LOCK(dvp);

View file

@ -71,6 +71,10 @@
#define UNIONFS_INTERNAL_DEBUG(msg, args...) #define UNIONFS_INTERNAL_DEBUG(msg, args...)
#endif #endif
#define KASSERT_UNIONFS_VNODE(vp) \
KASSERT(((vp)->v_op == &unionfs_vnodeops), \
("unionfs: it is not unionfs-vnode"))
/* lockmgr lock <-> reverse table */ /* lockmgr lock <-> reverse table */
struct lk_lr_table { struct lk_lr_table {
int lock; int lock;
@ -307,8 +311,27 @@ unionfs_lookup(struct vop_cachedlookup_args *ap)
error = lerror; error = lerror;
if (error != 0) if (error != 0)
goto unionfs_lookup_out; goto unionfs_lookup_out;
error = unionfs_nodeget(dvp->v_mount, uvp, lvp, dvp, &vp, /*
cnp, td); * get socket vnode.
*/
if (uvp != NULLVP && uvp->v_type == VSOCK) {
vp = uvp;
vref(vp);
if (cnp->cn_lkflags & LK_TYPE_MASK)
vn_lock(vp, cnp->cn_lkflags | LK_RETRY);
}
else if (lvp != NULLVP && lvp->v_type == VSOCK) {
vp = lvp;
vref(vp);
if (cnp->cn_lkflags & LK_TYPE_MASK)
vn_lock(vp, cnp->cn_lkflags | LK_RETRY);
}
/*
* get unionfs vnode.
*/
else
error = unionfs_nodeget(dvp->v_mount, uvp, lvp,
dvp, &vp, cnp, td);
if (error != 0) { if (error != 0) {
UNIONFSDEBUG("unionfs_lookup: Unable to create unionfs vnode."); UNIONFSDEBUG("unionfs_lookup: Unable to create unionfs vnode.");
goto unionfs_lookup_out; goto unionfs_lookup_out;
@ -320,7 +343,7 @@ unionfs_lookup(struct vop_cachedlookup_args *ap)
*(ap->a_vpp) = vp; *(ap->a_vpp) = vp;
if (cnflags & MAKEENTRY) if ((cnflags & MAKEENTRY) && vp->v_type != VSOCK)
cache_enter(dvp, vp, cnp); cache_enter(dvp, vp, cnp);
unionfs_lookup_out: unionfs_lookup_out:
@ -348,13 +371,21 @@ unionfs_create(struct vop_create_args *ap)
UNIONFS_INTERNAL_DEBUG("unionfs_create: enter\n"); UNIONFS_INTERNAL_DEBUG("unionfs_create: enter\n");
KASSERT_UNIONFS_VNODE(ap->a_dvp);
dunp = VTOUNIONFS(ap->a_dvp); dunp = VTOUNIONFS(ap->a_dvp);
cnp = ap->a_cnp; cnp = ap->a_cnp;
udvp = dunp->un_uppervp; udvp = dunp->un_uppervp;
error = EROFS; error = EROFS;
if (udvp != NULLVP) { if (udvp != NULLVP) {
if ((error = VOP_CREATE(udvp, &vp, cnp, ap->a_vap)) == 0) { error = VOP_CREATE(udvp, &vp, cnp, ap->a_vap);
if (error != 0)
goto unionfs_create_abort;
if (vp->v_type == VSOCK)
*(ap->a_vpp) = vp;
else {
VOP_UNLOCK(vp, 0); VOP_UNLOCK(vp, 0);
error = unionfs_nodeget(ap->a_dvp->v_mount, vp, NULLVP, error = unionfs_nodeget(ap->a_dvp->v_mount, vp, NULLVP,
ap->a_dvp, ap->a_vpp, cnp, curthread); ap->a_dvp, ap->a_vpp, cnp, curthread);
@ -362,6 +393,7 @@ unionfs_create(struct vop_create_args *ap)
} }
} }
unionfs_create_abort:
UNIONFS_INTERNAL_DEBUG("unionfs_create: leave (%d)\n", error); UNIONFS_INTERNAL_DEBUG("unionfs_create: leave (%d)\n", error);
return (error); return (error);
@ -377,6 +409,8 @@ unionfs_whiteout(struct vop_whiteout_args *ap)
UNIONFS_INTERNAL_DEBUG("unionfs_whiteout: enter\n"); UNIONFS_INTERNAL_DEBUG("unionfs_whiteout: enter\n");
KASSERT_UNIONFS_VNODE(ap->a_dvp);
dunp = VTOUNIONFS(ap->a_dvp); dunp = VTOUNIONFS(ap->a_dvp);
cnp = ap->a_cnp; cnp = ap->a_cnp;
udvp = dunp->un_uppervp; udvp = dunp->un_uppervp;
@ -411,13 +445,21 @@ unionfs_mknod(struct vop_mknod_args *ap)
UNIONFS_INTERNAL_DEBUG("unionfs_mknod: enter\n"); UNIONFS_INTERNAL_DEBUG("unionfs_mknod: enter\n");
KASSERT_UNIONFS_VNODE(ap->a_dvp);
dunp = VTOUNIONFS(ap->a_dvp); dunp = VTOUNIONFS(ap->a_dvp);
cnp = ap->a_cnp; cnp = ap->a_cnp;
udvp = dunp->un_uppervp; udvp = dunp->un_uppervp;
error = EROFS; error = EROFS;
if (udvp != NULLVP) { if (udvp != NULLVP) {
if ((error = VOP_MKNOD(udvp, &vp, cnp, ap->a_vap)) == 0) { error = VOP_MKNOD(udvp, &vp, cnp, ap->a_vap);
if (error != 0)
goto unionfs_mknod_abort;
if (vp->v_type == VSOCK)
*(ap->a_vpp) = vp;
else {
VOP_UNLOCK(vp, 0); VOP_UNLOCK(vp, 0);
error = unionfs_nodeget(ap->a_dvp->v_mount, vp, NULLVP, error = unionfs_nodeget(ap->a_dvp->v_mount, vp, NULLVP,
ap->a_dvp, ap->a_vpp, cnp, curthread); ap->a_dvp, ap->a_vpp, cnp, curthread);
@ -425,6 +467,7 @@ unionfs_mknod(struct vop_mknod_args *ap)
} }
} }
unionfs_mknod_abort:
UNIONFS_INTERNAL_DEBUG("unionfs_mknod: leave (%d)\n", error); UNIONFS_INTERNAL_DEBUG("unionfs_mknod: leave (%d)\n", error);
return (error); return (error);
@ -444,6 +487,8 @@ unionfs_open(struct vop_open_args *ap)
UNIONFS_INTERNAL_DEBUG("unionfs_open: enter\n"); UNIONFS_INTERNAL_DEBUG("unionfs_open: enter\n");
KASSERT_UNIONFS_VNODE(ap->a_vp);
error = 0; error = 0;
unp = VTOUNIONFS(ap->a_vp); unp = VTOUNIONFS(ap->a_vp);
uvp = unp->un_uppervp; uvp = unp->un_uppervp;
@ -523,6 +568,8 @@ unionfs_close(struct vop_close_args *ap)
UNIONFS_INTERNAL_DEBUG("unionfs_close: enter\n"); UNIONFS_INTERNAL_DEBUG("unionfs_close: enter\n");
KASSERT_UNIONFS_VNODE(ap->a_vp);
locked = 0; locked = 0;
unp = VTOUNIONFS(ap->a_vp); unp = VTOUNIONFS(ap->a_vp);
cred = ap->a_cred; cred = ap->a_cred;
@ -650,6 +697,8 @@ unionfs_access(struct vop_access_args *ap)
UNIONFS_INTERNAL_DEBUG("unionfs_access: enter\n"); UNIONFS_INTERNAL_DEBUG("unionfs_access: enter\n");
KASSERT_UNIONFS_VNODE(ap->a_vp);
ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount); ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount);
unp = VTOUNIONFS(ap->a_vp); unp = VTOUNIONFS(ap->a_vp);
uvp = unp->un_uppervp; uvp = unp->un_uppervp;
@ -727,6 +776,8 @@ unionfs_getattr(struct vop_getattr_args *ap)
UNIONFS_INTERNAL_DEBUG("unionfs_getattr: enter\n"); UNIONFS_INTERNAL_DEBUG("unionfs_getattr: enter\n");
KASSERT_UNIONFS_VNODE(ap->a_vp);
unp = VTOUNIONFS(ap->a_vp); unp = VTOUNIONFS(ap->a_vp);
ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount); ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount);
uvp = unp->un_uppervp; uvp = unp->un_uppervp;
@ -777,6 +828,8 @@ unionfs_setattr(struct vop_setattr_args *ap)
UNIONFS_INTERNAL_DEBUG("unionfs_setattr: enter\n"); UNIONFS_INTERNAL_DEBUG("unionfs_setattr: enter\n");
KASSERT_UNIONFS_VNODE(ap->a_vp);
error = EROFS; error = EROFS;
unp = VTOUNIONFS(ap->a_vp); unp = VTOUNIONFS(ap->a_vp);
uvp = unp->un_uppervp; uvp = unp->un_uppervp;
@ -815,6 +868,8 @@ unionfs_read(struct vop_read_args *ap)
/* UNIONFS_INTERNAL_DEBUG("unionfs_read: enter\n"); */ /* UNIONFS_INTERNAL_DEBUG("unionfs_read: enter\n"); */
KASSERT_UNIONFS_VNODE(ap->a_vp);
unp = VTOUNIONFS(ap->a_vp); unp = VTOUNIONFS(ap->a_vp);
tvp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); tvp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
@ -834,6 +889,8 @@ unionfs_write(struct vop_write_args *ap)
/* UNIONFS_INTERNAL_DEBUG("unionfs_write: enter\n"); */ /* UNIONFS_INTERNAL_DEBUG("unionfs_write: enter\n"); */
KASSERT_UNIONFS_VNODE(ap->a_vp);
unp = VTOUNIONFS(ap->a_vp); unp = VTOUNIONFS(ap->a_vp);
tvp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); tvp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
@ -853,6 +910,8 @@ unionfs_lease(struct vop_lease_args *ap)
UNIONFS_INTERNAL_DEBUG("unionfs_lease: enter\n"); UNIONFS_INTERNAL_DEBUG("unionfs_lease: enter\n");
KASSERT_UNIONFS_VNODE(ap->a_vp);
unp = VTOUNIONFS(ap->a_vp); unp = VTOUNIONFS(ap->a_vp);
vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
@ -873,6 +932,8 @@ unionfs_ioctl(struct vop_ioctl_args *ap)
UNIONFS_INTERNAL_DEBUG("unionfs_ioctl: enter\n"); UNIONFS_INTERNAL_DEBUG("unionfs_ioctl: enter\n");
KASSERT_UNIONFS_VNODE(ap->a_vp);
vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY); vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
unp = VTOUNIONFS(ap->a_vp); unp = VTOUNIONFS(ap->a_vp);
unionfs_get_node_status(unp, ap->a_td, &unsp); unionfs_get_node_status(unp, ap->a_td, &unsp);
@ -898,6 +959,8 @@ unionfs_poll(struct vop_poll_args *ap)
struct unionfs_node_status *unsp; struct unionfs_node_status *unsp;
struct vnode *ovp; struct vnode *ovp;
KASSERT_UNIONFS_VNODE(ap->a_vp);
vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY); vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
unp = VTOUNIONFS(ap->a_vp); unp = VTOUNIONFS(ap->a_vp);
unionfs_get_node_status(unp, ap->a_td, &unsp); unionfs_get_node_status(unp, ap->a_td, &unsp);
@ -918,6 +981,8 @@ unionfs_fsync(struct vop_fsync_args *ap)
struct unionfs_node_status *unsp; struct unionfs_node_status *unsp;
struct vnode *ovp; struct vnode *ovp;
KASSERT_UNIONFS_VNODE(ap->a_vp);
unp = VTOUNIONFS(ap->a_vp); unp = VTOUNIONFS(ap->a_vp);
unionfs_get_node_status(unp, ap->a_td, &unsp); unionfs_get_node_status(unp, ap->a_td, &unsp);
ovp = (unsp->uns_upper_opencnt ? unp->un_uppervp : unp->un_lowervp); ovp = (unsp->uns_upper_opencnt ? unp->un_uppervp : unp->un_lowervp);
@ -933,36 +998,81 @@ static int
unionfs_remove(struct vop_remove_args *ap) unionfs_remove(struct vop_remove_args *ap)
{ {
int error; int error;
char *path;
struct unionfs_node *dunp; struct unionfs_node *dunp;
struct unionfs_node *unp; struct unionfs_node *unp;
struct unionfs_mount *ump; struct unionfs_mount *ump;
struct vnode *udvp; struct vnode *udvp;
struct vnode *uvp; struct vnode *uvp;
struct vnode *lvp; struct vnode *lvp;
struct vnode *vp;
struct componentname *cnp; struct componentname *cnp;
struct componentname cn;
struct thread *td; struct thread *td;
UNIONFS_INTERNAL_DEBUG("unionfs_remove: enter\n"); UNIONFS_INTERNAL_DEBUG("unionfs_remove: enter\n");
KASSERT_UNIONFS_VNODE(ap->a_dvp);
error = 0; error = 0;
dunp = VTOUNIONFS(ap->a_dvp); dunp = VTOUNIONFS(ap->a_dvp);
unp = VTOUNIONFS(ap->a_vp);
udvp = dunp->un_uppervp; udvp = dunp->un_uppervp;
uvp = unp->un_uppervp;
lvp = unp->un_lowervp;
cnp = ap->a_cnp; cnp = ap->a_cnp;
td = curthread; td = curthread;
if (ap->a_vp->v_op != &unionfs_vnodeops) {
if (ap->a_vp->v_type != VSOCK)
return (EINVAL);
ump = NULL;
vp = uvp = lvp = NULLVP;
/* search vnode */
VOP_UNLOCK(ap->a_vp, 0);
error = unionfs_relookup(udvp, &vp, cnp, &cn, td,
cnp->cn_nameptr, strlen(cnp->cn_nameptr), DELETE);
if (error != 0 && error != ENOENT) {
vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
return (error);
}
if (error == 0 && vp == ap->a_vp) {
/* target vnode in upper */
uvp = vp;
vrele(vp);
path = NULL;
} else {
/* target vnode in lower */
if (vp != NULLVP) {
if (udvp == vp)
vrele(vp);
else
vput(vp);
}
vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
lvp = ap->a_vp;
path = ap->a_cnp->cn_nameptr;
}
} else {
ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount);
unp = VTOUNIONFS(ap->a_vp);
uvp = unp->un_uppervp;
lvp = unp->un_lowervp;
path = unp->un_path;
}
if (udvp == NULLVP) if (udvp == NULLVP)
return (EROFS); return (EROFS);
if (uvp != NULLVP) { if (uvp != NULLVP) {
ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount); /*
if (ump->um_whitemode == UNIONFS_WHITE_ALWAYS || lvp != NULLVP) * XXX: if the vnode type is VSOCK, it will create whiteout
* after remove.
*/
if (ump == NULL || ump->um_whitemode == UNIONFS_WHITE_ALWAYS ||
lvp != NULLVP)
cnp->cn_flags |= DOWHITEOUT; cnp->cn_flags |= DOWHITEOUT;
error = VOP_REMOVE(udvp, uvp, cnp); error = VOP_REMOVE(udvp, uvp, cnp);
} else if (lvp != NULLVP) } else if (lvp != NULLVP)
error = unionfs_mkwhiteout(udvp, cnp, td, unp->un_path); error = unionfs_mkwhiteout(udvp, cnp, td, path);
UNIONFS_INTERNAL_DEBUG("unionfs_remove: leave (%d)\n", error); UNIONFS_INTERNAL_DEBUG("unionfs_remove: leave (%d)\n", error);
@ -983,6 +1093,9 @@ unionfs_link(struct vop_link_args *ap)
UNIONFS_INTERNAL_DEBUG("unionfs_link: enter\n"); UNIONFS_INTERNAL_DEBUG("unionfs_link: enter\n");
KASSERT_UNIONFS_VNODE(ap->a_tdvp);
KASSERT_UNIONFS_VNODE(ap->a_vp);
error = 0; error = 0;
needrelookup = 0; needrelookup = 0;
dunp = VTOUNIONFS(ap->a_tdvp); dunp = VTOUNIONFS(ap->a_tdvp);
@ -1073,7 +1186,10 @@ unionfs_rename(struct vop_rename_args *ap)
/* check for cross device rename */ /* check for cross device rename */
if (fvp->v_mount != tdvp->v_mount || if (fvp->v_mount != tdvp->v_mount ||
(tvp != NULLVP && fvp->v_mount != tvp->v_mount)) { (tvp != NULLVP && fvp->v_mount != tvp->v_mount)) {
error = EXDEV; if (fvp->v_op != &unionfs_vnodeops)
error = ENODEV;
else
error = EXDEV;
goto unionfs_rename_abort; goto unionfs_rename_abort;
} }
@ -1085,6 +1201,12 @@ unionfs_rename(struct vop_rename_args *ap)
* from/to vnode is unionfs node. * from/to vnode is unionfs node.
*/ */
KASSERT_UNIONFS_VNODE(fdvp);
KASSERT_UNIONFS_VNODE(fvp);
KASSERT_UNIONFS_VNODE(tdvp);
if (tvp != NULLVP)
KASSERT_UNIONFS_VNODE(tvp);
unp = VTOUNIONFS(fdvp); unp = VTOUNIONFS(fdvp);
#ifdef UNIONFS_IDBG_RENAME #ifdef UNIONFS_IDBG_RENAME
UNIONFS_INTERNAL_DEBUG("fdvp=%p, ufdvp=%p, lfdvp=%p\n", fdvp, unp->un_uppervp, unp->un_lowervp); UNIONFS_INTERNAL_DEBUG("fdvp=%p, ufdvp=%p, lfdvp=%p\n", fdvp, unp->un_uppervp, unp->un_lowervp);
@ -1254,6 +1376,8 @@ unionfs_mkdir(struct vop_mkdir_args *ap)
UNIONFS_INTERNAL_DEBUG("unionfs_mkdir: enter\n"); UNIONFS_INTERNAL_DEBUG("unionfs_mkdir: enter\n");
KASSERT_UNIONFS_VNODE(ap->a_dvp);
error = EROFS; error = EROFS;
dunp = VTOUNIONFS(ap->a_dvp); dunp = VTOUNIONFS(ap->a_dvp);
cnp = ap->a_cnp; cnp = ap->a_cnp;
@ -1301,6 +1425,9 @@ unionfs_rmdir(struct vop_rmdir_args *ap)
UNIONFS_INTERNAL_DEBUG("unionfs_rmdir: enter\n"); UNIONFS_INTERNAL_DEBUG("unionfs_rmdir: enter\n");
KASSERT_UNIONFS_VNODE(ap->a_dvp);
KASSERT_UNIONFS_VNODE(ap->a_vp);
error = 0; error = 0;
dunp = VTOUNIONFS(ap->a_dvp); dunp = VTOUNIONFS(ap->a_dvp);
unp = VTOUNIONFS(ap->a_vp); unp = VTOUNIONFS(ap->a_vp);
@ -1353,6 +1480,8 @@ unionfs_symlink(struct vop_symlink_args *ap)
UNIONFS_INTERNAL_DEBUG("unionfs_symlink: enter\n"); UNIONFS_INTERNAL_DEBUG("unionfs_symlink: enter\n");
KASSERT_UNIONFS_VNODE(ap->a_dvp);
error = EROFS; error = EROFS;
dunp = VTOUNIONFS(ap->a_dvp); dunp = VTOUNIONFS(ap->a_dvp);
cnp = ap->a_cnp; cnp = ap->a_cnp;
@ -1396,6 +1525,8 @@ unionfs_readdir(struct vop_readdir_args *ap)
UNIONFS_INTERNAL_DEBUG("unionfs_readdir: enter\n"); UNIONFS_INTERNAL_DEBUG("unionfs_readdir: enter\n");
KASSERT_UNIONFS_VNODE(ap->a_vp);
error = 0; error = 0;
eofflag = 0; eofflag = 0;
locked = 0; locked = 0;
@ -1543,6 +1674,8 @@ unionfs_readlink(struct vop_readlink_args *ap)
UNIONFS_INTERNAL_DEBUG("unionfs_readlink: enter\n"); UNIONFS_INTERNAL_DEBUG("unionfs_readlink: enter\n");
KASSERT_UNIONFS_VNODE(ap->a_vp);
unp = VTOUNIONFS(ap->a_vp); unp = VTOUNIONFS(ap->a_vp);
vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
@ -1568,6 +1701,8 @@ unionfs_getwritemount(struct vop_getwritemount_args *ap)
if (vp == NULLVP || (vp->v_mount->mnt_flag & MNT_RDONLY)) if (vp == NULLVP || (vp->v_mount->mnt_flag & MNT_RDONLY))
return (EACCES); return (EACCES);
KASSERT_UNIONFS_VNODE(vp);
uvp = UNIONFSVPTOUPPERVP(vp); uvp = UNIONFSVPTOUPPERVP(vp);
if (uvp == NULLVP && VREG == vp->v_type) if (uvp == NULLVP && VREG == vp->v_type)
uvp = UNIONFSVPTOUPPERVP(VTOUNIONFS(vp)->un_dvp); uvp = UNIONFSVPTOUPPERVP(VTOUNIONFS(vp)->un_dvp);
@ -1661,6 +1796,8 @@ unionfs_lock(struct vop_lock1_args *ap)
struct vnode *uvp; struct vnode *uvp;
struct vnode *lvp; struct vnode *lvp;
KASSERT_UNIONFS_VNODE(ap->a_vp);
error = 0; error = 0;
uhold = 0; uhold = 0;
flags = ap->a_flags; flags = ap->a_flags;
@ -1781,6 +1918,8 @@ unionfs_unlock(struct vop_unlock_args *ap)
struct vnode *uvp; struct vnode *uvp;
struct unionfs_node *unp; struct unionfs_node *unp;
KASSERT_UNIONFS_VNODE(ap->a_vp);
error = 0; error = 0;
mtxlkflag = 0; mtxlkflag = 0;
uhold = 0; uhold = 0;
@ -1849,6 +1988,8 @@ unionfs_pathconf(struct vop_pathconf_args *ap)
struct unionfs_node *unp; struct unionfs_node *unp;
struct vnode *vp; struct vnode *vp;
KASSERT_UNIONFS_VNODE(ap->a_vp);
unp = VTOUNIONFS(ap->a_vp); unp = VTOUNIONFS(ap->a_vp);
vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
@ -1867,6 +2008,8 @@ unionfs_advlock(struct vop_advlock_args *ap)
UNIONFS_INTERNAL_DEBUG("unionfs_advlock: enter\n"); UNIONFS_INTERNAL_DEBUG("unionfs_advlock: enter\n");
KASSERT_UNIONFS_VNODE(ap->a_vp);
vp = ap->a_vp; vp = ap->a_vp;
td = curthread; td = curthread;
@ -1917,6 +2060,8 @@ unionfs_strategy(struct vop_strategy_args *ap)
struct unionfs_node *unp; struct unionfs_node *unp;
struct vnode *vp; struct vnode *vp;
KASSERT_UNIONFS_VNODE(ap->a_vp);
unp = VTOUNIONFS(ap->a_vp); unp = VTOUNIONFS(ap->a_vp);
vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
@ -1938,6 +2083,8 @@ unionfs_getacl(struct vop_getacl_args *ap)
struct unionfs_node *unp; struct unionfs_node *unp;
struct vnode *vp; struct vnode *vp;
KASSERT_UNIONFS_VNODE(ap->a_vp);
unp = VTOUNIONFS(ap->a_vp); unp = VTOUNIONFS(ap->a_vp);
vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
@ -1961,6 +2108,8 @@ unionfs_setacl(struct vop_setacl_args *ap)
UNIONFS_INTERNAL_DEBUG("unionfs_setacl: enter\n"); UNIONFS_INTERNAL_DEBUG("unionfs_setacl: enter\n");
KASSERT_UNIONFS_VNODE(ap->a_vp);
error = EROFS; error = EROFS;
unp = VTOUNIONFS(ap->a_vp); unp = VTOUNIONFS(ap->a_vp);
uvp = unp->un_uppervp; uvp = unp->un_uppervp;
@ -1993,6 +2142,8 @@ unionfs_aclcheck(struct vop_aclcheck_args *ap)
UNIONFS_INTERNAL_DEBUG("unionfs_aclcheck: enter\n"); UNIONFS_INTERNAL_DEBUG("unionfs_aclcheck: enter\n");
KASSERT_UNIONFS_VNODE(ap->a_vp);
unp = VTOUNIONFS(ap->a_vp); unp = VTOUNIONFS(ap->a_vp);
vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
@ -2011,6 +2162,8 @@ unionfs_openextattr(struct vop_openextattr_args *ap)
struct vnode *vp; struct vnode *vp;
struct vnode *tvp; struct vnode *tvp;
KASSERT_UNIONFS_VNODE(ap->a_vp);
vp = ap->a_vp; vp = ap->a_vp;
unp = VTOUNIONFS(vp); unp = VTOUNIONFS(vp);
tvp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp); tvp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
@ -2041,6 +2194,8 @@ unionfs_closeextattr(struct vop_closeextattr_args *ap)
struct vnode *vp; struct vnode *vp;
struct vnode *tvp; struct vnode *tvp;
KASSERT_UNIONFS_VNODE(ap->a_vp);
vp = ap->a_vp; vp = ap->a_vp;
unp = VTOUNIONFS(vp); unp = VTOUNIONFS(vp);
tvp = NULLVP; tvp = NULLVP;
@ -2073,6 +2228,8 @@ unionfs_getextattr(struct vop_getextattr_args *ap)
struct unionfs_node *unp; struct unionfs_node *unp;
struct vnode *vp; struct vnode *vp;
KASSERT_UNIONFS_VNODE(ap->a_vp);
unp = VTOUNIONFS(ap->a_vp); unp = VTOUNIONFS(ap->a_vp);
vp = NULLVP; vp = NULLVP;
@ -2099,6 +2256,8 @@ unionfs_setextattr(struct vop_setextattr_args *ap)
struct ucred *cred; struct ucred *cred;
struct thread *td; struct thread *td;
KASSERT_UNIONFS_VNODE(ap->a_vp);
error = EROFS; error = EROFS;
unp = VTOUNIONFS(ap->a_vp); unp = VTOUNIONFS(ap->a_vp);
uvp = unp->un_uppervp; uvp = unp->un_uppervp;
@ -2158,6 +2317,8 @@ unionfs_listextattr(struct vop_listextattr_args *ap)
struct unionfs_node *unp; struct unionfs_node *unp;
struct vnode *vp; struct vnode *vp;
KASSERT_UNIONFS_VNODE(ap->a_vp);
unp = VTOUNIONFS(ap->a_vp); unp = VTOUNIONFS(ap->a_vp);
vp = NULLVP; vp = NULLVP;
@ -2184,6 +2345,8 @@ unionfs_deleteextattr(struct vop_deleteextattr_args *ap)
struct ucred *cred; struct ucred *cred;
struct thread *td; struct thread *td;
KASSERT_UNIONFS_VNODE(ap->a_vp);
error = EROFS; error = EROFS;
unp = VTOUNIONFS(ap->a_vp); unp = VTOUNIONFS(ap->a_vp);
uvp = unp->un_uppervp; uvp = unp->un_uppervp;
@ -2248,6 +2411,8 @@ unionfs_setlabel(struct vop_setlabel_args *ap)
UNIONFS_INTERNAL_DEBUG("unionfs_setlabel: enter\n"); UNIONFS_INTERNAL_DEBUG("unionfs_setlabel: enter\n");
KASSERT_UNIONFS_VNODE(ap->a_vp);
error = EROFS; error = EROFS;
unp = VTOUNIONFS(ap->a_vp); unp = VTOUNIONFS(ap->a_vp);
uvp = unp->un_uppervp; uvp = unp->un_uppervp;