diff options
author | kib <kib@FreeBSD.org> | 2007-12-24 13:47:16 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2007-12-24 13:47:16 +0000 |
commit | 6d2bfd1ec9391b2641e8ddb454c45e869c9b91ac (patch) | |
tree | c4413025e2e17143ed7968392bcfa4aaeea37e7b /sys/dev/snp | |
parent | 0239a1cc16ad0973050aff8eaefa63393c648865 (diff) | |
download | FreeBSD-src-6d2bfd1ec9391b2641e8ddb454c45e869c9b91ac.zip FreeBSD-src-6d2bfd1ec9391b2641e8ddb454c45e869c9b91ac.tar.gz |
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
Diffstat (limited to 'sys/dev/snp')
-rw-r--r-- | sys/dev/snp/snp.c | 17 |
1 files changed, 6 insertions, 11 deletions
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; |