aboutsummaryrefslogtreecommitdiff
path: root/sys/fs
diff options
context:
space:
mode:
authorPoul-Henning Kamp <phk@FreeBSD.org>2004-02-21 21:57:26 +0000
committerPoul-Henning Kamp <phk@FreeBSD.org>2004-02-21 21:57:26 +0000
commitcd690b60dea90adc4ad499c6be171cd2b369d378 (patch)
treed076858b5e5f94786b0a38e000ef6c98a01e7a00 /sys/fs
parent816d62bbb948206731bba23727cd4746ffd987a0 (diff)
Notes
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/specfs/spec_vnops.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/sys/fs/specfs/spec_vnops.c b/sys/fs/specfs/spec_vnops.c
index 4682b5df6190..ab9ce7f5a5b4 100644
--- a/sys/fs/specfs/spec_vnops.c
+++ b/sys/fs/specfs/spec_vnops.c
@@ -140,7 +140,6 @@ spec_open(ap)
dev_t dev = vp->v_rdev;
int error;
struct cdevsw *dsw;
- const char *cp;
if (vp->v_type == VBLK)
return (ENXIO);
@@ -194,6 +193,8 @@ spec_open(ap)
vp->v_vflag |= VV_ISTTY;
VOP_UNLOCK(vp, 0, td);
+ dev_ref(dev);
+ cdevsw_ref(dsw);
if(!(dsw->d_flags & D_NEEDGIANT)) {
DROP_GIANT();
if (dsw->d_fdopen != NULL)
@@ -205,6 +206,9 @@ spec_open(ap)
error = dsw->d_fdopen(dev, ap->a_mode, td, ap->a_fdidx);
else
error = dsw->d_open(dev, ap->a_mode, S_IFCHR, td);
+ cdevsw_rel(dsw);
+ if (error != 0)
+ dev_rel(dev);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
if (error)
@@ -225,14 +229,6 @@ spec_open(ap)
if (!dev->si_bsize_phys)
dev->si_bsize_phys = DEV_BSIZE;
}
- if ((dsw->d_flags & D_DISK) == 0) {
- cp = devtoname(dev);
- if (*cp == '#' && (dsw->d_flags & D_NAGGED) == 0) {
- printf("WARNING: driver %s should register devices with make_dev() (dev_t = \"%s\")\n",
- dsw->d_name, cp);
- dsw->d_flags |= D_NAGGED;
- }
- }
return (error);
}
@@ -267,12 +263,16 @@ spec_read(ap)
dsw = devsw(dev);
VOP_UNLOCK(vp, 0, td);
+ KASSERT(dev->si_refcount > 0,
+ ("specread() on un-referenced dev_t (%s)", devtoname(dev)));
+ cdevsw_ref(dsw);
if (!(dsw->d_flags & D_NEEDGIANT)) {
DROP_GIANT();
error = dsw->d_read(dev, uio, ap->a_ioflag);
PICKUP_GIANT();
} else
error = dsw->d_read(dev, uio, ap->a_ioflag);
+ cdevsw_rel(dsw);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
if (uio->uio_resid != resid || (error == 0 && resid != 0))
vfs_timestamp(&dev->si_atime);
@@ -307,12 +307,16 @@ spec_write(ap)
resid = uio->uio_resid;
VOP_UNLOCK(vp, 0, td);
+ KASSERT(dev->si_refcount > 0,
+ ("spec_write() on un-referenced dev_t (%s)", devtoname(dev)));
+ cdevsw_ref(dsw);
if (!(dsw->d_flags & D_NEEDGIANT)) {
DROP_GIANT();
error = dsw->d_write(dev, uio, ap->a_ioflag);
PICKUP_GIANT();
} else
error = dsw->d_write(dev, uio, ap->a_ioflag);
+ cdevsw_rel(dsw);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
if (uio->uio_resid != resid || (error == 0 && resid != 0)) {
vfs_timestamp(&dev->si_ctime);
@@ -342,6 +346,9 @@ spec_ioctl(ap)
dev = ap->a_vp->v_rdev;
dsw = devsw(dev);
+ KASSERT(dev->si_refcount > 0,
+ ("spec_ioctl() on un-referenced dev_t (%s)", devtoname(dev)));
+ cdevsw_ref(dsw);
if (!(dsw->d_flags & D_NEEDGIANT)) {
DROP_GIANT();
error = dsw->d_ioctl(dev, ap->a_command,
@@ -350,6 +357,7 @@ spec_ioctl(ap)
} else
error = dsw->d_ioctl(dev, ap->a_command,
ap->a_data, ap->a_fflag, ap->a_td);
+ cdevsw_rel(dsw);
if (error == ENOIOCTL)
error = ENOTTY;
return (error);
@@ -371,12 +379,16 @@ spec_poll(ap)
dev = ap->a_vp->v_rdev;
dsw = devsw(dev);
+ KASSERT(dev->si_refcount > 0,
+ ("spec_poll() on un-referenced dev_t (%s)", devtoname(dev)));
+ cdevsw_ref(dsw);
if (!(dsw->d_flags & D_NEEDGIANT)) {
DROP_GIANT();
error = dsw->d_poll(dev, ap->a_events, ap->a_td);
PICKUP_GIANT();
} else
error = dsw->d_poll(dev, ap->a_events, ap->a_td);
+ cdevsw_rel(dsw);
return(error);
}
@@ -394,12 +406,16 @@ spec_kqfilter(ap)
dev = ap->a_vp->v_rdev;
dsw = devsw(dev);
+ KASSERT(dev->si_refcount > 0,
+ ("spec_kqfilter() on un-referenced dev_t (%s)", devtoname(dev)));
+ cdevsw_ref(dsw);
if (!(dsw->d_flags & D_NEEDGIANT)) {
DROP_GIANT();
error = dsw->d_kqfilter(dev, ap->a_kn);
PICKUP_GIANT();
} else
error = dsw->d_kqfilter(dev, ap->a_kn);
+ cdevsw_rel(dsw);
return (error);
}
@@ -631,12 +647,17 @@ spec_close(ap)
return (0);
}
VI_UNLOCK(vp);
+ KASSERT(dev->si_refcount > 0,
+ ("spec_close() on un-referenced dev_t (%s)", devtoname(dev)));
+ cdevsw_ref(dsw);
if (!(dsw->d_flags & D_NEEDGIANT)) {
DROP_GIANT();
error = dsw->d_close(dev, ap->a_fflag, S_IFCHR, td);
PICKUP_GIANT();
} else
error = dsw->d_close(dev, ap->a_fflag, S_IFCHR, td);
+ cdevsw_rel(dsw);
+ dev_rel(dev);
return (error);
}