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 b425c79675ad..9e930c009bf2 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; |
| @@ -1415,9 +1417,11 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) | |||
| 1415 | retval = tty_ldisc_setup(tty, tty->link); | 1417 | retval = tty_ldisc_setup(tty, tty->link); |
| 1416 | if (retval) | 1418 | if (retval) |
| 1417 | goto err_release_tty; | 1419 | goto err_release_tty; |
| 1420 | /* Return the tty locked so that it cannot vanish under the caller */ | ||
| 1418 | return tty; | 1421 | return tty; |
| 1419 | 1422 | ||
| 1420 | err_deinit_tty: | 1423 | err_deinit_tty: |
| 1424 | tty_unlock(tty); | ||
| 1421 | deinitialize_tty_struct(tty); | 1425 | deinitialize_tty_struct(tty); |
| 1422 | free_tty_struct(tty); | 1426 | free_tty_struct(tty); |
| 1423 | err_module_put: | 1427 | err_module_put: |
| @@ -1426,6 +1430,7 @@ err_module_put: | |||
| 1426 | 1430 | ||
| 1427 | /* call the tty release_tty routine to clean out this slot */ | 1431 | /* call the tty release_tty routine to clean out this slot */ |
| 1428 | err_release_tty: | 1432 | err_release_tty: |
| 1433 | tty_unlock(tty); | ||
| 1429 | printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, " | 1434 | printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, " |
| 1430 | "clearing slot %d\n", idx); | 1435 | "clearing slot %d\n", idx); |
| 1431 | release_tty(tty, idx); | 1436 | release_tty(tty, idx); |
| @@ -1628,7 +1633,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
| 1628 | if (tty_paranoia_check(tty, inode, __func__)) | 1633 | if (tty_paranoia_check(tty, inode, __func__)) |
| 1629 | return 0; | 1634 | return 0; |
| 1630 | 1635 | ||
| 1631 | tty_lock(); | 1636 | tty_lock(tty); |
| 1632 | check_tty_count(tty, __func__); | 1637 | check_tty_count(tty, __func__); |
| 1633 | 1638 | ||
| 1634 | __tty_fasync(-1, filp, 0); | 1639 | __tty_fasync(-1, filp, 0); |
| @@ -1637,10 +1642,11 @@ int tty_release(struct inode *inode, struct file *filp) | |||
| 1637 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 1642 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
| 1638 | tty->driver->subtype == PTY_TYPE_MASTER); | 1643 | tty->driver->subtype == PTY_TYPE_MASTER); |
| 1639 | devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; | 1644 | devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; |
| 1645 | /* Review: parallel close */ | ||
| 1640 | o_tty = tty->link; | 1646 | o_tty = tty->link; |
| 1641 | 1647 | ||
| 1642 | if (tty_release_checks(tty, o_tty, idx)) { | 1648 | if (tty_release_checks(tty, o_tty, idx)) { |
| 1643 | tty_unlock(); | 1649 | tty_unlock(tty); |
| 1644 | return 0; | 1650 | return 0; |
| 1645 | } | 1651 | } |
| 1646 | 1652 | ||
| @@ -1652,7 +1658,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
| 1652 | if (tty->ops->close) | 1658 | if (tty->ops->close) |
| 1653 | tty->ops->close(tty, filp); | 1659 | tty->ops->close(tty, filp); |
| 1654 | 1660 | ||
| 1655 | tty_unlock(); | 1661 | tty_unlock(tty); |
| 1656 | /* | 1662 | /* |
| 1657 | * Sanity check: if tty->count is going to zero, there shouldn't be | 1663 | * Sanity check: if tty->count is going to zero, there shouldn't be |
| 1658 | * any waiters on tty->read_wait or tty->write_wait. We test the | 1664 | * any waiters on tty->read_wait or tty->write_wait. We test the |
| @@ -1675,7 +1681,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
| 1675 | opens on /dev/tty */ | 1681 | opens on /dev/tty */ |
| 1676 | 1682 | ||
| 1677 | mutex_lock(&tty_mutex); | 1683 | mutex_lock(&tty_mutex); |
| 1678 | tty_lock(); | 1684 | tty_lock_pair(tty, o_tty); |
| 1679 | tty_closing = tty->count <= 1; | 1685 | tty_closing = tty->count <= 1; |
| 1680 | o_tty_closing = o_tty && | 1686 | o_tty_closing = o_tty && |
| 1681 | (o_tty->count <= (pty_master ? 1 : 0)); | 1687 | (o_tty->count <= (pty_master ? 1 : 0)); |
| @@ -1706,7 +1712,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
| 1706 | 1712 | ||
| 1707 | printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", | 1713 | printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", |
| 1708 | __func__, tty_name(tty, buf)); | 1714 | __func__, tty_name(tty, buf)); |
| 1709 | tty_unlock(); | 1715 | tty_unlock_pair(tty, o_tty); |
| 1710 | mutex_unlock(&tty_mutex); | 1716 | mutex_unlock(&tty_mutex); |
| 1711 | schedule(); | 1717 | schedule(); |
| 1712 | } | 1718 | } |
| @@ -1769,7 +1775,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
| 1769 | 1775 | ||
| 1770 | /* check whether both sides are closing ... */ | 1776 | /* check whether both sides are closing ... */ |
| 1771 | if (!tty_closing || (o_tty && !o_tty_closing)) { | 1777 | if (!tty_closing || (o_tty && !o_tty_closing)) { |
| 1772 | tty_unlock(); | 1778 | tty_unlock_pair(tty, o_tty); |
| 1773 | return 0; | 1779 | return 0; |
| 1774 | } | 1780 | } |
| 1775 | 1781 | ||
| @@ -1782,14 +1788,16 @@ int tty_release(struct inode *inode, struct file *filp) | |||
| 1782 | tty_ldisc_release(tty, o_tty); | 1788 | tty_ldisc_release(tty, o_tty); |
| 1783 | /* | 1789 | /* |
| 1784 | * The release_tty function takes care of the details of clearing | 1790 | * The release_tty function takes care of the details of clearing |
| 1785 | * the slots and preserving the termios structure. | 1791 | * the slots and preserving the termios structure. The tty_unlock_pair |
| 1792 | * should be safe as we keep a kref while the tty is locked (so the | ||
| 1793 | * unlock never unlocks a freed tty). | ||
| 1786 | */ | 1794 | */ |
| 1787 | release_tty(tty, idx); | 1795 | release_tty(tty, idx); |
| 1796 | tty_unlock_pair(tty, o_tty); | ||
| 1788 | 1797 | ||
| 1789 | /* Make this pty number available for reallocation */ | 1798 | /* Make this pty number available for reallocation */ |
| 1790 | if (devpts) | 1799 | if (devpts) |
| 1791 | devpts_kill_index(inode, idx); | 1800 | devpts_kill_index(inode, idx); |
| 1792 | tty_unlock(); | ||
| 1793 | return 0; | 1801 | return 0; |
| 1794 | } | 1802 | } |
| 1795 | 1803 | ||
| @@ -1893,6 +1901,9 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, | |||
| 1893 | * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev. | 1901 | * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev. |
| 1894 | * tty->count should protect the rest. | 1902 | * tty->count should protect the rest. |
| 1895 | * ->siglock protects ->signal/->sighand | 1903 | * ->siglock protects ->signal/->sighand |
| 1904 | * | ||
| 1905 | * Note: the tty_unlock/lock cases without a ref are only safe due to | ||
| 1906 | * tty_mutex | ||
| 1896 | */ | 1907 | */ |
| 1897 | 1908 | ||
| 1898 | static int tty_open(struct inode *inode, struct file *filp) | 1909 | static int tty_open(struct inode *inode, struct file *filp) |
| @@ -1916,8 +1927,7 @@ retry_open: | |||
| 1916 | retval = 0; | 1927 | retval = 0; |
| 1917 | 1928 | ||
| 1918 | mutex_lock(&tty_mutex); | 1929 | mutex_lock(&tty_mutex); |
| 1919 | tty_lock(); | 1930 | /* This is protected by the tty_mutex */ |
| 1920 | |||
| 1921 | tty = tty_open_current_tty(device, filp); | 1931 | tty = tty_open_current_tty(device, filp); |
| 1922 | if (IS_ERR(tty)) { | 1932 | if (IS_ERR(tty)) { |
| 1923 | retval = PTR_ERR(tty); | 1933 | retval = PTR_ERR(tty); |
| @@ -1938,17 +1948,19 @@ retry_open: | |||
| 1938 | } | 1948 | } |
| 1939 | 1949 | ||
| 1940 | if (tty) { | 1950 | if (tty) { |
| 1951 | tty_lock(tty); | ||
| 1941 | retval = tty_reopen(tty); | 1952 | retval = tty_reopen(tty); |
| 1942 | if (retval) | 1953 | if (retval < 0) { |
| 1954 | tty_unlock(tty); | ||
| 1943 | tty = ERR_PTR(retval); | 1955 | tty = ERR_PTR(retval); |
| 1944 | } else | 1956 | } |
| 1957 | } else /* Returns with the tty_lock held for now */ | ||
| 1945 | tty = tty_init_dev(driver, index); | 1958 | tty = tty_init_dev(driver, index); |
| 1946 | 1959 | ||
| 1947 | mutex_unlock(&tty_mutex); | 1960 | mutex_unlock(&tty_mutex); |
| 1948 | if (driver) | 1961 | if (driver) |
| 1949 | tty_driver_kref_put(driver); | 1962 | tty_driver_kref_put(driver); |
| 1950 | if (IS_ERR(tty)) { | 1963 | if (IS_ERR(tty)) { |
| 1951 | tty_unlock(); | ||
| 1952 | retval = PTR_ERR(tty); | 1964 | retval = PTR_ERR(tty); |
| 1953 | goto err_file; | 1965 | goto err_file; |
| 1954 | } | 1966 | } |
| @@ -1977,7 +1989,7 @@ retry_open: | |||
| 1977 | printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, | 1989 | printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, |
| 1978 | retval, tty->name); | 1990 | retval, tty->name); |
| 1979 | #endif | 1991 | #endif |
| 1980 | tty_unlock(); /* need to call tty_release without BTM */ | 1992 | tty_unlock(tty); /* need to call tty_release without BTM */ |
| 1981 | tty_release(inode, filp); | 1993 | tty_release(inode, filp); |
| 1982 | if (retval != -ERESTARTSYS) | 1994 | if (retval != -ERESTARTSYS) |
| 1983 | return retval; | 1995 | return retval; |
| @@ -1989,17 +2001,15 @@ retry_open: | |||
| 1989 | /* | 2001 | /* |
| 1990 | * Need to reset f_op in case a hangup happened. | 2002 | * Need to reset f_op in case a hangup happened. |
| 1991 | */ | 2003 | */ |
| 1992 | tty_lock(); | ||
| 1993 | if (filp->f_op == &hung_up_tty_fops) | 2004 | if (filp->f_op == &hung_up_tty_fops) |
| 1994 | filp->f_op = &tty_fops; | 2005 | filp->f_op = &tty_fops; |
| 1995 | tty_unlock(); | ||
| 1996 | goto retry_open; | 2006 | goto retry_open; |
| 1997 | } | 2007 | } |
| 1998 | tty_unlock(); | 2008 | tty_unlock(tty); |
| 1999 | 2009 | ||
| 2000 | 2010 | ||
| 2001 | mutex_lock(&tty_mutex); | 2011 | mutex_lock(&tty_mutex); |
| 2002 | tty_lock(); | 2012 | tty_lock(tty); |
| 2003 | spin_lock_irq(¤t->sighand->siglock); | 2013 | spin_lock_irq(¤t->sighand->siglock); |
| 2004 | if (!noctty && | 2014 | if (!noctty && |
| 2005 | current->signal->leader && | 2015 | current->signal->leader && |
| @@ -2007,11 +2017,10 @@ retry_open: | |||
| 2007 | tty->session == NULL) | 2017 | tty->session == NULL) |
| 2008 | __proc_set_tty(current, tty); | 2018 | __proc_set_tty(current, tty); |
| 2009 | spin_unlock_irq(¤t->sighand->siglock); | 2019 | spin_unlock_irq(¤t->sighand->siglock); |
| 2010 | tty_unlock(); | 2020 | tty_unlock(tty); |
| 2011 | mutex_unlock(&tty_mutex); | 2021 | mutex_unlock(&tty_mutex); |
| 2012 | return 0; | 2022 | return 0; |
| 2013 | err_unlock: | 2023 | err_unlock: |
| 2014 | tty_unlock(); | ||
| 2015 | mutex_unlock(&tty_mutex); | 2024 | mutex_unlock(&tty_mutex); |
| 2016 | /* after locks to avoid deadlock */ | 2025 | /* after locks to avoid deadlock */ |
| 2017 | if (!IS_ERR_OR_NULL(driver)) | 2026 | if (!IS_ERR_OR_NULL(driver)) |
| @@ -2094,10 +2103,13 @@ out: | |||
| 2094 | 2103 | ||
| 2095 | static int tty_fasync(int fd, struct file *filp, int on) | 2104 | static int tty_fasync(int fd, struct file *filp, int on) |
| 2096 | { | 2105 | { |
| 2106 | struct tty_struct *tty = file_tty(filp); | ||
| 2097 | int retval; | 2107 | int retval; |
| 2098 | tty_lock(); | 2108 | |
| 2109 | tty_lock(tty); | ||
| 2099 | retval = __tty_fasync(fd, filp, on); | 2110 | retval = __tty_fasync(fd, filp, on); |
| 2100 | tty_unlock(); | 2111 | tty_unlock(tty); |
| 2112 | |||
| 2101 | return retval; | 2113 | return retval; |
| 2102 | } | 2114 | } |
| 2103 | 2115 | ||
| @@ -2934,6 +2946,7 @@ void initialize_tty_struct(struct tty_struct *tty, | |||
| 2934 | tty->pgrp = NULL; | 2946 | tty->pgrp = NULL; |
| 2935 | tty->overrun_time = jiffies; | 2947 | tty->overrun_time = jiffies; |
| 2936 | tty_buffer_init(tty); | 2948 | tty_buffer_init(tty); |
| 2949 | mutex_init(&tty->legacy_mutex); | ||
| 2937 | mutex_init(&tty->termios_mutex); | 2950 | mutex_init(&tty->termios_mutex); |
| 2938 | mutex_init(&tty->ldisc_mutex); | 2951 | mutex_init(&tty->ldisc_mutex); |
| 2939 | init_waitqueue_head(&tty->write_wait); | 2952 | init_waitqueue_head(&tty->write_wait); |
