From 2d5bba3ae320422ed721d160fd59624ba449b6ad Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 15 Jun 2016 15:55:14 +0000 Subject: [PATCH] Another follow-up to r291460. Only access vp->v_rdev for VCHR vnodes in devfs_reclaim(). Reported and tested by: pho Sponsored by: The FreeBSD Foundation Approved by: re (gjb) MFC after: 1 week --- sys/fs/devfs/devfs_vnops.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c index f8efd10eb6cb..7cc0f9ee0b11 100644 --- a/sys/fs/devfs/devfs_vnops.c +++ b/sys/fs/devfs/devfs_vnops.c @@ -1360,10 +1360,10 @@ devfs_readlink(struct vop_readlink_args *ap) static int devfs_reclaim(struct vop_reclaim_args *ap) { - struct vnode *vp = ap->a_vp; + struct vnode *vp; struct devfs_dirent *de; - struct cdev *dev; + vp = ap->a_vp; mtx_lock(&devfs_de_interlock); de = vp->v_data; if (de != NULL) { @@ -1371,24 +1371,31 @@ devfs_reclaim(struct vop_reclaim_args *ap) vp->v_data = NULL; } mtx_unlock(&devfs_de_interlock); - vnode_destroy_vobject(vp); + return (0); +} + +static int +devfs_reclaim_vchr(struct vop_reclaim_args *ap) +{ + struct vnode *vp; + struct cdev *dev; + + vp = ap->a_vp; + MPASS(vp->v_type == VCHR); + + devfs_reclaim(ap); VI_LOCK(vp); dev_lock(); dev = vp->v_rdev; vp->v_rdev = NULL; - - if (dev == NULL) { - dev_unlock(); - VI_UNLOCK(vp); - return (0); - } - - dev->si_usecount -= vp->v_usecount; + if (dev != NULL) + dev->si_usecount -= vp->v_usecount; dev_unlock(); VI_UNLOCK(vp); - dev_rel(dev); + if (dev != NULL) + dev_rel(dev); return (0); } @@ -1898,7 +1905,7 @@ static struct vop_vector devfs_specops = { .vop_readdir = VOP_PANIC, .vop_readlink = VOP_PANIC, .vop_reallocblks = VOP_PANIC, - .vop_reclaim = devfs_reclaim, + .vop_reclaim = devfs_reclaim_vchr, .vop_remove = devfs_remove, .vop_rename = VOP_PANIC, .vop_revoke = devfs_revoke,