svn commit: r237780 - stable/8/sys/kern
Peter Holm
pho at FreeBSD.org
Fri Jun 29 14:14:50 UTC 2012
Author: pho
Date: Fri Jun 29 14:14:49 2012
New Revision: 237780
URL: http://svn.freebsd.org/changeset/base/237780
Log:
MFC: r237219
In tty_makedev() the following construction:
dev = make_dev_cred();
dev->si_drv1 = tp;
leaves a small window where the newly created device may be opened
and si_drv1 is NULL.
As this is a vary rare situation, using a lock to close the window
seems overkill. Instead just wait for the assignment of si_drv1.
Modified:
stable/8/sys/kern/tty.c
Directory Properties:
stable/8/sys/ (props changed)
Modified: stable/8/sys/kern/tty.c
==============================================================================
--- stable/8/sys/kern/tty.c Fri Jun 29 13:02:46 2012 (r237779)
+++ stable/8/sys/kern/tty.c Fri Jun 29 14:14:49 2012 (r237780)
@@ -216,9 +216,15 @@ ttydev_leave(struct tty *tp)
static int
ttydev_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
{
- struct tty *tp = dev->si_drv1;
+ struct tty *tp;
int error = 0;
+ while ((tp = dev->si_drv1) == NULL) {
+ error = tsleep(&dev->si_drv1, PCATCH, "ttdrv1", 1);
+ if (error != EWOULDBLOCK)
+ return (error);
+ }
+
tty_lock(tp);
if (tty_gone(tp)) {
/* Device is already gone. */
@@ -726,9 +732,14 @@ static struct cdevsw ttydev_cdevsw = {
static int
ttyil_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
{
- struct tty *tp = dev->si_drv1;
+ struct tty *tp;
int error = 0;
+ while ((tp = dev->si_drv1) == NULL) {
+ error = tsleep(&dev->si_drv1, PCATCH, "ttdrv1", 1);
+ if (error != EWOULDBLOCK)
+ return (error);
+ }
tty_lock(tp);
if (tty_gone(tp))
error = ENODEV;
@@ -1166,6 +1177,7 @@ tty_makedev(struct tty *tp, struct ucred
dev = make_dev_cred(&ttydev_cdevsw, 0, cred,
uid, gid, mode, "%s%s", prefix, name);
dev->si_drv1 = tp;
+ wakeup(&dev->si_drv1);
tp->t_dev = dev;
/* Slave call-in devices. */
@@ -1174,12 +1186,14 @@ tty_makedev(struct tty *tp, struct ucred
uid, gid, mode, "%s%s.init", prefix, name);
dev_depends(tp->t_dev, dev);
dev->si_drv1 = tp;
+ wakeup(&dev->si_drv1);
dev->si_drv2 = &tp->t_termios_init_in;
dev = make_dev_cred(&ttyil_cdevsw, 0, cred,
uid, gid, mode, "%s%s.lock", prefix, name);
dev_depends(tp->t_dev, dev);
dev->si_drv1 = tp;
+ wakeup(&dev->si_drv1);
dev->si_drv2 = &tp->t_termios_lock_in;
}
@@ -1189,6 +1203,7 @@ tty_makedev(struct tty *tp, struct ucred
UID_UUCP, GID_DIALER, 0660, "cua%s", name);
dev_depends(tp->t_dev, dev);
dev->si_drv1 = tp;
+ wakeup(&dev->si_drv1);
/* Slave call-out devices. */
if (tp->t_flags & TF_INITLOCK) {
@@ -1196,12 +1211,14 @@ tty_makedev(struct tty *tp, struct ucred
UID_UUCP, GID_DIALER, 0660, "cua%s.init", name);
dev_depends(tp->t_dev, dev);
dev->si_drv1 = tp;
+ wakeup(&dev->si_drv1);
dev->si_drv2 = &tp->t_termios_init_out;
dev = make_dev_cred(&ttyil_cdevsw, 0, cred,
UID_UUCP, GID_DIALER, 0660, "cua%s.lock", name);
dev_depends(tp->t_dev, dev);
dev->si_drv1 = tp;
+ wakeup(&dev->si_drv1);
dev->si_drv2 = &tp->t_termios_lock_out;
}
}
More information about the svn-src-all
mailing list