aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_io.c
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2008-10-13 05:41:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-13 12:51:42 -0400
commitfeebed6515a113eeb33919e9557a8b9710ea627c (patch)
tree0461178ee0c5e16ea90023e4b6386cb5c57d3391 /drivers/char/tty_io.c
parentbf7a06bcce205705ea5c7675cbb8ea9239ea30a0 (diff)
tty: shutdown method
Right now there are various drivers that try to use tty->count to know when they get the final close. Aristeau Rozanski showed while debugging the vt sysfs race that this isn't entirely safe. Instead of driver side tricks to work around this introduce a shutdown which is called when the tty is being destructed. This also means that the shutdown method is tied into the refcounting. Use this to rework the console close/sysfs logic. Remove lots of special case code from the tty core code. The pty code can now have a shutdown() method that replaces the special case hackery in the tree free up paths. Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r--drivers/char/tty_io.c49
1 files changed, 29 insertions, 20 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 2e96ce0fddc5..f91704d57a4e 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1482,6 +1482,31 @@ release_mem_out:
1482 goto end_init; 1482 goto end_init;
1483} 1483}
1484 1484
1485void tty_free_termios(struct tty_struct *tty)
1486{
1487 struct ktermios *tp;
1488 int idx = tty->index;
1489 /* Kill this flag and push into drivers for locking etc */
1490 if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) {
1491 /* FIXME: Locking on ->termios array */
1492 tp = tty->termios;
1493 tty->driver->termios[idx] = NULL;
1494 kfree(tp);
1495
1496 tp = tty->termios_locked;
1497 tty->driver->termios_locked[idx] = NULL;
1498 kfree(tp);
1499 }
1500}
1501EXPORT_SYMBOL(tty_free_termios);
1502
1503void tty_shutdown(struct tty_struct *tty)
1504{
1505 tty->driver->ttys[tty->index] = NULL;
1506 tty_free_termios(tty);
1507}
1508EXPORT_SYMBOL(tty_shutdown);
1509
1485/** 1510/**
1486 * release_one_tty - release tty structure memory 1511 * release_one_tty - release tty structure memory
1487 * @kref: kref of tty we are obliterating 1512 * @kref: kref of tty we are obliterating
@@ -1499,27 +1524,11 @@ static void release_one_tty(struct kref *kref)
1499{ 1524{
1500 struct tty_struct *tty = container_of(kref, struct tty_struct, kref); 1525 struct tty_struct *tty = container_of(kref, struct tty_struct, kref);
1501 struct tty_driver *driver = tty->driver; 1526 struct tty_driver *driver = tty->driver;
1502 int devpts = tty->driver->flags & TTY_DRIVER_DEVPTS_MEM;
1503 struct ktermios *tp;
1504 int idx = tty->index;
1505
1506 if (!devpts)
1507 tty->driver->ttys[idx] = NULL;
1508
1509 if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) {
1510 /* FIXME: Locking on ->termios array */
1511 tp = tty->termios;
1512 if (!devpts)
1513 tty->driver->termios[idx] = NULL;
1514 kfree(tp);
1515
1516 tp = tty->termios_locked;
1517 if (!devpts)
1518 tty->driver->termios_locked[idx] = NULL;
1519 kfree(tp);
1520 }
1521
1522 1527
1528 if (tty->ops->shutdown)
1529 tty->ops->shutdown(tty);
1530 else
1531 tty_shutdown(tty);
1523 tty->magic = 0; 1532 tty->magic = 0;
1524 /* FIXME: locking on tty->driver->refcount */ 1533 /* FIXME: locking on tty->driver->refcount */
1525 tty->driver->refcount--; 1534 tty->driver->refcount--;