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
This commit is contained in:
parent
0239a1cc16
commit
6d2bfd1ec9
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user