The attached patch changes VOP_REMOVE and VOP_RMDIR so that they neither unlock nor release the directory vnode. Except for rename, these are the last two directory operations that still vput dvp -- all the others (lookup, create, link, mkdir, &c.) have been changed to stop doing that.
These still unlock and release the object vnode. I don't plan to change that -- instead, later, I would like to change all the directory operations, particularly rename, so that they take arguments (dvp, cnp) instead of (dvp, cnp, vp) and do the last lookup (and permissions checks) themselves. Comments? Objections?
Index: external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c =================================================================== RCS file: /cvsroot/src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c,v retrieving revision 1.24 diff -p -u -r1.24 zfs_vnops.c --- external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c 11 Apr 2017 14:25:01 -0000 1.24 +++ external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c 16 Apr 2017 17:21:32 -0000 @@ -4975,7 +4975,7 @@ zfs_netbsd_create(void *v) static int zfs_netbsd_remove(void *v) { - struct vop_remove_args /* { + struct vop_remove_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -5002,13 +5002,6 @@ zfs_netbsd_remove(void *v) 0); KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); - - /* - * Unlock and release dvp because the VOP_REMOVE protocol is insane. - */ - VOP_UNLOCK(dvp); - VN_RELE(dvp); - return (error); } @@ -5048,7 +5041,7 @@ zfs_netbsd_mkdir(void *v) static int zfs_netbsd_rmdir(void *v) { - struct vop_rmdir_args /* { + struct vop_rmdir_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -5075,12 +5068,6 @@ zfs_netbsd_rmdir(void *v) NULL, 0); KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); - - /* - * Unlock and release dvp because the VOP_RMDIR protocol is insane. - */ - VOP_UNLOCK(dvp); - VN_RELE(dvp); return error; } Index: lib/libp2k/p2k.c =================================================================== RCS file: /cvsroot/src/lib/libp2k/p2k.c,v retrieving revision 1.69 diff -p -u -r1.69 p2k.c --- lib/libp2k/p2k.c 11 Apr 2017 14:25:02 -0000 1.69 +++ lib/libp2k/p2k.c 16 Apr 2017 17:21:32 -0000 @@ -1026,8 +1026,11 @@ do_nukenode(struct p2k_node *p2n_dir, st RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); rump_pub_vp_incref(vp); rv = nukefn(dvp, vp, cn); - assert(RUMP_VOP_ISLOCKED(dvp) == 0); + assert(dvp != vp); + assert(RUMP_VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); assert(RUMP_VOP_ISLOCKED(vp) == 0); + rump_pub_vp_rele(dvp); + RUMP_VOP_UNLOCK(dvp); freecn(cn); return rv; Index: sys/coda/coda_vnops.c =================================================================== RCS file: /cvsroot/src/sys/coda/coda_vnops.c,v retrieving revision 1.104 diff -p -u -r1.104 coda_vnops.c --- sys/coda/coda_vnops.c 11 Apr 2017 14:24:59 -0000 1.104 +++ sys/coda/coda_vnops.c 16 Apr 2017 17:21:32 -0000 @@ -1071,7 +1071,7 @@ int coda_remove(void *v) { /* true args */ - struct vop_remove_args *ap = v; + struct vop_remove_v2_args *ap = v; vnode_t *dvp = ap->a_dvp; struct cnode *cp = VTOC(dvp); vnode_t *vp = ap->a_vp; @@ -1124,14 +1124,13 @@ coda_remove(void *v) CODADEBUG(CODA_REMOVE, myprintf(("in remove result %d\n",error)); ) /* - * Unlock parent and child (avoiding double if "."). + * Unlock and release child (avoiding double if "."). */ if (dvp == vp) { vrele(vp); } else { vput(vp); } - vput(dvp); return(error); } @@ -1377,7 +1376,7 @@ int coda_rmdir(void *v) { /* true args */ - struct vop_rmdir_args *ap = v; + struct vop_rmdir_v2_args *ap = v; vnode_t *dvp = ap->a_dvp; struct cnode *dcp = VTOC(dvp); vnode_t *vp = ap->a_vp; @@ -1429,8 +1428,7 @@ coda_rmdir(void *v) CODADEBUG(CODA_RMDIR, myprintf(("in rmdir result %d\n", error)); ) exit: - /* vput both vnodes */ - vput(dvp); + /* unlock and release child */ if (dvp == vp) { vrele(vp); } else { Index: sys/compat/svr4/svr4_stream.c =================================================================== RCS file: /cvsroot/src/sys/compat/svr4/svr4_stream.c,v retrieving revision 1.87 diff -p -u -r1.87 svr4_stream.c --- sys/compat/svr4/svr4_stream.c 13 Sep 2016 07:01:08 -0000 1.87 +++ sys/compat/svr4/svr4_stream.c 16 Apr 2017 17:21:32 -0000 @@ -328,6 +328,7 @@ clean_pipe(struct lwp *l, const char *pa goto bad; error = VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); + vput(nd.ni_dvp); pathbuf_destroy(pb); return error; Index: sys/fs/msdosfs/msdosfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/msdosfs/msdosfs_vnops.c,v retrieving revision 1.97 diff -p -u -r1.97 msdosfs_vnops.c --- sys/fs/msdosfs/msdosfs_vnops.c 1 Mar 2017 10:41:28 -0000 1.97 +++ sys/fs/msdosfs/msdosfs_vnops.c 16 Apr 2017 17:21:33 -0000 @@ -715,7 +715,7 @@ msdosfs_update(struct vnode *vp, const s int msdosfs_remove(void *v) { - struct vop_remove_args /* { + struct vop_remove_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -739,7 +739,7 @@ msdosfs_remove(void *v) else vput(ap->a_vp); /* causes msdosfs_inactive() to be called * via vrele() */ - vput(ap->a_dvp); + return (error); } @@ -1266,7 +1266,7 @@ bad2: int msdosfs_rmdir(void *v) { - struct vop_rmdir_args /* { + struct vop_rmdir_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -1283,8 +1283,7 @@ msdosfs_rmdir(void *v) * No rmdir "." please. */ if (dp == ip) { - vrele(dvp); - vput(vp); + vrele(vp); return (EINVAL); } /* @@ -1316,8 +1315,6 @@ msdosfs_rmdir(void *v) */ VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK); cache_purge(dvp); - vput(dvp); - dvp = NULL; /* * Truncate the directory that is being deleted. */ @@ -1325,8 +1322,6 @@ msdosfs_rmdir(void *v) cache_purge(vp); out: VN_KNOTE(vp, NOTE_DELETE); - if (dvp) - vput(dvp); vput(vp); return (error); } Index: sys/fs/nilfs/nilfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/nilfs/nilfs_vnops.c,v retrieving revision 1.34 diff -p -u -r1.34 nilfs_vnops.c --- sys/fs/nilfs/nilfs_vnops.c 11 Apr 2017 14:24:59 -0000 1.34 +++ sys/fs/nilfs/nilfs_vnops.c 16 Apr 2017 17:21:33 -0000 @@ -1404,7 +1404,7 @@ out_unlocked: int nilfs_remove(void *v) { - struct vop_remove_args /* { + struct vop_remove_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -1435,7 +1435,6 @@ nilfs_remove(void *v) vrele(vp); else vput(vp); - vput(dvp); return error; } @@ -1445,7 +1444,7 @@ nilfs_remove(void *v) int nilfs_rmdir(void *v) { - struct vop_rmdir_args /* { + struct vop_rmdir_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -1462,8 +1461,7 @@ nilfs_rmdir(void *v) /* don't allow '.' to be deleted */ if (dir_node == nilfs_node) { - vrele(dvp); - vput(vp); + vrele(vp); return EINVAL; } @@ -1472,7 +1470,6 @@ nilfs_rmdir(void *v) refcnt = 2; /* XXX */ if (refcnt > 1) { /* NOT empty */ - vput(dvp); vput(vp); return ENOTEMPTY; } @@ -1486,8 +1483,7 @@ nilfs_rmdir(void *v) } DPRINTFIF(NODE, error, ("\tgot error removing file\n")); - /* unput the nodes and exit */ - vput(dvp); + /* put the node and exit */ vput(vp); return error; Index: sys/fs/puffs/puffs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/puffs/puffs_vnops.c,v retrieving revision 1.209 diff -p -u -r1.209 puffs_vnops.c --- sys/fs/puffs/puffs_vnops.c 11 Apr 2017 14:24:59 -0000 1.209 +++ sys/fs/puffs/puffs_vnops.c 16 Apr 2017 17:21:33 -0000 @@ -1829,7 +1829,7 @@ callremove(struct puffs_mount *pmp, puff int puffs_vnop_remove(void *v) { - struct vop_remove_args /* { + struct vop_remove_v2_args /* { const struct vnodeop_desc *a_desc; struct vnode *a_dvp; struct vnode *a_vp; @@ -1853,7 +1853,8 @@ puffs_vnop_remove(void *v) PUFFS_VN_REMOVE, VPTOPNC(dvp)); puffs_msg_enqueue(pmp, park_remove); - REFPN_AND_UNLOCKVP(dvp, dpn); + vref(dvp); /* hang onto caller's reference at end */ + REFPN(dpn); if (dvp == vp) REFPN(pn); else @@ -1952,7 +1953,7 @@ callrmdir(struct puffs_mount *pmp, puffs int puffs_vnop_rmdir(void *v) { - struct vop_rmdir_args /* { + struct vop_rmdir_v2_args /* { const struct vnodeop_desc *a_desc; struct vnode *a_dvp; struct vnode *a_vp; @@ -1975,7 +1976,9 @@ puffs_vnop_rmdir(void *v) PUFFS_VN_RMDIR, VPTOPNC(dvp)); puffs_msg_enqueue(pmp, park_rmdir); - REFPN_AND_UNLOCKVP(dvp, dpn); + vref(dvp); /* hang onto caller's reference at end */ + KASSERTMSG((dvp != vp), "rmdir ."); + REFPN(dpn); REFPN_AND_UNLOCKVP(vp, pn); error = puffs_msg_wait2(pmp, park_rmdir, dpn, pn); Index: sys/fs/smbfs/smbfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/smbfs/smbfs_vnops.c,v retrieving revision 1.93 diff -p -u -r1.93 smbfs_vnops.c --- sys/fs/smbfs/smbfs_vnops.c 21 Dec 2014 10:48:53 -0000 1.93 +++ sys/fs/smbfs/smbfs_vnops.c 16 Apr 2017 17:21:33 -0000 @@ -618,7 +618,7 @@ smbfs_create(void *v) int smbfs_remove(void *v) { - struct vop_remove_args /* { + struct vop_remove_v2_args /* { struct vnodeop_desc *a_desc; struct vnode * a_dvp; struct vnode * a_vp; @@ -648,7 +648,6 @@ smbfs_remove(void *v) vrele(vp); else vput(vp); - vput(dvp); return (error); } @@ -822,7 +821,7 @@ smbfs_mkdir(void *v) int smbfs_rmdir(void *v) { - struct vop_rmdir_args /* { + struct vop_rmdir_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -837,8 +836,7 @@ smbfs_rmdir(void *v) int error; if (dvp == vp) { - vrele(dvp); - vput(dvp); + vrele(vp); return (EINVAL); } @@ -853,7 +851,6 @@ smbfs_rmdir(void *v) cache_purge(dvp); cache_purge(vp); vput(vp); - vput(dvp); return (error); } Index: sys/fs/sysvbfs/sysvbfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/sysvbfs/sysvbfs_vnops.c,v retrieving revision 1.61 diff -p -u -r1.61 sysvbfs_vnops.c --- sys/fs/sysvbfs/sysvbfs_vnops.c 11 Apr 2017 14:25:00 -0000 1.61 +++ sys/fs/sysvbfs/sysvbfs_vnops.c 16 Apr 2017 17:21:34 -0000 @@ -508,7 +508,7 @@ sysvbfs_write(void *arg) int sysvbfs_remove(void *arg) { - struct vop_remove_args /* { + struct vop_remove_v2_args /* { struct vnodeop_desc *a_desc; struct vnode * a_dvp; struct vnode * a_vp; @@ -523,8 +523,10 @@ sysvbfs_remove(void *arg) DPRINTF("%s: delete %s\n", __func__, ap->a_cnp->cn_nameptr); - if (vp->v_type == VDIR) + if (vp->v_type == VDIR) { + vrele(vp); return EPERM; + } if ((err = bfs_file_delete(bfs, ap->a_cnp->cn_nameptr, true)) != 0) DPRINTF("%s: bfs_file_delete failed.\n", __func__); @@ -535,7 +537,6 @@ sysvbfs_remove(void *arg) vrele(vp); else vput(vp); - vput(dvp); if (err == 0) { bnode->removed = 1; Index: sys/fs/tmpfs/tmpfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/tmpfs/tmpfs_vnops.c,v retrieving revision 1.131 diff -p -u -r1.131 tmpfs_vnops.c --- sys/fs/tmpfs/tmpfs_vnops.c 11 Apr 2017 14:25:00 -0000 1.131 +++ sys/fs/tmpfs/tmpfs_vnops.c 16 Apr 2017 17:21:34 -0000 @@ -652,7 +652,7 @@ tmpfs_fsync(void *v) int tmpfs_remove(void *v) { - struct vop_remove_args /* { + struct vop_remove_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -716,12 +716,11 @@ tmpfs_remove(void *v) tmpfs_update(dvp, TMPFS_UPDATE_MTIME | TMPFS_UPDATE_CTIME); error = 0; out: - /* Drop the references and unlock the vnodes. */ - vput(vp); + /* Drop the reference and unlock the node. */ if (dvp == vp) { - vrele(dvp); + vrele(vp); } else { - vput(dvp); + vput(vp); } return error; } @@ -813,7 +812,7 @@ tmpfs_mkdir(void *v) int tmpfs_rmdir(void *v) { - struct vop_rmdir_args /* { + struct vop_rmdir_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -898,8 +897,8 @@ tmpfs_rmdir(void *v) KASSERT(node->tn_size == 0); KASSERT(node->tn_links == 0); out: - /* Release the nodes. */ - vput(dvp); + /* Release the node. */ + KASSERT(dvp != vp); vput(vp); return error; } Index: sys/fs/udf/udf_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/udf/udf_vnops.c,v retrieving revision 1.103 diff -p -u -r1.103 udf_vnops.c --- sys/fs/udf/udf_vnops.c 11 Apr 2017 14:25:00 -0000 1.103 +++ sys/fs/udf/udf_vnops.c 16 Apr 2017 17:21:34 -0000 @@ -1941,7 +1941,7 @@ udf_readlink(void *v) int udf_remove(void *v) { - struct vop_remove_args /* { + struct vop_remove_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -1972,7 +1972,6 @@ udf_remove(void *v) vrele(vp); else vput(vp); - vput(dvp); return error; } @@ -1982,7 +1981,7 @@ udf_remove(void *v) int udf_rmdir(void *v) { - struct vop_rmdir_args /* { + struct vop_rmdir_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -1999,8 +1998,7 @@ udf_rmdir(void *v) /* don't allow '.' to be deleted */ if (dir_node == udf_node) { - vrele(dvp); - vput(vp); + vrele(vp); return EINVAL; } @@ -2017,7 +2015,6 @@ udf_rmdir(void *v) dirhash_put(udf_node->dir_hash); if (!isempty) { - vput(dvp); vput(vp); return ENOTEMPTY; } @@ -2040,8 +2037,7 @@ udf_rmdir(void *v) } DPRINTFIF(NODE, error, ("\tgot error removing dir\n")); - /* unput the nodes and exit */ - vput(dvp); + /* put the node and exit */ vput(vp); return error; Index: sys/fs/union/union_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/union/union_vnops.c,v retrieving revision 1.65 diff -p -u -r1.65 union_vnops.c --- sys/fs/union/union_vnops.c 11 Apr 2017 14:25:00 -0000 1.65 +++ sys/fs/union/union_vnops.c 16 Apr 2017 17:21:34 -0000 @@ -1153,7 +1153,7 @@ union_seek(void *v) int union_remove(void *v) { - struct vop_remove_args /* { + struct vop_remove_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -1170,24 +1170,18 @@ union_remove(void *v) struct vnode *dvp = dun->un_uppervp; struct vnode *vp = un->un_uppervp; - /* - * Account for VOP_REMOVE to vrele dvp and vp. - * Note: VOP_REMOVE will unlock dvp and vp. - */ - vref(dvp); + /* Account for VOP_REMOVE to vrele vp. */ vref(vp); if (union_dowhiteout(un, cnp->cn_cred)) cnp->cn_flags |= DOWHITEOUT; error = VOP_REMOVE(dvp, vp, cnp); if (!error) union_removed_upper(un); - vrele(ap->a_dvp); vrele(ap->a_vp); } else { error = union_mkwhiteout( MOUNTTOUNIONMOUNT(UNIONTOV(dun)->v_mount), dun->un_uppervp, ap->a_cnp, un); - vput(ap->a_dvp); vput(ap->a_vp); } @@ -1417,7 +1411,7 @@ union_mkdir(void *v) int union_rmdir(void *v) { - struct vop_rmdir_args /* { + struct vop_rmdir_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -1432,7 +1426,6 @@ union_rmdir(void *v) error = union_check_rmdir(un, cnp->cn_cred); if (error) { - vput(ap->a_dvp); vput(ap->a_vp); return error; } @@ -1441,24 +1434,18 @@ union_rmdir(void *v) struct vnode *dvp = dun->un_uppervp; struct vnode *vp = un->un_uppervp; - /* - * Account for VOP_RMDIR to vrele dvp and vp. - * Note: VOP_RMDIR will unlock dvp and vp. - */ - vref(dvp); + /* Account for VOP_RMDIR to vrele vp. */ vref(vp); if (union_dowhiteout(un, cnp->cn_cred)) cnp->cn_flags |= DOWHITEOUT; error = VOP_RMDIR(dvp, vp, ap->a_cnp); if (!error) union_removed_upper(un); - vrele(ap->a_dvp); vrele(ap->a_vp); } else { error = union_mkwhiteout( MOUNTTOUNIONMOUNT(UNIONTOV(dun)->v_mount), dun->un_uppervp, ap->a_cnp, un); - vput(ap->a_dvp); vput(ap->a_vp); } Index: sys/fs/unionfs/unionfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/unionfs/unionfs_vnops.c,v retrieving revision 1.10 diff -p -u -r1.10 unionfs_vnops.c --- sys/fs/unionfs/unionfs_vnops.c 11 Apr 2017 14:25:00 -0000 1.10 +++ sys/fs/unionfs/unionfs_vnops.c 16 Apr 2017 17:21:34 -0000 @@ -857,7 +857,7 @@ unionfs_fsync(void *v) static int unionfs_remove(void *v) { - struct vop_remove_args *ap = v; + struct vop_remove_v2_args *ap = v; int error; struct unionfs_node *dunp; struct unionfs_node *unp; @@ -877,8 +877,10 @@ unionfs_remove(void *v) lvp = unp->un_lowervp; cnp = ap->a_cnp; - if (udvp == NULLVP) + if (udvp == NULLVP) { + vput(ap->a_vp); return (EROFS); + } if (uvp != NULLVP) { ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount); @@ -1206,7 +1208,7 @@ unionfs_mkdir(void *v) static int unionfs_rmdir(void *v) { - struct vop_rmdir_args *ap = v; + struct vop_rmdir_v2_args *ap = v; int error; struct unionfs_node *dunp; struct unionfs_node *unp; @@ -1226,8 +1228,10 @@ unionfs_rmdir(void *v) uvp = unp->un_uppervp; lvp = unp->un_lowervp; - if (udvp == NULLVP) + if (udvp == NULLVP) { + vput(ap->a_vp); return (EROFS); + } if (udvp == uvp) return (EOPNOTSUPP); Index: sys/fs/v7fs/v7fs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/v7fs/v7fs_vnops.c,v retrieving revision 1.24 diff -p -u -r1.24 v7fs_vnops.c --- sys/fs/v7fs/v7fs_vnops.c 11 Apr 2017 14:25:00 -0000 1.24 +++ sys/fs/v7fs/v7fs_vnops.c 16 Apr 2017 17:21:35 -0000 @@ -680,7 +680,7 @@ v7fs_fsync(void *v) int v7fs_remove(void *v) { - struct vop_remove_args /* { + struct vop_remove_v2_args /* { struct vnodeop_desc *a_desc; struct vnode * a_dvp; struct vnode * a_vp; @@ -717,7 +717,6 @@ out: vrele(vp); /* v_usecount-- of unlocked vp */ else vput(vp); /* unlock vp and then v_usecount-- */ - vput(dvp); return error; } @@ -865,7 +864,7 @@ v7fs_mkdir(void *v) int v7fs_rmdir(void *v) { - struct vop_rmdir_args /* { + struct vop_rmdir_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -895,7 +894,6 @@ v7fs_rmdir(void *v) uvm_vnp_setsize(dvp, v7fs_inode_filesize(&parent_node->inode)); out: vput(vp); - vput(dvp); return error; } Index: sys/kern/vfs_syscalls.c =================================================================== RCS file: /cvsroot/src/sys/kern/vfs_syscalls.c,v retrieving revision 1.510 diff -p -u -r1.510 vfs_syscalls.c --- sys/kern/vfs_syscalls.c 12 Apr 2017 10:28:39 -0000 1.510 +++ sys/kern/vfs_syscalls.c 16 Apr 2017 17:21:35 -0000 @@ -2696,6 +2696,7 @@ do_sys_unlinkat(struct lwp *l, int fdat, goto abort; } else { error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); + vput(nd.ni_dvp); goto out; } } @@ -2719,6 +2720,7 @@ do_sys_unlinkat(struct lwp *l, int fdat, (void)fileassoc_file_delete(vp); #endif /* FILEASSOC */ error = VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); + vput(nd.ni_dvp); goto out; abort: Index: sys/kern/vnode_if.c =================================================================== RCS file: /cvsroot/src/sys/kern/vnode_if.c,v retrieving revision 1.102 diff -p -u -r1.102 vnode_if.c --- sys/kern/vnode_if.c 16 Apr 2017 17:18:55 -0000 1.102 +++ sys/kern/vnode_if.c 16 Apr 2017 17:21:35 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: vnode_if.c,v 1.102 2017/04/16 17:18:55 riastradh Exp $ */ +/* $NetBSD$ */ /* * Warning: DO NOT EDIT! This file is automatically generated! @@ -40,7 +40,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vnode_if.c,v 1.102 2017/04/16 17:18:55 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD$"); #include <sys/param.h> #include <sys/mount.h> @@ -777,18 +777,18 @@ VOP_SEEK(struct vnode *vp, } const int vop_remove_vp_offsets[] = { - VOPARG_OFFSETOF(struct vop_remove_args,a_dvp), - VOPARG_OFFSETOF(struct vop_remove_args,a_vp), + VOPARG_OFFSETOF(struct vop_remove_v2_args,a_dvp), + VOPARG_OFFSETOF(struct vop_remove_v2_args,a_vp), VDESC_NO_OFFSET }; const struct vnodeop_desc vop_remove_desc = { VOP_REMOVE_DESCOFFSET, "vop_remove", - 0 | VDESC_VP0_WILLPUT | VDESC_VP1_WILLPUT, + 0 | VDESC_VP1_WILLPUT, vop_remove_vp_offsets, VDESC_NO_OFFSET, VDESC_NO_OFFSET, - VOPARG_OFFSETOF(struct vop_remove_args, a_cnp), + VOPARG_OFFSETOF(struct vop_remove_v2_args, a_cnp), }; int VOP_REMOVE(struct vnode *dvp, @@ -797,7 +797,7 @@ VOP_REMOVE(struct vnode *dvp, { int error; bool mpsafe; - struct vop_remove_args a; + struct vop_remove_v2_args a; a.a_desc = VDESC(vop_remove); a.a_dvp = dvp; a.a_vp = vp; @@ -926,18 +926,18 @@ VOP_MKDIR(struct vnode *dvp, } const int vop_rmdir_vp_offsets[] = { - VOPARG_OFFSETOF(struct vop_rmdir_args,a_dvp), - VOPARG_OFFSETOF(struct vop_rmdir_args,a_vp), + VOPARG_OFFSETOF(struct vop_rmdir_v2_args,a_dvp), + VOPARG_OFFSETOF(struct vop_rmdir_v2_args,a_vp), VDESC_NO_OFFSET }; const struct vnodeop_desc vop_rmdir_desc = { VOP_RMDIR_DESCOFFSET, "vop_rmdir", - 0 | VDESC_VP0_WILLPUT | VDESC_VP1_WILLPUT, + 0 | VDESC_VP1_WILLPUT, vop_rmdir_vp_offsets, VDESC_NO_OFFSET, VDESC_NO_OFFSET, - VOPARG_OFFSETOF(struct vop_rmdir_args, a_cnp), + VOPARG_OFFSETOF(struct vop_rmdir_v2_args, a_cnp), }; int VOP_RMDIR(struct vnode *dvp, @@ -946,7 +946,7 @@ VOP_RMDIR(struct vnode *dvp, { int error; bool mpsafe; - struct vop_rmdir_args a; + struct vop_rmdir_v2_args a; a.a_desc = VDESC(vop_rmdir); a.a_dvp = dvp; a.a_vp = vp; Index: sys/kern/vnode_if.src =================================================================== RCS file: /cvsroot/src/sys/kern/vnode_if.src,v retrieving revision 1.73 diff -p -u -r1.73 vnode_if.src --- sys/kern/vnode_if.src 16 Apr 2017 16:48:08 -0000 1.73 +++ sys/kern/vnode_if.src 16 Apr 2017 17:21:35 -0000 @@ -269,13 +269,14 @@ vop_seek { }; # -#% remove dvp L U U +#% remove dvp L L L #% remove vp L U U # #! remove cnp DELETE, LOCKPARENT | LOCKLEAF # vop_remove { - IN LOCKED=YES WILLPUT struct vnode *dvp; + VERSION 2 + IN LOCKED=YES struct vnode *dvp; IN LOCKED=YES WILLPUT struct vnode *vp; IN struct componentname *cnp; }; @@ -326,13 +327,14 @@ vop_mkdir { }; # -#% rmdir dvp L U U +#% rmdir dvp L L L #% rmdir vp L U U # #! rmdir cnp DELETE, LOCKPARENT | LOCKLEAF # vop_rmdir { - IN LOCKED=YES WILLPUT struct vnode *dvp; + VERSION 2 + IN LOCKED=YES struct vnode *dvp; IN LOCKED=YES WILLPUT struct vnode *vp; IN struct componentname *cnp; }; Index: sys/miscfs/deadfs/dead_vnops.c =================================================================== RCS file: /cvsroot/src/sys/miscfs/deadfs/dead_vnops.c,v retrieving revision 1.60 diff -p -u -r1.60 dead_vnops.c --- sys/miscfs/deadfs/dead_vnops.c 11 Apr 2017 14:25:00 -0000 1.60 +++ sys/miscfs/deadfs/dead_vnops.c 16 Apr 2017 17:21:35 -0000 @@ -234,13 +234,12 @@ dead_poll(void *v) int dead_remove(void *v) { - struct vop_remove_args /* { + struct vop_remove_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; } */ *ap = v; - vput(ap->a_dvp); vput(ap->a_vp); return EIO; @@ -286,13 +285,12 @@ dead_rename(void *v) int dead_rmdir(void *v) { - struct vop_rmdir_args /* { + struct vop_rmdir_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; } */ *ap = v; - vput(ap->a_dvp); vput(ap->a_vp); return EIO; Index: sys/miscfs/genfs/layer_vnops.c =================================================================== RCS file: /cvsroot/src/sys/miscfs/genfs/layer_vnops.c,v retrieving revision 1.62 diff -p -u -r1.62 layer_vnops.c --- sys/miscfs/genfs/layer_vnops.c 11 Apr 2017 14:25:00 -0000 1.62 +++ sys/miscfs/genfs/layer_vnops.c 16 Apr 2017 17:21:36 -0000 @@ -609,8 +609,8 @@ layer_inactive(void *v) int layer_remove(void *v) { - struct vop_remove_args /* { - struct vonde *a_dvp; + struct vop_remove_v2_args /* { + struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; } */ *ap = v; @@ -660,7 +660,7 @@ layer_rename(void *v) int layer_rmdir(void *v) { - struct vop_rmdir_args /* { + struct vop_rmdir_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; Index: sys/nfs/nfs_serv.c =================================================================== RCS file: /cvsroot/src/sys/nfs/nfs_serv.c,v retrieving revision 1.172 diff -p -u -r1.172 nfs_serv.c --- sys/nfs/nfs_serv.c 21 Apr 2015 03:19:03 -0000 1.172 +++ sys/nfs/nfs_serv.c 16 Apr 2017 17:21:36 -0000 @@ -1859,6 +1859,7 @@ out: nqsrv_getl(nd.ni_dvp, ND_WRITE); nqsrv_getl(vp, ND_WRITE); error = VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); + vput(nd.ni_dvp); } else { VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); if (nd.ni_dvp == vp) @@ -2601,6 +2602,7 @@ out: nqsrv_getl(nd.ni_dvp, ND_WRITE); nqsrv_getl(vp, ND_WRITE); error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); + vput(nd.ni_dvp); } else { VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); if (nd.ni_dvp == nd.ni_vp) Index: sys/nfs/nfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/nfs/nfs_vnops.c,v retrieving revision 1.309 diff -p -u -r1.309 nfs_vnops.c --- sys/nfs/nfs_vnops.c 19 Jan 2016 10:56:59 -0000 1.309 +++ sys/nfs/nfs_vnops.c 16 Apr 2017 17:21:37 -0000 @@ -1738,7 +1738,7 @@ again: int nfs_remove(void *v) { - struct vop_remove_args /* { + struct vop_remove_v2_args /* { struct vnodeop_desc *a_desc; struct vnode * a_dvp; struct vnode * a_vp; @@ -1790,7 +1790,6 @@ nfs_remove(void *v) vrele(vp); else vput(vp); - vput(dvp); return (error); } @@ -2265,7 +2264,7 @@ nfs_mkdir(void *v) int nfs_rmdir(void *v) { - struct vop_rmdir_args /* { + struct vop_rmdir_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -2288,8 +2287,7 @@ nfs_rmdir(void *v) struct nfsnode *dnp; if (dvp == vp) { - vrele(dvp); - vput(dvp); + vrele(vp); return (EINVAL); } nfsstats.rpccnt[NFSPROC_RMDIR]++; @@ -2311,7 +2309,6 @@ nfs_rmdir(void *v) VN_KNOTE(vp, NOTE_DELETE); cache_purge(vp); vput(vp); - vput(dvp); /* * Kludge: Map ENOENT => 0 assuming that you have a reply to a retry. */ Index: sys/rump/include/rump/rumpvnode_if.h =================================================================== RCS file: /cvsroot/src/sys/rump/include/rump/rumpvnode_if.h,v retrieving revision 1.26 diff -p -u -r1.26 rumpvnode_if.h --- sys/rump/include/rump/rumpvnode_if.h 16 Apr 2017 17:18:55 -0000 1.26 +++ sys/rump/include/rump/rumpvnode_if.h 16 Apr 2017 17:21:37 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: rumpvnode_if.h,v 1.26 2017/04/16 17:18:55 riastradh Exp $ */ +/* $NetBSD$ */ /* * Warning: DO NOT EDIT! This file is automatically generated! Index: sys/rump/librump/rumpvfs/rumpfs.c =================================================================== RCS file: /cvsroot/src/sys/rump/librump/rumpvfs/rumpfs.c,v retrieving revision 1.146 diff -p -u -r1.146 rumpfs.c --- sys/rump/librump/rumpvfs/rumpfs.c 11 Apr 2017 14:25:01 -0000 1.146 +++ sys/rump/librump/rumpvfs/rumpfs.c 16 Apr 2017 17:21:37 -0000 @@ -983,7 +983,7 @@ rump_vop_mkdir(void *v) static int rump_vop_rmdir(void *v) { - struct vop_rmdir_args /* { + struct vop_rmdir_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -1015,16 +1015,14 @@ rump_vop_rmdir(void *v) rn->rn_va.va_nlink = 0; out: - vput(dvp); vput(vp); - return rv; } static int rump_vop_remove(void *v) { - struct vop_remove_args /* { + struct vop_remove_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -1043,9 +1041,7 @@ rump_vop_remove(void *v) rn->rn_flags |= RUMPNODE_CANRECLAIM; rn->rn_va.va_nlink = 0; - vput(dvp); vput(vp); - return rv; } Index: sys/rump/librump/rumpvfs/rumpvnode_if.c =================================================================== RCS file: /cvsroot/src/sys/rump/librump/rumpvfs/rumpvnode_if.c,v retrieving revision 1.26 diff -p -u -r1.26 rumpvnode_if.c --- sys/rump/librump/rumpvfs/rumpvnode_if.c 16 Apr 2017 17:18:55 -0000 1.26 +++ sys/rump/librump/rumpvfs/rumpvnode_if.c 16 Apr 2017 17:21:37 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: rumpvnode_if.c,v 1.26 2017/04/16 17:18:55 riastradh Exp $ */ +/* $NetBSD$ */ /* * Warning: DO NOT EDIT! This file is automatically generated! @@ -40,7 +40,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rumpvnode_if.c,v 1.26 2017/04/16 17:18:55 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD$"); #include <sys/param.h> #include <sys/mount.h> Index: sys/sys/vnode_if.h =================================================================== RCS file: /cvsroot/src/sys/sys/vnode_if.h,v retrieving revision 1.97 diff -p -u -r1.97 vnode_if.h --- sys/sys/vnode_if.h 16 Apr 2017 17:18:54 -0000 1.97 +++ sys/sys/vnode_if.h 16 Apr 2017 17:21:37 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: vnode_if.h,v 1.97 2017/04/16 17:18:54 riastradh Exp $ */ +/* $NetBSD$ */ /* * Warning: DO NOT EDIT! This file is automatically generated! @@ -270,7 +270,7 @@ extern const struct vnodeop_desc vop_see int VOP_SEEK(struct vnode *, off_t, off_t, kauth_cred_t); #define VOP_REMOVE_DESCOFFSET 22 -struct vop_remove_args { +struct vop_remove_v2_args { const struct vnodeop_desc *a_desc; struct vnode *a_dvp; struct vnode *a_vp; @@ -316,7 +316,7 @@ int VOP_MKDIR(struct vnode *, struct vno struct vattr *); #define VOP_RMDIR_DESCOFFSET 26 -struct vop_rmdir_args { +struct vop_rmdir_v2_args { const struct vnodeop_desc *a_desc; struct vnode *a_dvp; struct vnode *a_vp; Index: sys/ufs/chfs/chfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/ufs/chfs/chfs_vnops.c,v retrieving revision 1.31 diff -p -u -r1.31 chfs_vnops.c --- sys/ufs/chfs/chfs_vnops.c 11 Apr 2017 14:25:01 -0000 1.31 +++ sys/ufs/chfs/chfs_vnops.c 16 Apr 2017 17:21:38 -0000 @@ -1032,9 +1032,9 @@ chfs_fsync(void *v) int chfs_remove(void *v) { - struct vnode *dvp = ((struct vop_remove_args *) v)->a_dvp; - struct vnode *vp = ((struct vop_remove_args *) v)->a_vp; - struct componentname *cnp = (((struct vop_remove_args *) v)->a_cnp); + struct vnode *dvp = ((struct vop_remove_v2_args *) v)->a_dvp; + struct vnode *vp = ((struct vop_remove_v2_args *) v)->a_vp; + struct componentname *cnp = (((struct vop_remove_v2_args *) v)->a_cnp); dbg("remove\n"); KASSERT(VOP_ISLOCKED(dvp)); @@ -1056,7 +1056,6 @@ chfs_remove(void *v) parent, cnp->cn_nameptr, cnp->cn_namelen); out: - vput(dvp); vput(vp); return error; @@ -1195,9 +1194,9 @@ chfs_mkdir(void *v) int chfs_rmdir(void *v) { - struct vnode *dvp = ((struct vop_rmdir_args *) v)->a_dvp; - struct vnode *vp = ((struct vop_rmdir_args *) v)->a_vp; - struct componentname *cnp = ((struct vop_rmdir_args *) v)->a_cnp; + struct vnode *dvp = ((struct vop_rmdir_v2_args *) v)->a_dvp; + struct vnode *vp = ((struct vop_rmdir_v2_args *) v)->a_vp; + struct componentname *cnp = ((struct vop_rmdir_v2_args *) v)->a_cnp; dbg("rmdir()\n"); KASSERT(VOP_ISLOCKED(dvp)); @@ -1226,7 +1225,6 @@ chfs_rmdir(void *v) parent, cnp->cn_nameptr, cnp->cn_namelen); out: - vput(dvp); vput(vp); return error; Index: sys/ufs/ext2fs/ext2fs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_vnops.c,v retrieving revision 1.125 diff -p -u -r1.125 ext2fs_vnops.c --- sys/ufs/ext2fs/ext2fs_vnops.c 15 Aug 2016 18:38:10 -0000 1.125 +++ sys/ufs/ext2fs/ext2fs_vnops.c 16 Apr 2017 17:21:38 -0000 @@ -556,7 +556,7 @@ ext2fs_chown(struct vnode *vp, uid_t uid int ext2fs_remove(void *v) { - struct vop_remove_args /* { + struct vop_remove_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -590,7 +590,6 @@ ext2fs_remove(void *v) vrele(vp); else vput(vp); - vput(dvp); return error; } @@ -787,7 +786,7 @@ out: int ext2fs_rmdir(void *v) { - struct vop_rmdir_args /* { + struct vop_rmdir_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -810,8 +809,7 @@ ext2fs_rmdir(void *v) * No rmdir "." please. */ if (dp == ip) { - vrele(dvp); - vput(vp); + vrele(vp); return EINVAL; } /* @@ -845,8 +843,6 @@ ext2fs_rmdir(void *v) dp->i_flag |= IN_CHANGE; VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK); cache_purge(dvp); - vput(dvp); - dvp = NULL; /* * Truncate inode. The only stuff left * in the directory is "." and "..". The @@ -863,8 +859,6 @@ ext2fs_rmdir(void *v) cache_purge(ITOV(ip)); out: VN_KNOTE(vp, NOTE_DELETE); - if (dvp) - vput(dvp); vput(vp); return error; } Index: sys/ufs/lfs/lfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/ufs/lfs/lfs_vnops.c,v retrieving revision 1.313 diff -p -u -r1.313 lfs_vnops.c --- sys/ufs/lfs/lfs_vnops.c 11 Apr 2017 14:25:01 -0000 1.313 +++ sys/ufs/lfs/lfs_vnops.c 16 Apr 2017 17:21:38 -0000 @@ -1083,7 +1083,7 @@ out: int lfs_remove(void *v) { - struct vop_remove_args /* { + struct vop_remove_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -1104,7 +1104,6 @@ lfs_remove(void *v) vrele(vp); else vput(vp); - vput(dvp); return error; } error = ulfs_remove(ap); @@ -1127,7 +1126,7 @@ lfs_remove(void *v) int lfs_rmdir(void *v) { - struct vop_rmdir_args /* { + struct vop_rmdir_v2_args /* { struct vnodeop_desc *a_desc; struct vnode *a_dvp; struct vnode *a_vp; @@ -1145,10 +1144,9 @@ lfs_rmdir(void *v) ip = VTOI(vp); if ((error = lfs_set_dirop(ap->a_dvp, ap->a_vp)) != 0) { if (ap->a_dvp == vp) - vrele(ap->a_dvp); + vrele(vp); else - vput(ap->a_dvp); - vput(vp); + vput(vp); return error; } error = ulfs_rmdir(ap); Index: sys/ufs/lfs/ulfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/ufs/lfs/ulfs_vnops.c,v retrieving revision 1.47 diff -p -u -r1.47 ulfs_vnops.c --- sys/ufs/lfs/ulfs_vnops.c 11 Apr 2017 05:48:04 -0000 1.47 +++ sys/ufs/lfs/ulfs_vnops.c 16 Apr 2017 17:21:38 -0000 @@ -500,7 +500,7 @@ ulfs_chown(struct vnode *vp, uid_t uid, int ulfs_remove(void *v) { - struct vop_remove_args /* { + struct vop_remove_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -536,7 +536,6 @@ ulfs_remove(void *v) vrele(vp); else vput(vp); - vput(dvp); return (error); } @@ -667,7 +666,7 @@ ulfs_whiteout(void *v) int ulfs_rmdir(void *v) { - struct vop_rmdir_args /* { + struct vop_rmdir_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -697,10 +696,9 @@ ulfs_rmdir(void *v) */ if (dp == ip || vp->v_mountedhere != NULL) { if (dp == ip) - vrele(dvp); + vrele(vp); else - vput(dvp); - vput(vp); + vput(vp); return (EINVAL); } @@ -752,7 +750,6 @@ ulfs_rmdir(void *v) out: VN_KNOTE(vp, NOTE_DELETE); vput(vp); - vput(dvp); return (error); } Index: sys/ufs/ufs/ufs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ufs/ufs_vnops.c,v retrieving revision 1.236 diff -p -u -r1.236 ufs_vnops.c --- sys/ufs/ufs/ufs_vnops.c 18 Mar 2017 05:39:06 -0000 1.236 +++ sys/ufs/ufs/ufs_vnops.c 16 Apr 2017 17:21:38 -0000 @@ -714,7 +714,7 @@ ufs_chown(struct vnode *vp, uid_t uid, g int ufs_remove(void *v) { - struct vop_remove_args /* { + struct vop_remove_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -752,7 +752,6 @@ ufs_remove(void *v) vrele(vp); else vput(vp); - vput(dvp); return (error); } @@ -1047,7 +1046,7 @@ ufs_mkdir(void *v) int ufs_rmdir(void *v) { - struct vop_rmdir_args /* { + struct vop_rmdir_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -1073,10 +1072,9 @@ ufs_rmdir(void *v) */ if (dp == ip || vp->v_mountedhere != NULL) { if (dp == ip) - vrele(dvp); + vrele(vp); else - vput(dvp); - vput(vp); + vput(vp); return (EINVAL); } @@ -1138,7 +1136,6 @@ ufs_rmdir(void *v) out: VN_KNOTE(vp, NOTE_DELETE); vput(vp); - vput(dvp); return (error); }