diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c index 598bcb9..c697d8d 100644 --- a/sys/fs/devfs/devfs_vnops.c +++ b/sys/fs/devfs/devfs_vnops.c @@ -188,7 +188,6 @@ devfs_allocv(struct devfs_dirent *de, struct mount *mp, struct vnode **vpp, stru sx_xunlock(&dmp->dm_lock); return (ENOENT); } - loop: DEVFS_DE_HOLD(de); DEVFS_DMP_HOLD(dmp); mtx_lock(&devfs_de_interlock); @@ -204,8 +203,10 @@ devfs_allocv(struct devfs_dirent *de, struct mount *mp, struct vnode **vpp, stru vput(vp); return (ENOENT); } - else if (error) - goto loop; + else if (error) { + sx_xunlock(&dmp->dm_lock); + return (error); + } sx_xunlock(&dmp->dm_lock); *vpp = vp; return (0); diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c index ffce8ad..5c4d4b1 100644 --- a/sys/kern/kern_conf.c +++ b/sys/kern/kern_conf.c @@ -225,6 +225,8 @@ dev_relthread(struct cdev *dev) mtx_assert(&devmtx, MA_NOTOWNED); dev_lock(); + KASSERT(dev->si_threadcount > 0, + ("%s threadcount is wrong", dev->si_name)); dev->si_threadcount--; dev_unlock(); } diff --git a/sys/kern/tty.c b/sys/kern/tty.c index e952832..168a814 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -269,11 +269,12 @@ tty_gettp(struct cdev *dev) struct cdevsw *csw; csw = dev_refthread(dev); - KASSERT(csw != NULL, ("No cdevsw in ttycode (%s)", devtoname(dev))); + if (csw == NULL) + return (NULL); KASSERT(csw->d_flags & D_TTY, ("non D_TTY (%s) in tty code", devtoname(dev))); - dev_relthread(dev); tp = dev->si_tty; + dev_relthread(dev); KASSERT(tp != NULL, ("no tty pointer on (%s) in tty code", devtoname(dev))); return (tp); @@ -1324,7 +1325,7 @@ ttykqfilter(struct cdev *dev, struct knote *kn) int s; tp = tty_gettp(dev); - if (tp->t_state & TS_GONE) + if (tp == NULL || (tp->t_state & TS_GONE)) return (ENODEV); switch (kn->kn_filter) { @@ -3055,6 +3056,7 @@ ttyfree(struct tty *tp) ttygone(tp); unit = tp->t_devunit; dev = tp->t_mdev; + dev->si_tty = NULL; tp->t_dev = NULL; ttyrel(tp); destroy_dev(dev); @@ -3254,7 +3256,7 @@ ttyread(struct cdev *dev, struct uio *uio, int flag) tp = tty_gettp(dev); - if (tp->t_state & TS_GONE) + if (tp == NULL || (tp->t_state & TS_GONE)) return (ENODEV); return (ttyld_read(tp, uio, flag)); } @@ -3266,7 +3268,7 @@ ttywrite(struct cdev *dev, struct uio *uio, int flag) tp = tty_gettp(dev); - if (tp->t_state & TS_GONE) + if (tp == NULL || (tp->t_state & TS_GONE)) return (ENODEV); return (ttyld_write(tp, uio, flag)); }