diff --git a/sys/fs/unionfs/union.h b/sys/fs/unionfs/union.h index 8cb6f03e64ac..38820595c706 100644 --- a/sys/fs/unionfs/union.h +++ b/sys/fs/unionfs/union.h @@ -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_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_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_delete(struct vnode *dvp, struct componentname *cnp, struct thread *td); int unionfs_relookup_for_rename(struct vnode *dvp, struct componentname *cnp, struct thread *td); diff --git a/sys/fs/unionfs/union_subr.c b/sys/fs/unionfs/union_subr.c index 7422de879276..beaef2f94ec6 100644 --- a/sys/fs/unionfs/union_subr.c +++ b/sys/fs/unionfs/union_subr.c @@ -113,10 +113,10 @@ unionfs_get_cached_vnode(struct vnode *uvp, struct vnode *lvp, struct unionfs_node *unp; struct vnode *vp; - KASSERT((uvp == NULLVP || uvp->v_type == VDIR || uvp->v_type == VSOCK), - ("unionfs_get_cached_vnode: v_type != VDIR/VSOCK")); - KASSERT((lvp == NULLVP || lvp->v_type == VDIR || lvp->v_type == VSOCK), - ("unionfs_get_cached_vnode: v_type != VDIR/VSOCK")); + KASSERT((uvp == NULLVP || uvp->v_type == VDIR), + ("unionfs_get_cached_vnode: v_type != VDIR")); + KASSERT((lvp == NULLVP || lvp->v_type == VDIR), + ("unionfs_get_cached_vnode: v_type != VDIR")); VI_LOCK(dvp); hd = unionfs_get_hashhead(dvp, path); @@ -150,12 +150,10 @@ unionfs_ins_cached_vnode(struct unionfs_node *uncp, struct unionfs_node *unp; struct vnode *vp; - KASSERT((uncp->un_uppervp==NULLVP || uncp->un_uppervp->v_type==VDIR || - uncp->un_uppervp->v_type==VSOCK), - ("unionfs_ins_cached_vnode: v_type != VDIR/VSOCK")); - KASSERT((uncp->un_lowervp==NULLVP || uncp->un_lowervp->v_type==VDIR || - uncp->un_lowervp->v_type==VSOCK), - ("unionfs_ins_cached_vnode: v_type != VDIR/VSOCK")); + KASSERT((uncp->un_uppervp==NULLVP || uncp->un_uppervp->v_type==VDIR), + ("unionfs_ins_cached_vnode: v_type != VDIR")); + KASSERT((uncp->un_lowervp==NULLVP || uncp->un_lowervp->v_type==VDIR), + ("unionfs_ins_cached_vnode: v_type != VDIR")); VI_LOCK(dvp); hd = unionfs_get_hashhead(dvp, path); @@ -236,7 +234,7 @@ unionfs_nodeget(struct mount *mp, struct vnode *uppervp, path = NULL; /* 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); if (vp != NULLVP) { vref(vp); @@ -277,20 +275,9 @@ unionfs_nodeget(struct mount *mp, struct vnode *uppervp, if (lowervp != NULLVP) vref(lowervp); - switch (vt) { - case VDIR: + if (vt == VDIR) unp->un_hashtbl = hashinit(NUNIONFSNODECACHE, M_UNIONFSHASH, &(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_uppervp = uppervp; @@ -314,7 +301,7 @@ unionfs_nodeget(struct mount *mp, struct vnode *uppervp, (lowervp != NULLVP && ump->um_lowervp == lowervp)) 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); if ((*vpp) != 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 * LK_EXCLUSIVE lock is held. */ -static int +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) @@ -748,8 +735,7 @@ unionfs_node_update(struct unionfs_node *unp, struct vnode *uvp, /* * cache update */ - if (unp->un_path != NULL && dvp != NULLVP && - (vp->v_type == VDIR || vp->v_type == VSOCK)) { + if (unp->un_path != NULL && dvp != NULLVP && vp->v_type == VDIR) { static struct unionfs_node_hashhead *hd; VI_LOCK(dvp); diff --git a/sys/fs/unionfs/union_vnops.c b/sys/fs/unionfs/union_vnops.c index e900e7bf8b96..d16851d883ea 100644 --- a/sys/fs/unionfs/union_vnops.c +++ b/sys/fs/unionfs/union_vnops.c @@ -71,6 +71,10 @@ #define UNIONFS_INTERNAL_DEBUG(msg, args...) #endif +#define KASSERT_UNIONFS_VNODE(vp) \ + KASSERT(((vp)->v_op == &unionfs_vnodeops), \ + ("unionfs: it is not unionfs-vnode")) + /* lockmgr lock <-> reverse table */ struct lk_lr_table { int lock; @@ -307,8 +311,27 @@ unionfs_lookup(struct vop_cachedlookup_args *ap) error = lerror; if (error != 0) 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) { UNIONFSDEBUG("unionfs_lookup: Unable to create unionfs vnode."); goto unionfs_lookup_out; @@ -320,7 +343,7 @@ unionfs_lookup(struct vop_cachedlookup_args *ap) *(ap->a_vpp) = vp; - if (cnflags & MAKEENTRY) + if ((cnflags & MAKEENTRY) && vp->v_type != VSOCK) cache_enter(dvp, vp, cnp); unionfs_lookup_out: @@ -348,13 +371,21 @@ unionfs_create(struct vop_create_args *ap) UNIONFS_INTERNAL_DEBUG("unionfs_create: enter\n"); + KASSERT_UNIONFS_VNODE(ap->a_dvp); + dunp = VTOUNIONFS(ap->a_dvp); cnp = ap->a_cnp; udvp = dunp->un_uppervp; error = EROFS; 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); error = unionfs_nodeget(ap->a_dvp->v_mount, vp, NULLVP, 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); return (error); @@ -377,6 +409,8 @@ unionfs_whiteout(struct vop_whiteout_args *ap) UNIONFS_INTERNAL_DEBUG("unionfs_whiteout: enter\n"); + KASSERT_UNIONFS_VNODE(ap->a_dvp); + dunp = VTOUNIONFS(ap->a_dvp); cnp = ap->a_cnp; udvp = dunp->un_uppervp; @@ -411,13 +445,21 @@ unionfs_mknod(struct vop_mknod_args *ap) UNIONFS_INTERNAL_DEBUG("unionfs_mknod: enter\n"); + KASSERT_UNIONFS_VNODE(ap->a_dvp); + dunp = VTOUNIONFS(ap->a_dvp); cnp = ap->a_cnp; udvp = dunp->un_uppervp; error = EROFS; 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); error = unionfs_nodeget(ap->a_dvp->v_mount, vp, NULLVP, 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); return (error); @@ -444,6 +487,8 @@ unionfs_open(struct vop_open_args *ap) UNIONFS_INTERNAL_DEBUG("unionfs_open: enter\n"); + KASSERT_UNIONFS_VNODE(ap->a_vp); + error = 0; unp = VTOUNIONFS(ap->a_vp); uvp = unp->un_uppervp; @@ -523,6 +568,8 @@ unionfs_close(struct vop_close_args *ap) UNIONFS_INTERNAL_DEBUG("unionfs_close: enter\n"); + KASSERT_UNIONFS_VNODE(ap->a_vp); + locked = 0; unp = VTOUNIONFS(ap->a_vp); cred = ap->a_cred; @@ -650,6 +697,8 @@ unionfs_access(struct vop_access_args *ap) UNIONFS_INTERNAL_DEBUG("unionfs_access: enter\n"); + KASSERT_UNIONFS_VNODE(ap->a_vp); + ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount); unp = VTOUNIONFS(ap->a_vp); uvp = unp->un_uppervp; @@ -727,6 +776,8 @@ unionfs_getattr(struct vop_getattr_args *ap) UNIONFS_INTERNAL_DEBUG("unionfs_getattr: enter\n"); + KASSERT_UNIONFS_VNODE(ap->a_vp); + unp = VTOUNIONFS(ap->a_vp); ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount); uvp = unp->un_uppervp; @@ -777,6 +828,8 @@ unionfs_setattr(struct vop_setattr_args *ap) UNIONFS_INTERNAL_DEBUG("unionfs_setattr: enter\n"); + KASSERT_UNIONFS_VNODE(ap->a_vp); + error = EROFS; unp = VTOUNIONFS(ap->a_vp); uvp = unp->un_uppervp; @@ -815,6 +868,8 @@ unionfs_read(struct vop_read_args *ap) /* UNIONFS_INTERNAL_DEBUG("unionfs_read: enter\n"); */ + KASSERT_UNIONFS_VNODE(ap->a_vp); + unp = VTOUNIONFS(ap->a_vp); 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"); */ + KASSERT_UNIONFS_VNODE(ap->a_vp); + unp = VTOUNIONFS(ap->a_vp); 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"); + KASSERT_UNIONFS_VNODE(ap->a_vp); + unp = VTOUNIONFS(ap->a_vp); 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"); + KASSERT_UNIONFS_VNODE(ap->a_vp); + vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY); unp = VTOUNIONFS(ap->a_vp); 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 vnode *ovp; + KASSERT_UNIONFS_VNODE(ap->a_vp); + vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY); unp = VTOUNIONFS(ap->a_vp); 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 vnode *ovp; + KASSERT_UNIONFS_VNODE(ap->a_vp); + unp = VTOUNIONFS(ap->a_vp); unionfs_get_node_status(unp, ap->a_td, &unsp); ovp = (unsp->uns_upper_opencnt ? unp->un_uppervp : unp->un_lowervp); @@ -933,36 +998,81 @@ static int unionfs_remove(struct vop_remove_args *ap) { int error; + char *path; struct unionfs_node *dunp; struct unionfs_node *unp; struct unionfs_mount *ump; struct vnode *udvp; struct vnode *uvp; struct vnode *lvp; + struct vnode *vp; struct componentname *cnp; + struct componentname cn; struct thread *td; UNIONFS_INTERNAL_DEBUG("unionfs_remove: enter\n"); + KASSERT_UNIONFS_VNODE(ap->a_dvp); + error = 0; dunp = VTOUNIONFS(ap->a_dvp); - unp = VTOUNIONFS(ap->a_vp); udvp = dunp->un_uppervp; - uvp = unp->un_uppervp; - lvp = unp->un_lowervp; cnp = ap->a_cnp; 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) return (EROFS); 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; error = VOP_REMOVE(udvp, uvp, cnp); } 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); @@ -983,6 +1093,9 @@ unionfs_link(struct vop_link_args *ap) UNIONFS_INTERNAL_DEBUG("unionfs_link: enter\n"); + KASSERT_UNIONFS_VNODE(ap->a_tdvp); + KASSERT_UNIONFS_VNODE(ap->a_vp); + error = 0; needrelookup = 0; dunp = VTOUNIONFS(ap->a_tdvp); @@ -1073,7 +1186,10 @@ unionfs_rename(struct vop_rename_args *ap) /* check for cross device rename */ if (fvp->v_mount != tdvp->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; } @@ -1085,6 +1201,12 @@ unionfs_rename(struct vop_rename_args *ap) * 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); #ifdef UNIONFS_IDBG_RENAME 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"); + KASSERT_UNIONFS_VNODE(ap->a_dvp); + error = EROFS; dunp = VTOUNIONFS(ap->a_dvp); cnp = ap->a_cnp; @@ -1301,6 +1425,9 @@ unionfs_rmdir(struct vop_rmdir_args *ap) UNIONFS_INTERNAL_DEBUG("unionfs_rmdir: enter\n"); + KASSERT_UNIONFS_VNODE(ap->a_dvp); + KASSERT_UNIONFS_VNODE(ap->a_vp); + error = 0; dunp = VTOUNIONFS(ap->a_dvp); unp = VTOUNIONFS(ap->a_vp); @@ -1353,6 +1480,8 @@ unionfs_symlink(struct vop_symlink_args *ap) UNIONFS_INTERNAL_DEBUG("unionfs_symlink: enter\n"); + KASSERT_UNIONFS_VNODE(ap->a_dvp); + error = EROFS; dunp = VTOUNIONFS(ap->a_dvp); cnp = ap->a_cnp; @@ -1396,6 +1525,8 @@ unionfs_readdir(struct vop_readdir_args *ap) UNIONFS_INTERNAL_DEBUG("unionfs_readdir: enter\n"); + KASSERT_UNIONFS_VNODE(ap->a_vp); + error = 0; eofflag = 0; locked = 0; @@ -1543,6 +1674,8 @@ unionfs_readlink(struct vop_readlink_args *ap) UNIONFS_INTERNAL_DEBUG("unionfs_readlink: enter\n"); + KASSERT_UNIONFS_VNODE(ap->a_vp); + unp = VTOUNIONFS(ap->a_vp); 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)) return (EACCES); + KASSERT_UNIONFS_VNODE(vp); + uvp = UNIONFSVPTOUPPERVP(vp); if (uvp == NULLVP && VREG == vp->v_type) uvp = UNIONFSVPTOUPPERVP(VTOUNIONFS(vp)->un_dvp); @@ -1661,6 +1796,8 @@ unionfs_lock(struct vop_lock1_args *ap) struct vnode *uvp; struct vnode *lvp; + KASSERT_UNIONFS_VNODE(ap->a_vp); + error = 0; uhold = 0; flags = ap->a_flags; @@ -1781,6 +1918,8 @@ unionfs_unlock(struct vop_unlock_args *ap) struct vnode *uvp; struct unionfs_node *unp; + KASSERT_UNIONFS_VNODE(ap->a_vp); + error = 0; mtxlkflag = 0; uhold = 0; @@ -1849,6 +1988,8 @@ unionfs_pathconf(struct vop_pathconf_args *ap) struct unionfs_node *unp; struct vnode *vp; + KASSERT_UNIONFS_VNODE(ap->a_vp); + unp = VTOUNIONFS(ap->a_vp); 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"); + KASSERT_UNIONFS_VNODE(ap->a_vp); + vp = ap->a_vp; td = curthread; @@ -1917,6 +2060,8 @@ unionfs_strategy(struct vop_strategy_args *ap) struct unionfs_node *unp; struct vnode *vp; + KASSERT_UNIONFS_VNODE(ap->a_vp); + unp = VTOUNIONFS(ap->a_vp); 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 vnode *vp; + KASSERT_UNIONFS_VNODE(ap->a_vp); + unp = VTOUNIONFS(ap->a_vp); 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"); + KASSERT_UNIONFS_VNODE(ap->a_vp); + error = EROFS; unp = VTOUNIONFS(ap->a_vp); uvp = unp->un_uppervp; @@ -1993,6 +2142,8 @@ unionfs_aclcheck(struct vop_aclcheck_args *ap) UNIONFS_INTERNAL_DEBUG("unionfs_aclcheck: enter\n"); + KASSERT_UNIONFS_VNODE(ap->a_vp); + unp = VTOUNIONFS(ap->a_vp); 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 *tvp; + KASSERT_UNIONFS_VNODE(ap->a_vp); + vp = ap->a_vp; unp = VTOUNIONFS(vp); 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 *tvp; + KASSERT_UNIONFS_VNODE(ap->a_vp); + vp = ap->a_vp; unp = VTOUNIONFS(vp); tvp = NULLVP; @@ -2073,6 +2228,8 @@ unionfs_getextattr(struct vop_getextattr_args *ap) struct unionfs_node *unp; struct vnode *vp; + KASSERT_UNIONFS_VNODE(ap->a_vp); + unp = VTOUNIONFS(ap->a_vp); vp = NULLVP; @@ -2099,6 +2256,8 @@ unionfs_setextattr(struct vop_setextattr_args *ap) struct ucred *cred; struct thread *td; + KASSERT_UNIONFS_VNODE(ap->a_vp); + error = EROFS; unp = VTOUNIONFS(ap->a_vp); uvp = unp->un_uppervp; @@ -2158,6 +2317,8 @@ unionfs_listextattr(struct vop_listextattr_args *ap) struct unionfs_node *unp; struct vnode *vp; + KASSERT_UNIONFS_VNODE(ap->a_vp); + unp = VTOUNIONFS(ap->a_vp); vp = NULLVP; @@ -2184,6 +2345,8 @@ unionfs_deleteextattr(struct vop_deleteextattr_args *ap) struct ucred *cred; struct thread *td; + KASSERT_UNIONFS_VNODE(ap->a_vp); + error = EROFS; unp = VTOUNIONFS(ap->a_vp); uvp = unp->un_uppervp; @@ -2248,6 +2411,8 @@ unionfs_setlabel(struct vop_setlabel_args *ap) UNIONFS_INTERNAL_DEBUG("unionfs_setlabel: enter\n"); + KASSERT_UNIONFS_VNODE(ap->a_vp); + error = EROFS; unp = VTOUNIONFS(ap->a_vp); uvp = unp->un_uppervp;