diff options
-rw-r--r-- | drivers/tty/pty.c | 25 | ||||
-rw-r--r-- | drivers/tty/tty_io.c | 20 | ||||
-rw-r--r-- | drivers/tty/tty_ldisc.c | 3 |
3 files changed, 37 insertions, 11 deletions
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 60c08ce83782..d6579a9064c4 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c | |||
@@ -282,6 +282,17 @@ done: | |||
282 | return 0; | 282 | return 0; |
283 | } | 283 | } |
284 | 284 | ||
285 | /** | ||
286 | * pty_common_install - set up the pty pair | ||
287 | * @driver: the pty driver | ||
288 | * @tty: the tty being instantiated | ||
289 | * @bool: legacy, true if this is BSD style | ||
290 | * | ||
291 | * Perform the initial set up for the tty/pty pair. Called from the | ||
292 | * tty layer when the port is first opened. | ||
293 | * | ||
294 | * Locking: the caller must hold the tty_mutex | ||
295 | */ | ||
285 | static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty, | 296 | static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty, |
286 | bool legacy) | 297 | bool legacy) |
287 | { | 298 | { |
@@ -364,6 +375,14 @@ static int pty_install(struct tty_driver *driver, struct tty_struct *tty) | |||
364 | return pty_common_install(driver, tty, true); | 375 | return pty_common_install(driver, tty, true); |
365 | } | 376 | } |
366 | 377 | ||
378 | static void pty_remove(struct tty_driver *driver, struct tty_struct *tty) | ||
379 | { | ||
380 | struct tty_struct *pair = tty->link; | ||
381 | driver->ttys[tty->index] = NULL; | ||
382 | if (pair) | ||
383 | pair->driver->ttys[pair->index] = NULL; | ||
384 | } | ||
385 | |||
367 | static int pty_bsd_ioctl(struct tty_struct *tty, | 386 | static int pty_bsd_ioctl(struct tty_struct *tty, |
368 | unsigned int cmd, unsigned long arg) | 387 | unsigned int cmd, unsigned long arg) |
369 | { | 388 | { |
@@ -395,7 +414,8 @@ static const struct tty_operations master_pty_ops_bsd = { | |||
395 | .set_termios = pty_set_termios, | 414 | .set_termios = pty_set_termios, |
396 | .ioctl = pty_bsd_ioctl, | 415 | .ioctl = pty_bsd_ioctl, |
397 | .cleanup = pty_cleanup, | 416 | .cleanup = pty_cleanup, |
398 | .resize = pty_resize | 417 | .resize = pty_resize, |
418 | .remove = pty_remove | ||
399 | }; | 419 | }; |
400 | 420 | ||
401 | static const struct tty_operations slave_pty_ops_bsd = { | 421 | static const struct tty_operations slave_pty_ops_bsd = { |
@@ -409,7 +429,8 @@ static const struct tty_operations slave_pty_ops_bsd = { | |||
409 | .unthrottle = pty_unthrottle, | 429 | .unthrottle = pty_unthrottle, |
410 | .set_termios = pty_set_termios, | 430 | .set_termios = pty_set_termios, |
411 | .cleanup = pty_cleanup, | 431 | .cleanup = pty_cleanup, |
412 | .resize = pty_resize | 432 | .resize = pty_resize, |
433 | .remove = pty_remove | ||
413 | }; | 434 | }; |
414 | 435 | ||
415 | static void __init legacy_pty_init(void) | 436 | static void __init legacy_pty_init(void) |
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index be18d60ddf4c..c6f4d711771b 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -1465,7 +1465,6 @@ EXPORT_SYMBOL(tty_free_termios); | |||
1465 | * in use. It also gets called when setup of a device fails. | 1465 | * in use. It also gets called when setup of a device fails. |
1466 | * | 1466 | * |
1467 | * Locking: | 1467 | * Locking: |
1468 | * tty_mutex - sometimes only | ||
1469 | * takes the file list lock internally when working on the list | 1468 | * takes the file list lock internally when working on the list |
1470 | * of ttys that the driver keeps. | 1469 | * of ttys that the driver keeps. |
1471 | * | 1470 | * |
@@ -1526,17 +1525,16 @@ EXPORT_SYMBOL(tty_kref_put); | |||
1526 | * and decrement the refcount of the backing module. | 1525 | * and decrement the refcount of the backing module. |
1527 | * | 1526 | * |
1528 | * Locking: | 1527 | * Locking: |
1529 | * tty_mutex - sometimes only | 1528 | * tty_mutex |
1530 | * takes the file list lock internally when working on the list | 1529 | * takes the file list lock internally when working on the list |
1531 | * of ttys that the driver keeps. | 1530 | * of ttys that the driver keeps. |
1532 | * FIXME: should we require tty_mutex is held here ?? | ||
1533 | * | 1531 | * |
1534 | */ | 1532 | */ |
1535 | static void release_tty(struct tty_struct *tty, int idx) | 1533 | static void release_tty(struct tty_struct *tty, int idx) |
1536 | { | 1534 | { |
1537 | /* This should always be true but check for the moment */ | 1535 | /* This should always be true but check for the moment */ |
1538 | WARN_ON(tty->index != idx); | 1536 | WARN_ON(tty->index != idx); |
1539 | 1537 | WARN_ON(!mutex_is_locked(&tty_mutex)); | |
1540 | if (tty->ops->shutdown) | 1538 | if (tty->ops->shutdown) |
1541 | tty->ops->shutdown(tty); | 1539 | tty->ops->shutdown(tty); |
1542 | tty_free_termios(tty); | 1540 | tty_free_termios(tty); |
@@ -1708,6 +1706,9 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1708 | * The closing flags are now consistent with the open counts on | 1706 | * The closing flags are now consistent with the open counts on |
1709 | * both sides, and we've completed the last operation that could | 1707 | * both sides, and we've completed the last operation that could |
1710 | * block, so it's safe to proceed with closing. | 1708 | * block, so it's safe to proceed with closing. |
1709 | * | ||
1710 | * We must *not* drop the tty_mutex until we ensure that a further | ||
1711 | * entry into tty_open can not pick up this tty. | ||
1711 | */ | 1712 | */ |
1712 | if (pty_master) { | 1713 | if (pty_master) { |
1713 | if (--o_tty->count < 0) { | 1714 | if (--o_tty->count < 0) { |
@@ -1759,12 +1760,13 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1759 | } | 1760 | } |
1760 | 1761 | ||
1761 | mutex_unlock(&tty_mutex); | 1762 | mutex_unlock(&tty_mutex); |
1763 | tty_unlock(); | ||
1764 | /* At this point the TTY_CLOSING flag should ensure a dead tty | ||
1765 | cannot be re-opened by a racing opener */ | ||
1762 | 1766 | ||
1763 | /* check whether both sides are closing ... */ | 1767 | /* check whether both sides are closing ... */ |
1764 | if (!tty_closing || (o_tty && !o_tty_closing)) { | 1768 | if (!tty_closing || (o_tty && !o_tty_closing)) |
1765 | tty_unlock(); | ||
1766 | return 0; | 1769 | return 0; |
1767 | } | ||
1768 | 1770 | ||
1769 | #ifdef TTY_DEBUG_HANGUP | 1771 | #ifdef TTY_DEBUG_HANGUP |
1770 | printk(KERN_DEBUG "%s: freeing tty structure...\n", __func__); | 1772 | printk(KERN_DEBUG "%s: freeing tty structure...\n", __func__); |
@@ -1777,12 +1779,14 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1777 | * The release_tty function takes care of the details of clearing | 1779 | * The release_tty function takes care of the details of clearing |
1778 | * the slots and preserving the termios structure. | 1780 | * the slots and preserving the termios structure. |
1779 | */ | 1781 | */ |
1782 | mutex_lock(&tty_mutex); | ||
1780 | release_tty(tty, idx); | 1783 | release_tty(tty, idx); |
1784 | mutex_unlock(&tty_mutex); | ||
1781 | 1785 | ||
1782 | /* Make this pty number available for reallocation */ | 1786 | /* Make this pty number available for reallocation */ |
1783 | if (devpts) | 1787 | if (devpts) |
1784 | devpts_kill_index(inode, idx); | 1788 | devpts_kill_index(inode, idx); |
1785 | tty_unlock(); | 1789 | |
1786 | return 0; | 1790 | return 0; |
1787 | } | 1791 | } |
1788 | 1792 | ||
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index e6156c60d190..3d0687197d09 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c | |||
@@ -912,7 +912,6 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) | |||
912 | * race with the set_ldisc code path. | 912 | * race with the set_ldisc code path. |
913 | */ | 913 | */ |
914 | 914 | ||
915 | tty_unlock(); | ||
916 | tty_ldisc_halt(tty); | 915 | tty_ldisc_halt(tty); |
917 | tty_ldisc_flush_works(tty); | 916 | tty_ldisc_flush_works(tty); |
918 | tty_lock(); | 917 | tty_lock(); |
@@ -930,6 +929,8 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) | |||
930 | tty_set_termios_ldisc(tty, N_TTY); | 929 | tty_set_termios_ldisc(tty, N_TTY); |
931 | mutex_unlock(&tty->ldisc_mutex); | 930 | mutex_unlock(&tty->ldisc_mutex); |
932 | 931 | ||
932 | tty_unlock(); | ||
933 | |||
933 | /* This will need doing differently if we need to lock */ | 934 | /* This will need doing differently if we need to lock */ |
934 | if (o_tty) | 935 | if (o_tty) |
935 | tty_ldisc_release(o_tty, NULL); | 936 | tty_ldisc_release(o_tty, NULL); |