Fix a LOR relating to freeing cdevs.

This commit is contained in:
Poul-Henning Kamp 2004-10-01 06:33:39 +00:00
parent 000d5e07e0
commit ba2851254f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=136014
3 changed files with 19 additions and 11 deletions

View File

@ -98,17 +98,31 @@ dev_ref(struct cdev *dev)
}
void
dev_rel(struct cdev *dev)
dev_rel(struct vnode *vp)
{
struct cdev *dev;
int flag;
dev = vp->v_rdev;
mtx_assert(&devmtx, MA_NOTOWNED);
dev_lock();
SLIST_REMOVE(&dev->si_hlist, vp, vnode, v_specnext);
dev->si_usecount -= vp->v_usecount;
vp->v_rdev = NULL;
dev->si_refcount--;
KASSERT(dev->si_refcount >= 0,
("dev_rel(%s) gave negative count", devtoname(dev)));
flag = 0;
if (dev->si_devsw == NULL && dev->si_refcount == 0) {
LIST_REMOVE(dev, si_list);
freedev(dev);
flag = 1;
}
dev_unlock();
if (flag)
freedev(dev);
return;
}
struct cdevsw *
dev_refthread(struct cdev *dev)
{

View File

@ -2698,14 +2698,8 @@ vgonel(vp, td)
* if it is on one.
*/
VI_LOCK(vp);
if (vp->v_type == VCHR && vp->v_rdev != NULL) {
dev_lock();
SLIST_REMOVE(&vp->v_rdev->si_hlist, vp, vnode, v_specnext);
vp->v_rdev->si_usecount -= vp->v_usecount;
dev_rel(vp->v_rdev);
vp->v_rdev = NULL;
dev_unlock();
}
if (vp->v_type == VCHR && vp->v_rdev != NULL)
dev_rel(vp);
/*
* If it is on the freelist and not already at the head,

View File

@ -266,7 +266,7 @@ const char *devtoname(struct cdev *_dev);
int dev_named(struct cdev *_pdev, const char *_name);
void dev_depends(struct cdev *_pdev, struct cdev *_cdev);
void dev_ref(struct cdev *dev);
void dev_rel(struct cdev *dev);
void dev_rel(struct vnode *vp);
void dev_strategy(struct buf *bp);
struct cdev *makebdev(int _maj, int _min);
struct cdev *make_dev(struct cdevsw *_devsw, int _minor, uid_t _uid, gid_t _gid,