From 6d2bfd1ec9391b2641e8ddb454c45e869c9b91ac Mon Sep 17 00:00:00 2001 From: kib Date: Mon, 24 Dec 2007 13:47:16 +0000 Subject: Move the check for the snp device being already attached after the fget() call, that is sleeping point, and possibly dropping Giant. The snp_target == NULL implies the snp_tty == NULL. Remove the code that is put under snp_target == NULL and snp_tty != NULL clause. In snpclose(), do the snp_detach() before scheduling the snp device destruction. Otherwise, after the return from snpclose(), the snp device is already removed from the snp_list, but tty is still in snooped state. Any attempt to do i/o on such tty cause panic because ttytosnp() returns NULL. Tested by: Peter Holm MFC after: 1 week --- sys/dev/snp/snp.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) (limited to 'sys/dev/snp') diff --git a/sys/dev/snp/snp.c b/sys/dev/snp/snp.c index 2365634..845ef31 100644 --- a/sys/dev/snp/snp.c +++ b/sys/dev/snp/snp.c @@ -466,7 +466,8 @@ snpclose(struct cdev *dev, int flags, int fmt, struct thread *td) free(snp->snp_buf, M_SNP); snp->snp_flags &= ~SNOOP_OPEN; dev->si_drv1 = NULL; - destroy_dev_sched_cb(dev, snp_detach, snp); + snp_detach(snp); + destroy_dev_sched(dev); return (0); } @@ -491,7 +492,7 @@ snpioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, struct thread *td) { struct snoop *snp; - struct tty *tp, *tpo; + struct tty *tp; struct cdev *tdev; struct file *fp; int s; @@ -502,8 +503,6 @@ snpioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, s = *(int *)data; if (s < 0) return (snp_down(snp)); - if (snp->snp_tty != NULL) - return (EBUSY); if (fget(td, s, &fp) != 0) return (EINVAL); @@ -516,6 +515,9 @@ snpioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, tdev = fp->f_vnode->v_rdev; fdrop(fp, td); + if (snp->snp_tty != NULL) + return (EBUSY); + tp = snpdevtotty(tdev); if (!tp) return (EINVAL); @@ -523,13 +525,6 @@ snpioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, return (EBUSY); s = spltty(); - - if (snp->snp_target == NULL) { - tpo = snp->snp_tty; - if (tpo) - tpo->t_state &= ~TS_SNOOP; - } - tp->t_state |= TS_SNOOP; snp->snp_olddisc = tp->t_line; tp->t_line = snooplinedisc; -- cgit v1.1