diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c --- a/sys/fs/devfs/devfs_vnops.c +++ b/sys/fs/devfs/devfs_vnops.c @@ -507,18 +507,6 @@ return (not_found); } -static void -devfs_insmntque_dtr(struct vnode *vp, struct devfs_dirent *de) -{ - - mtx_lock(&devfs_de_interlock); - vp->v_data = NULL; - de->de_vnode = NULL; - mtx_unlock(&devfs_de_interlock); - vgone(vp); - vput(vp); -} - /* * devfs_allocv shall be entered with dmp->dm_lock held, and it drops * it on return. @@ -615,9 +603,14 @@ vp->v_data = de; de->de_vnode = vp; mtx_unlock(&devfs_de_interlock); - error = insmntque1(vp, mp, NULL, NULL); + error = insmntque1(vp, mp); if (error != 0) { - devfs_insmntque_dtr(vp, de); + mtx_lock(&devfs_de_interlock); + vp->v_data = NULL; + de->de_vnode = NULL; + mtx_unlock(&devfs_de_interlock); + vgone(vp); + vput(vp); (void) devfs_allocv_drop_refs(1, dmp, de); return (error); } diff --git a/sys/fs/fdescfs/fdesc_vnops.c b/sys/fs/fdescfs/fdesc_vnops.c --- a/sys/fs/fdescfs/fdesc_vnops.c +++ b/sys/fs/fdescfs/fdesc_vnops.c @@ -191,7 +191,7 @@ fd->fd_ix = ix; if (ftype == Fdesc && fmp->flags & FMNT_LINRDLNKF) vp->v_vflag |= VV_READLINK; - error = insmntque1(vp, mp, NULL, NULL); + error = insmntque1(vp, mp); if (error != 0) { vgone(vp); vput(vp); diff --git a/sys/fs/nullfs/null_subr.c b/sys/fs/nullfs/null_subr.c --- a/sys/fs/nullfs/null_subr.c +++ b/sys/fs/nullfs/null_subr.c @@ -235,7 +235,7 @@ vp->v_type = lowervp->v_type; vp->v_data = xp; vp->v_vnlock = lowervp->v_vnlock; - error = insmntque1(vp, mp, NULL, NULL); + error = insmntque1(vp, mp); if (error != 0) { vput(lowervp); null_destroy_proto(vp, xp); diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c --- a/sys/fs/tmpfs/tmpfs_subr.c +++ b/sys/fs/tmpfs/tmpfs_subr.c @@ -822,21 +822,6 @@ } } -/* - * Need to clear v_object for insmntque failure. - */ -static void -tmpfs_insmntque_dtr(struct vnode *vp) -{ - - tmpfs_destroy_vobject(vp, vp->v_object); - vp->v_object = NULL; - vp->v_data = NULL; - vp->v_op = &dead_vnodeops; - vgone(vp); - vput(vp); -} - /* * Allocates a new vnode for the node node or returns a new reference to * an existing one if the node had already a vnode referencing it. The @@ -983,9 +968,15 @@ if (vp->v_type != VFIFO) VN_LOCK_ASHARE(vp); - error = insmntque1(vp, mp, NULL, NULL); + error = insmntque1(vp, mp); if (error != 0) { - tmpfs_insmntque_dtr(vp); + /* Need to clear v_object for insmntque failure. */ + tmpfs_destroy_vobject(vp, vp->v_object); + vp->v_object = NULL; + vp->v_data = NULL; + vp->v_op = &dead_vnodeops; + vgone(vp); + vput(vp); vp = NULL; } diff --git a/sys/fs/unionfs/union_subr.c b/sys/fs/unionfs/union_subr.c --- a/sys/fs/unionfs/union_subr.c +++ b/sys/fs/unionfs/union_subr.c @@ -389,7 +389,7 @@ ("%s: NULL dvp for non-root vp %p", __func__, vp)); vn_lock_pair(lowervp, false, uppervp, false); - error = insmntque1(vp, mp, NULL, NULL); + error = insmntque1(vp, mp); if (error != 0) { unionfs_nodeget_cleanup(vp, unp); return (error); diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -1934,22 +1934,8 @@ MNT_IUNLOCK(mp); } -static void -insmntque_stddtr(struct vnode *vp, void *dtr_arg) -{ - - vp->v_data = NULL; - vp->v_op = &dead_vnodeops; - vgone(vp); - vput(vp); -} - -/* - * Insert into list of vnodes for the new mount point, if available. - */ -int -insmntque1(struct vnode *vp, struct mount *mp, - void (*dtr)(struct vnode *, void *), void *dtr_arg) +static int +insmntque1_int(struct vnode *vp, struct mount *mp, bool dtr) { KASSERT(vp->v_mount == NULL, @@ -1974,8 +1960,12 @@ (vp->v_vflag & VV_FORCEINSMQ) == 0) { VI_UNLOCK(vp); MNT_IUNLOCK(mp); - if (dtr != NULL) - dtr(vp, dtr_arg); + if (dtr) { + vp->v_data = NULL; + vp->v_op = &dead_vnodeops; + vgone(vp); + vput(vp); + } return (EBUSY); } vp->v_mount = mp; @@ -1989,11 +1979,21 @@ return (0); } +/* + * Insert into list of vnodes for the new mount point, if available. + * insmntque() reclaims the vnode on insertion failure, insmntque1() + * leaves handling of the vnode to the caller. + */ int insmntque(struct vnode *vp, struct mount *mp) { + return (insmntque1_int(vp, mp, true)); +} - return (insmntque1(vp, mp, insmntque_stddtr, NULL)); +int +insmntque1(struct vnode *vp, struct mount *mp) +{ + return (insmntque1_int(vp, mp, false)); } /* diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -689,9 +689,8 @@ struct vnode **vpp); void getnewvnode_reserve(void); void getnewvnode_drop_reserve(void); -int insmntque1(struct vnode *vp, struct mount *mp, - void (*dtr)(struct vnode *, void *), void *dtr_arg); int insmntque(struct vnode *vp, struct mount *mp); +int insmntque1(struct vnode *vp, struct mount *mp); u_quad_t init_va_filerev(void); int speedup_syncer(void); int vn_vptocnp(struct vnode **vp, char *buf, size_t *buflen);