Index: fs/deadfs/dead_vnops.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/fs/deadfs/dead_vnops.c,v retrieving revision 1.49 diff -u -r1.49 dead_vnops.c --- fs/deadfs/dead_vnops.c 22 Feb 2006 06:11:59 -0000 1.49 +++ fs/deadfs/dead_vnops.c 1 Jan 2007 11:52:32 -0000 @@ -49,6 +49,7 @@ static vop_read_t dead_read; static vop_write_t dead_write; static vop_getwritemount_t dead_getwritemount; +static vop_rename_t dead_rename; struct vop_vector dead_vnodeops = { .vop_default = &default_vnodeops, @@ -73,7 +74,7 @@ .vop_readlink = VOP_EBADF, .vop_reclaim = VOP_NULL, .vop_remove = VOP_PANIC, - .vop_rename = VOP_PANIC, + .vop_rename = dead_rename, .vop_rmdir = VOP_PANIC, .vop_setattr = VOP_EBADF, .vop_symlink = VOP_PANIC, @@ -211,3 +212,25 @@ { return (POLLHUP); } + +static int +dead_rename(ap) + struct vop_rename_args /* { + struct vnode *a_fdvp; + struct vnode *a_fvp; + struct componentname *a_fcnp; + struct vnode *a_tdvp; + struct vnode *a_tvp; + struct componentname *a_tcnp; + } */ *ap; +{ + if (ap->a_tvp) + vput(ap->a_tvp); + if (ap->a_tdvp == ap->a_tvp) + vrele(ap->a_tdvp); + else + vput(ap->a_tdvp); + vrele(ap->a_fdvp); + vrele(ap->a_fvp); + return (EXDEV); +} Index: kern/vfs_lookup.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/kern/vfs_lookup.c,v retrieving revision 1.96 diff -u -r1.96 vfs_lookup.c --- kern/vfs_lookup.c 22 Oct 2006 11:52:14 -0000 1.96 +++ kern/vfs_lookup.c 1 Jan 2007 11:52:32 -0000 @@ -69,13 +69,18 @@ * Allocation zone for namei */ uma_zone_t namei_zone; +/* + * Placeholder vnode for mp traversal + */ +static struct vnode *vp_crossmp; static void nameiinit(void *dummy __unused) { namei_zone = uma_zcreate("NAMEI", MAXPATHLEN, NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); - + getnewvnode("crossmp", NULL, &dead_vnodeops, &vp_crossmp); + vp_crossmp->v_vnlock->lk_flags &= ~LK_NOSHARE; } SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_SECOND, nameiinit, NULL) @@ -559,7 +564,8 @@ * If we have a shared lock we may need to upgrade the lock for the * last operation. */ - if (VOP_ISLOCKED(dp, td) == LK_SHARED && + if (dp != vp_crossmp && + VOP_ISLOCKED(dp, td) == LK_SHARED && (cnp->cn_flags & ISLASTCN) && (cnp->cn_flags & LOCKPARENT)) vn_lock(dp, LK_UPGRADE|LK_RETRY, td); /* @@ -658,10 +664,17 @@ VFS_UNLOCK_GIANT(vfslocked); vfslocked = VFS_LOCK_GIANT(mp); if (dp != ndp->ni_dvp) - VOP_UNLOCK(ndp->ni_dvp, 0, td); + vput(ndp->ni_dvp); + else + vrele(ndp->ni_dvp); + VFS_UNLOCK_GIANT(dvfslocked); + dvfslocked = 0; + vref(vp_crossmp); + ndp->ni_dvp = vp_crossmp; error = VFS_ROOT(mp, compute_cn_lkflags(mp, cnp->cn_lkflags), &tdp, td); vfs_unbusy(mp, td); - vn_lock(ndp->ni_dvp, compute_cn_lkflags(mp, cnp->cn_lkflags | LK_RETRY), td); + if (vn_lock(vp_crossmp, LK_SHARED | LK_NOWAIT, td)) + panic("vp_crossmp exclusively locked or reclaimed"); if (error) { dpunlocked = 1; goto bad2; Index: kern/vfs_subr.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/kern/vfs_subr.c,v retrieving revision 1.692 diff -u -r1.692 vfs_subr.c --- kern/vfs_subr.c 13 Nov 2006 05:51:22 -0000 1.692 +++ kern/vfs_subr.c 1 Jan 2007 11:52:32 -0000 @@ -939,8 +939,6 @@ mac_init_vnode(vp); if (mp != NULL && (mp->mnt_flag & MNT_MULTILABEL) == 0) mac_associate_vnode_singlelabel(mp, vp); - else if (mp == NULL) - printf("NULL mp in getnewvnode()\n"); #endif if (mp != NULL) { insmntque(vp, mp);