diff options
Diffstat (limited to 'drivers/tty/tty_io.c')
-rw-r--r-- | drivers/tty/tty_io.c | 67 |
1 files changed, 40 insertions, 27 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index ac96f74573d0..ca7c25d9f6d5 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -185,6 +185,7 @@ void free_tty_struct(struct tty_struct *tty) | |||
185 | put_device(tty->dev); | 185 | put_device(tty->dev); |
186 | kfree(tty->write_buf); | 186 | kfree(tty->write_buf); |
187 | tty_buffer_free_all(tty); | 187 | tty_buffer_free_all(tty); |
188 | tty->magic = 0xDEADDEAD; | ||
188 | kfree(tty); | 189 | kfree(tty); |
189 | } | 190 | } |
190 | 191 | ||
@@ -573,7 +574,7 @@ void __tty_hangup(struct tty_struct *tty) | |||
573 | } | 574 | } |
574 | spin_unlock(&redirect_lock); | 575 | spin_unlock(&redirect_lock); |
575 | 576 | ||
576 | tty_lock(); | 577 | tty_lock(tty); |
577 | 578 | ||
578 | /* some functions below drop BTM, so we need this bit */ | 579 | /* some functions below drop BTM, so we need this bit */ |
579 | set_bit(TTY_HUPPING, &tty->flags); | 580 | set_bit(TTY_HUPPING, &tty->flags); |
@@ -666,7 +667,7 @@ void __tty_hangup(struct tty_struct *tty) | |||
666 | clear_bit(TTY_HUPPING, &tty->flags); | 667 | clear_bit(TTY_HUPPING, &tty->flags); |
667 | tty_ldisc_enable(tty); | 668 | tty_ldisc_enable(tty); |
668 | 669 | ||
669 | tty_unlock(); | 670 | tty_unlock(tty); |
670 | 671 | ||
671 | if (f) | 672 | if (f) |
672 | fput(f); | 673 | fput(f); |
@@ -1103,12 +1104,12 @@ void tty_write_message(struct tty_struct *tty, char *msg) | |||
1103 | { | 1104 | { |
1104 | if (tty) { | 1105 | if (tty) { |
1105 | mutex_lock(&tty->atomic_write_lock); | 1106 | mutex_lock(&tty->atomic_write_lock); |
1106 | tty_lock(); | 1107 | tty_lock(tty); |
1107 | if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) { | 1108 | if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) { |
1108 | tty_unlock(); | 1109 | tty_unlock(tty); |
1109 | tty->ops->write(tty, msg, strlen(msg)); | 1110 | tty->ops->write(tty, msg, strlen(msg)); |
1110 | } else | 1111 | } else |
1111 | tty_unlock(); | 1112 | tty_unlock(tty); |
1112 | tty_write_unlock(tty); | 1113 | tty_write_unlock(tty); |
1113 | } | 1114 | } |
1114 | return; | 1115 | return; |
@@ -1403,6 +1404,7 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) | |||
1403 | } | 1404 | } |
1404 | initialize_tty_struct(tty, driver, idx); | 1405 | initialize_tty_struct(tty, driver, idx); |
1405 | 1406 | ||
1407 | tty_lock(tty); | ||
1406 | retval = tty_driver_install_tty(driver, tty); | 1408 | retval = tty_driver_install_tty(driver, tty); |
1407 | if (retval < 0) | 1409 | if (retval < 0) |
1408 | goto err_deinit_tty; | 1410 | goto err_deinit_tty; |
@@ -1418,9 +1420,11 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) | |||
1418 | retval = tty_ldisc_setup(tty, tty->link); | 1420 | retval = tty_ldisc_setup(tty, tty->link); |
1419 | if (retval) | 1421 | if (retval) |
1420 | goto err_release_tty; | 1422 | goto err_release_tty; |
1423 | /* Return the tty locked so that it cannot vanish under the caller */ | ||
1421 | return tty; | 1424 | return tty; |
1422 | 1425 | ||
1423 | err_deinit_tty: | 1426 | err_deinit_tty: |
1427 | tty_unlock(tty); | ||
1424 | deinitialize_tty_struct(tty); | 1428 | deinitialize_tty_struct(tty); |
1425 | free_tty_struct(tty); | 1429 | free_tty_struct(tty); |
1426 | err_module_put: | 1430 | err_module_put: |
@@ -1429,6 +1433,7 @@ err_module_put: | |||
1429 | 1433 | ||
1430 | /* call the tty release_tty routine to clean out this slot */ | 1434 | /* call the tty release_tty routine to clean out this slot */ |
1431 | err_release_tty: | 1435 | err_release_tty: |
1436 | tty_unlock(tty); | ||
1432 | printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, " | 1437 | printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, " |
1433 | "clearing slot %d\n", idx); | 1438 | "clearing slot %d\n", idx); |
1434 | release_tty(tty, idx); | 1439 | release_tty(tty, idx); |
@@ -1631,7 +1636,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1631 | if (tty_paranoia_check(tty, inode, __func__)) | 1636 | if (tty_paranoia_check(tty, inode, __func__)) |
1632 | return 0; | 1637 | return 0; |
1633 | 1638 | ||
1634 | tty_lock(); | 1639 | tty_lock(tty); |
1635 | check_tty_count(tty, __func__); | 1640 | check_tty_count(tty, __func__); |
1636 | 1641 | ||
1637 | __tty_fasync(-1, filp, 0); | 1642 | __tty_fasync(-1, filp, 0); |
@@ -1640,10 +1645,11 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1640 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 1645 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
1641 | tty->driver->subtype == PTY_TYPE_MASTER); | 1646 | tty->driver->subtype == PTY_TYPE_MASTER); |
1642 | devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; | 1647 | devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; |
1648 | /* Review: parallel close */ | ||
1643 | o_tty = tty->link; | 1649 | o_tty = tty->link; |
1644 | 1650 | ||
1645 | if (tty_release_checks(tty, o_tty, idx)) { | 1651 | if (tty_release_checks(tty, o_tty, idx)) { |
1646 | tty_unlock(); | 1652 | tty_unlock(tty); |
1647 | return 0; | 1653 | return 0; |
1648 | } | 1654 | } |
1649 | 1655 | ||
@@ -1655,7 +1661,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1655 | if (tty->ops->close) | 1661 | if (tty->ops->close) |
1656 | tty->ops->close(tty, filp); | 1662 | tty->ops->close(tty, filp); |
1657 | 1663 | ||
1658 | tty_unlock(); | 1664 | tty_unlock(tty); |
1659 | /* | 1665 | /* |
1660 | * Sanity check: if tty->count is going to zero, there shouldn't be | 1666 | * Sanity check: if tty->count is going to zero, there shouldn't be |
1661 | * any waiters on tty->read_wait or tty->write_wait. We test the | 1667 | * any waiters on tty->read_wait or tty->write_wait. We test the |
@@ -1678,7 +1684,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1678 | opens on /dev/tty */ | 1684 | opens on /dev/tty */ |
1679 | 1685 | ||
1680 | mutex_lock(&tty_mutex); | 1686 | mutex_lock(&tty_mutex); |
1681 | tty_lock(); | 1687 | tty_lock_pair(tty, o_tty); |
1682 | tty_closing = tty->count <= 1; | 1688 | tty_closing = tty->count <= 1; |
1683 | o_tty_closing = o_tty && | 1689 | o_tty_closing = o_tty && |
1684 | (o_tty->count <= (pty_master ? 1 : 0)); | 1690 | (o_tty->count <= (pty_master ? 1 : 0)); |
@@ -1709,7 +1715,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1709 | 1715 | ||
1710 | printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", | 1716 | printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", |
1711 | __func__, tty_name(tty, buf)); | 1717 | __func__, tty_name(tty, buf)); |
1712 | tty_unlock(); | 1718 | tty_unlock_pair(tty, o_tty); |
1713 | mutex_unlock(&tty_mutex); | 1719 | mutex_unlock(&tty_mutex); |
1714 | schedule(); | 1720 | schedule(); |
1715 | } | 1721 | } |
@@ -1772,7 +1778,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1772 | 1778 | ||
1773 | /* check whether both sides are closing ... */ | 1779 | /* check whether both sides are closing ... */ |
1774 | if (!tty_closing || (o_tty && !o_tty_closing)) { | 1780 | if (!tty_closing || (o_tty && !o_tty_closing)) { |
1775 | tty_unlock(); | 1781 | tty_unlock_pair(tty, o_tty); |
1776 | return 0; | 1782 | return 0; |
1777 | } | 1783 | } |
1778 | 1784 | ||
@@ -1785,14 +1791,16 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1785 | tty_ldisc_release(tty, o_tty); | 1791 | tty_ldisc_release(tty, o_tty); |
1786 | /* | 1792 | /* |
1787 | * The release_tty function takes care of the details of clearing | 1793 | * The release_tty function takes care of the details of clearing |
1788 | * the slots and preserving the termios structure. | 1794 | * the slots and preserving the termios structure. The tty_unlock_pair |
1795 | * should be safe as we keep a kref while the tty is locked (so the | ||
1796 | * unlock never unlocks a freed tty). | ||
1789 | */ | 1797 | */ |
1790 | release_tty(tty, idx); | 1798 | release_tty(tty, idx); |
1799 | tty_unlock_pair(tty, o_tty); | ||
1791 | 1800 | ||
1792 | /* Make this pty number available for reallocation */ | 1801 | /* Make this pty number available for reallocation */ |
1793 | if (devpts) | 1802 | if (devpts) |
1794 | devpts_kill_index(inode, idx); | 1803 | devpts_kill_index(inode, idx); |
1795 | tty_unlock(); | ||
1796 | return 0; | 1804 | return 0; |
1797 | } | 1805 | } |
1798 | 1806 | ||
@@ -1896,6 +1904,9 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, | |||
1896 | * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev. | 1904 | * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev. |
1897 | * tty->count should protect the rest. | 1905 | * tty->count should protect the rest. |
1898 | * ->siglock protects ->signal/->sighand | 1906 | * ->siglock protects ->signal/->sighand |
1907 | * | ||
1908 | * Note: the tty_unlock/lock cases without a ref are only safe due to | ||
1909 | * tty_mutex | ||
1899 | */ | 1910 | */ |
1900 | 1911 | ||
1901 | static int tty_open(struct inode *inode, struct file *filp) | 1912 | static int tty_open(struct inode *inode, struct file *filp) |
@@ -1919,8 +1930,7 @@ retry_open: | |||
1919 | retval = 0; | 1930 | retval = 0; |
1920 | 1931 | ||
1921 | mutex_lock(&tty_mutex); | 1932 | mutex_lock(&tty_mutex); |
1922 | tty_lock(); | 1933 | /* This is protected by the tty_mutex */ |
1923 | |||
1924 | tty = tty_open_current_tty(device, filp); | 1934 | tty = tty_open_current_tty(device, filp); |
1925 | if (IS_ERR(tty)) { | 1935 | if (IS_ERR(tty)) { |
1926 | retval = PTR_ERR(tty); | 1936 | retval = PTR_ERR(tty); |
@@ -1941,17 +1951,19 @@ retry_open: | |||
1941 | } | 1951 | } |
1942 | 1952 | ||
1943 | if (tty) { | 1953 | if (tty) { |
1954 | tty_lock(tty); | ||
1944 | retval = tty_reopen(tty); | 1955 | retval = tty_reopen(tty); |
1945 | if (retval) | 1956 | if (retval < 0) { |
1957 | tty_unlock(tty); | ||
1946 | tty = ERR_PTR(retval); | 1958 | tty = ERR_PTR(retval); |
1947 | } else | 1959 | } |
1960 | } else /* Returns with the tty_lock held for now */ | ||
1948 | tty = tty_init_dev(driver, index); | 1961 | tty = tty_init_dev(driver, index); |
1949 | 1962 | ||
1950 | mutex_unlock(&tty_mutex); | 1963 | mutex_unlock(&tty_mutex); |
1951 | if (driver) | 1964 | if (driver) |
1952 | tty_driver_kref_put(driver); | 1965 | tty_driver_kref_put(driver); |
1953 | if (IS_ERR(tty)) { | 1966 | if (IS_ERR(tty)) { |
1954 | tty_unlock(); | ||
1955 | retval = PTR_ERR(tty); | 1967 | retval = PTR_ERR(tty); |
1956 | goto err_file; | 1968 | goto err_file; |
1957 | } | 1969 | } |
@@ -1980,7 +1992,7 @@ retry_open: | |||
1980 | printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, | 1992 | printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, |
1981 | retval, tty->name); | 1993 | retval, tty->name); |
1982 | #endif | 1994 | #endif |
1983 | tty_unlock(); /* need to call tty_release without BTM */ | 1995 | tty_unlock(tty); /* need to call tty_release without BTM */ |
1984 | tty_release(inode, filp); | 1996 | tty_release(inode, filp); |
1985 | if (retval != -ERESTARTSYS) | 1997 | if (retval != -ERESTARTSYS) |
1986 | return retval; | 1998 | return retval; |
@@ -1992,17 +2004,15 @@ retry_open: | |||
1992 | /* | 2004 | /* |
1993 | * Need to reset f_op in case a hangup happened. | 2005 | * Need to reset f_op in case a hangup happened. |
1994 | */ | 2006 | */ |
1995 | tty_lock(); | ||
1996 | if (filp->f_op == &hung_up_tty_fops) | 2007 | if (filp->f_op == &hung_up_tty_fops) |
1997 | filp->f_op = &tty_fops; | 2008 | filp->f_op = &tty_fops; |
1998 | tty_unlock(); | ||
1999 | goto retry_open; | 2009 | goto retry_open; |
2000 | } | 2010 | } |
2001 | tty_unlock(); | 2011 | tty_unlock(tty); |
2002 | 2012 | ||
2003 | 2013 | ||
2004 | mutex_lock(&tty_mutex); | 2014 | mutex_lock(&tty_mutex); |
2005 | tty_lock(); | 2015 | tty_lock(tty); |
2006 | spin_lock_irq(¤t->sighand->siglock); | 2016 | spin_lock_irq(¤t->sighand->siglock); |
2007 | if (!noctty && | 2017 | if (!noctty && |
2008 | current->signal->leader && | 2018 | current->signal->leader && |
@@ -2010,11 +2020,10 @@ retry_open: | |||
2010 | tty->session == NULL) | 2020 | tty->session == NULL) |
2011 | __proc_set_tty(current, tty); | 2021 | __proc_set_tty(current, tty); |
2012 | spin_unlock_irq(¤t->sighand->siglock); | 2022 | spin_unlock_irq(¤t->sighand->siglock); |
2013 | tty_unlock(); | 2023 | tty_unlock(tty); |
2014 | mutex_unlock(&tty_mutex); | 2024 | mutex_unlock(&tty_mutex); |
2015 | return 0; | 2025 | return 0; |
2016 | err_unlock: | 2026 | err_unlock: |
2017 | tty_unlock(); | ||
2018 | mutex_unlock(&tty_mutex); | 2027 | mutex_unlock(&tty_mutex); |
2019 | /* after locks to avoid deadlock */ | 2028 | /* after locks to avoid deadlock */ |
2020 | if (!IS_ERR_OR_NULL(driver)) | 2029 | if (!IS_ERR_OR_NULL(driver)) |
@@ -2097,10 +2106,13 @@ out: | |||
2097 | 2106 | ||
2098 | static int tty_fasync(int fd, struct file *filp, int on) | 2107 | static int tty_fasync(int fd, struct file *filp, int on) |
2099 | { | 2108 | { |
2109 | struct tty_struct *tty = file_tty(filp); | ||
2100 | int retval; | 2110 | int retval; |
2101 | tty_lock(); | 2111 | |
2112 | tty_lock(tty); | ||
2102 | retval = __tty_fasync(fd, filp, on); | 2113 | retval = __tty_fasync(fd, filp, on); |
2103 | tty_unlock(); | 2114 | tty_unlock(tty); |
2115 | |||
2104 | return retval; | 2116 | return retval; |
2105 | } | 2117 | } |
2106 | 2118 | ||
@@ -2937,6 +2949,7 @@ void initialize_tty_struct(struct tty_struct *tty, | |||
2937 | tty->pgrp = NULL; | 2949 | tty->pgrp = NULL; |
2938 | tty->overrun_time = jiffies; | 2950 | tty->overrun_time = jiffies; |
2939 | tty_buffer_init(tty); | 2951 | tty_buffer_init(tty); |
2952 | mutex_init(&tty->legacy_mutex); | ||
2940 | mutex_init(&tty->termios_mutex); | 2953 | mutex_init(&tty->termios_mutex); |
2941 | mutex_init(&tty->ldisc_mutex); | 2954 | mutex_init(&tty->ldisc_mutex); |
2942 | init_waitqueue_head(&tty->write_wait); | 2955 | init_waitqueue_head(&tty->write_wait); |