aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/tty/pty.c25
-rw-r--r--drivers/tty/tty_io.c20
-rw-r--r--drivers/tty/tty_ldisc.c3
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 */
285static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty, 296static 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
378static 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
367static int pty_bsd_ioctl(struct tty_struct *tty, 386static 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
401static const struct tty_operations slave_pty_ops_bsd = { 421static 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
415static void __init legacy_pty_init(void) 436static 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 */
1535static void release_tty(struct tty_struct *tty, int idx) 1533static 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);