diff options
Diffstat (limited to 'drivers/tty/tty_io.c')
-rw-r--r-- | drivers/tty/tty_io.c | 101 |
1 files changed, 62 insertions, 39 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index b425c79675ad..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,10 +1404,14 @@ 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; |
1409 | 1411 | ||
1412 | if (!tty->port) | ||
1413 | tty->port = driver->ports[idx]; | ||
1414 | |||
1410 | /* | 1415 | /* |
1411 | * Structures all installed ... call the ldisc open routines. | 1416 | * Structures all installed ... call the ldisc open routines. |
1412 | * If we fail here just call release_tty to clean up. No need | 1417 | * If we fail here just call release_tty to clean up. No need |
@@ -1415,9 +1420,11 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) | |||
1415 | retval = tty_ldisc_setup(tty, tty->link); | 1420 | retval = tty_ldisc_setup(tty, tty->link); |
1416 | if (retval) | 1421 | if (retval) |
1417 | goto err_release_tty; | 1422 | goto err_release_tty; |
1423 | /* Return the tty locked so that it cannot vanish under the caller */ | ||
1418 | return tty; | 1424 | return tty; |
1419 | 1425 | ||
1420 | err_deinit_tty: | 1426 | err_deinit_tty: |
1427 | tty_unlock(tty); | ||
1421 | deinitialize_tty_struct(tty); | 1428 | deinitialize_tty_struct(tty); |
1422 | free_tty_struct(tty); | 1429 | free_tty_struct(tty); |
1423 | err_module_put: | 1430 | err_module_put: |
@@ -1426,6 +1433,7 @@ err_module_put: | |||
1426 | 1433 | ||
1427 | /* call the tty release_tty routine to clean out this slot */ | 1434 | /* call the tty release_tty routine to clean out this slot */ |
1428 | err_release_tty: | 1435 | err_release_tty: |
1436 | tty_unlock(tty); | ||
1429 | printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, " | 1437 | printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, " |
1430 | "clearing slot %d\n", idx); | 1438 | "clearing slot %d\n", idx); |
1431 | release_tty(tty, idx); | 1439 | release_tty(tty, idx); |
@@ -1628,7 +1636,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1628 | if (tty_paranoia_check(tty, inode, __func__)) | 1636 | if (tty_paranoia_check(tty, inode, __func__)) |
1629 | return 0; | 1637 | return 0; |
1630 | 1638 | ||
1631 | tty_lock(); | 1639 | tty_lock(tty); |
1632 | check_tty_count(tty, __func__); | 1640 | check_tty_count(tty, __func__); |
1633 | 1641 | ||
1634 | __tty_fasync(-1, filp, 0); | 1642 | __tty_fasync(-1, filp, 0); |
@@ -1637,10 +1645,11 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1637 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 1645 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
1638 | tty->driver->subtype == PTY_TYPE_MASTER); | 1646 | tty->driver->subtype == PTY_TYPE_MASTER); |
1639 | devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; | 1647 | devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; |
1648 | /* Review: parallel close */ | ||
1640 | o_tty = tty->link; | 1649 | o_tty = tty->link; |
1641 | 1650 | ||
1642 | if (tty_release_checks(tty, o_tty, idx)) { | 1651 | if (tty_release_checks(tty, o_tty, idx)) { |
1643 | tty_unlock(); | 1652 | tty_unlock(tty); |
1644 | return 0; | 1653 | return 0; |
1645 | } | 1654 | } |
1646 | 1655 | ||
@@ -1652,7 +1661,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1652 | if (tty->ops->close) | 1661 | if (tty->ops->close) |
1653 | tty->ops->close(tty, filp); | 1662 | tty->ops->close(tty, filp); |
1654 | 1663 | ||
1655 | tty_unlock(); | 1664 | tty_unlock(tty); |
1656 | /* | 1665 | /* |
1657 | * 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 |
1658 | * 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 |
@@ -1675,7 +1684,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1675 | opens on /dev/tty */ | 1684 | opens on /dev/tty */ |
1676 | 1685 | ||
1677 | mutex_lock(&tty_mutex); | 1686 | mutex_lock(&tty_mutex); |
1678 | tty_lock(); | 1687 | tty_lock_pair(tty, o_tty); |
1679 | tty_closing = tty->count <= 1; | 1688 | tty_closing = tty->count <= 1; |
1680 | o_tty_closing = o_tty && | 1689 | o_tty_closing = o_tty && |
1681 | (o_tty->count <= (pty_master ? 1 : 0)); | 1690 | (o_tty->count <= (pty_master ? 1 : 0)); |
@@ -1706,7 +1715,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1706 | 1715 | ||
1707 | printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", | 1716 | printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", |
1708 | __func__, tty_name(tty, buf)); | 1717 | __func__, tty_name(tty, buf)); |
1709 | tty_unlock(); | 1718 | tty_unlock_pair(tty, o_tty); |
1710 | mutex_unlock(&tty_mutex); | 1719 | mutex_unlock(&tty_mutex); |
1711 | schedule(); | 1720 | schedule(); |
1712 | } | 1721 | } |
@@ -1769,7 +1778,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1769 | 1778 | ||
1770 | /* check whether both sides are closing ... */ | 1779 | /* check whether both sides are closing ... */ |
1771 | if (!tty_closing || (o_tty && !o_tty_closing)) { | 1780 | if (!tty_closing || (o_tty && !o_tty_closing)) { |
1772 | tty_unlock(); | 1781 | tty_unlock_pair(tty, o_tty); |
1773 | return 0; | 1782 | return 0; |
1774 | } | 1783 | } |
1775 | 1784 | ||
@@ -1782,14 +1791,16 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1782 | tty_ldisc_release(tty, o_tty); | 1791 | tty_ldisc_release(tty, o_tty); |
1783 | /* | 1792 | /* |
1784 | * The release_tty function takes care of the details of clearing | 1793 | * The release_tty function takes care of the details of clearing |
1785 | * 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). | ||
1786 | */ | 1797 | */ |
1787 | release_tty(tty, idx); | 1798 | release_tty(tty, idx); |
1799 | tty_unlock_pair(tty, o_tty); | ||
1788 | 1800 | ||
1789 | /* Make this pty number available for reallocation */ | 1801 | /* Make this pty number available for reallocation */ |
1790 | if (devpts) | 1802 | if (devpts) |
1791 | devpts_kill_index(inode, idx); | 1803 | devpts_kill_index(inode, idx); |
1792 | tty_unlock(); | ||
1793 | return 0; | 1804 | return 0; |
1794 | } | 1805 | } |
1795 | 1806 | ||
@@ -1893,6 +1904,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. | 1904 | * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev. |
1894 | * tty->count should protect the rest. | 1905 | * tty->count should protect the rest. |
1895 | * ->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 | ||
1896 | */ | 1910 | */ |
1897 | 1911 | ||
1898 | static int tty_open(struct inode *inode, struct file *filp) | 1912 | static int tty_open(struct inode *inode, struct file *filp) |
@@ -1916,8 +1930,7 @@ retry_open: | |||
1916 | retval = 0; | 1930 | retval = 0; |
1917 | 1931 | ||
1918 | mutex_lock(&tty_mutex); | 1932 | mutex_lock(&tty_mutex); |
1919 | tty_lock(); | 1933 | /* This is protected by the tty_mutex */ |
1920 | |||
1921 | tty = tty_open_current_tty(device, filp); | 1934 | tty = tty_open_current_tty(device, filp); |
1922 | if (IS_ERR(tty)) { | 1935 | if (IS_ERR(tty)) { |
1923 | retval = PTR_ERR(tty); | 1936 | retval = PTR_ERR(tty); |
@@ -1938,17 +1951,19 @@ retry_open: | |||
1938 | } | 1951 | } |
1939 | 1952 | ||
1940 | if (tty) { | 1953 | if (tty) { |
1954 | tty_lock(tty); | ||
1941 | retval = tty_reopen(tty); | 1955 | retval = tty_reopen(tty); |
1942 | if (retval) | 1956 | if (retval < 0) { |
1957 | tty_unlock(tty); | ||
1943 | tty = ERR_PTR(retval); | 1958 | tty = ERR_PTR(retval); |
1944 | } else | 1959 | } |
1960 | } else /* Returns with the tty_lock held for now */ | ||
1945 | tty = tty_init_dev(driver, index); | 1961 | tty = tty_init_dev(driver, index); |
1946 | 1962 | ||
1947 | mutex_unlock(&tty_mutex); | 1963 | mutex_unlock(&tty_mutex); |
1948 | if (driver) | 1964 | if (driver) |
1949 | tty_driver_kref_put(driver); | 1965 | tty_driver_kref_put(driver); |
1950 | if (IS_ERR(tty)) { | 1966 | if (IS_ERR(tty)) { |
1951 | tty_unlock(); | ||
1952 | retval = PTR_ERR(tty); | 1967 | retval = PTR_ERR(tty); |
1953 | goto err_file; | 1968 | goto err_file; |
1954 | } | 1969 | } |
@@ -1977,7 +1992,7 @@ retry_open: | |||
1977 | printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, | 1992 | printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, |
1978 | retval, tty->name); | 1993 | retval, tty->name); |
1979 | #endif | 1994 | #endif |
1980 | tty_unlock(); /* need to call tty_release without BTM */ | 1995 | tty_unlock(tty); /* need to call tty_release without BTM */ |
1981 | tty_release(inode, filp); | 1996 | tty_release(inode, filp); |
1982 | if (retval != -ERESTARTSYS) | 1997 | if (retval != -ERESTARTSYS) |
1983 | return retval; | 1998 | return retval; |
@@ -1989,17 +2004,15 @@ retry_open: | |||
1989 | /* | 2004 | /* |
1990 | * Need to reset f_op in case a hangup happened. | 2005 | * Need to reset f_op in case a hangup happened. |
1991 | */ | 2006 | */ |
1992 | tty_lock(); | ||
1993 | if (filp->f_op == &hung_up_tty_fops) | 2007 | if (filp->f_op == &hung_up_tty_fops) |
1994 | filp->f_op = &tty_fops; | 2008 | filp->f_op = &tty_fops; |
1995 | tty_unlock(); | ||
1996 | goto retry_open; | 2009 | goto retry_open; |
1997 | } | 2010 | } |
1998 | tty_unlock(); | 2011 | tty_unlock(tty); |
1999 | 2012 | ||
2000 | 2013 | ||
2001 | mutex_lock(&tty_mutex); | 2014 | mutex_lock(&tty_mutex); |
2002 | tty_lock(); | 2015 | tty_lock(tty); |
2003 | spin_lock_irq(¤t->sighand->siglock); | 2016 | spin_lock_irq(¤t->sighand->siglock); |
2004 | if (!noctty && | 2017 | if (!noctty && |
2005 | current->signal->leader && | 2018 | current->signal->leader && |
@@ -2007,11 +2020,10 @@ retry_open: | |||
2007 | tty->session == NULL) | 2020 | tty->session == NULL) |
2008 | __proc_set_tty(current, tty); | 2021 | __proc_set_tty(current, tty); |
2009 | spin_unlock_irq(¤t->sighand->siglock); | 2022 | spin_unlock_irq(¤t->sighand->siglock); |
2010 | tty_unlock(); | 2023 | tty_unlock(tty); |
2011 | mutex_unlock(&tty_mutex); | 2024 | mutex_unlock(&tty_mutex); |
2012 | return 0; | 2025 | return 0; |
2013 | err_unlock: | 2026 | err_unlock: |
2014 | tty_unlock(); | ||
2015 | mutex_unlock(&tty_mutex); | 2027 | mutex_unlock(&tty_mutex); |
2016 | /* after locks to avoid deadlock */ | 2028 | /* after locks to avoid deadlock */ |
2017 | if (!IS_ERR_OR_NULL(driver)) | 2029 | if (!IS_ERR_OR_NULL(driver)) |
@@ -2094,10 +2106,13 @@ out: | |||
2094 | 2106 | ||
2095 | static int tty_fasync(int fd, struct file *filp, int on) | 2107 | static int tty_fasync(int fd, struct file *filp, int on) |
2096 | { | 2108 | { |
2109 | struct tty_struct *tty = file_tty(filp); | ||
2097 | int retval; | 2110 | int retval; |
2098 | tty_lock(); | 2111 | |
2112 | tty_lock(tty); | ||
2099 | retval = __tty_fasync(fd, filp, on); | 2113 | retval = __tty_fasync(fd, filp, on); |
2100 | tty_unlock(); | 2114 | tty_unlock(tty); |
2115 | |||
2101 | return retval; | 2116 | return retval; |
2102 | } | 2117 | } |
2103 | 2118 | ||
@@ -2934,6 +2949,7 @@ void initialize_tty_struct(struct tty_struct *tty, | |||
2934 | tty->pgrp = NULL; | 2949 | tty->pgrp = NULL; |
2935 | tty->overrun_time = jiffies; | 2950 | tty->overrun_time = jiffies; |
2936 | tty_buffer_init(tty); | 2951 | tty_buffer_init(tty); |
2952 | mutex_init(&tty->legacy_mutex); | ||
2937 | mutex_init(&tty->termios_mutex); | 2953 | mutex_init(&tty->termios_mutex); |
2938 | mutex_init(&tty->ldisc_mutex); | 2954 | mutex_init(&tty->ldisc_mutex); |
2939 | init_waitqueue_head(&tty->write_wait); | 2955 | init_waitqueue_head(&tty->write_wait); |
@@ -3094,6 +3110,7 @@ static void destruct_tty_driver(struct kref *kref) | |||
3094 | kfree(p); | 3110 | kfree(p); |
3095 | cdev_del(&driver->cdev); | 3111 | cdev_del(&driver->cdev); |
3096 | } | 3112 | } |
3113 | kfree(driver->ports); | ||
3097 | kfree(driver); | 3114 | kfree(driver); |
3098 | } | 3115 | } |
3099 | 3116 | ||
@@ -3132,6 +3149,18 @@ int tty_register_driver(struct tty_driver *driver) | |||
3132 | if (!p) | 3149 | if (!p) |
3133 | return -ENOMEM; | 3150 | return -ENOMEM; |
3134 | } | 3151 | } |
3152 | /* | ||
3153 | * There is too many lines in PTY and we won't need the array there | ||
3154 | * since it has an ->install hook where it assigns ports properly. | ||
3155 | */ | ||
3156 | if (driver->type != TTY_DRIVER_TYPE_PTY) { | ||
3157 | driver->ports = kcalloc(driver->num, sizeof(struct tty_port *), | ||
3158 | GFP_KERNEL); | ||
3159 | if (!driver->ports) { | ||
3160 | error = -ENOMEM; | ||
3161 | goto err_free_p; | ||
3162 | } | ||
3163 | } | ||
3135 | 3164 | ||
3136 | if (!driver->major) { | 3165 | if (!driver->major) { |
3137 | error = alloc_chrdev_region(&dev, driver->minor_start, | 3166 | error = alloc_chrdev_region(&dev, driver->minor_start, |
@@ -3144,10 +3173,8 @@ int tty_register_driver(struct tty_driver *driver) | |||
3144 | dev = MKDEV(driver->major, driver->minor_start); | 3173 | dev = MKDEV(driver->major, driver->minor_start); |
3145 | error = register_chrdev_region(dev, driver->num, driver->name); | 3174 | error = register_chrdev_region(dev, driver->num, driver->name); |
3146 | } | 3175 | } |
3147 | if (error < 0) { | 3176 | if (error < 0) |
3148 | kfree(p); | 3177 | goto err_free_p; |
3149 | return error; | ||
3150 | } | ||
3151 | 3178 | ||
3152 | if (p) { | 3179 | if (p) { |
3153 | driver->ttys = (struct tty_struct **)p; | 3180 | driver->ttys = (struct tty_struct **)p; |
@@ -3160,13 +3187,8 @@ int tty_register_driver(struct tty_driver *driver) | |||
3160 | cdev_init(&driver->cdev, &tty_fops); | 3187 | cdev_init(&driver->cdev, &tty_fops); |
3161 | driver->cdev.owner = driver->owner; | 3188 | driver->cdev.owner = driver->owner; |
3162 | error = cdev_add(&driver->cdev, dev, driver->num); | 3189 | error = cdev_add(&driver->cdev, dev, driver->num); |
3163 | if (error) { | 3190 | if (error) |
3164 | unregister_chrdev_region(dev, driver->num); | 3191 | goto err_unreg_char; |
3165 | driver->ttys = NULL; | ||
3166 | driver->termios = NULL; | ||
3167 | kfree(p); | ||
3168 | return error; | ||
3169 | } | ||
3170 | 3192 | ||
3171 | mutex_lock(&tty_mutex); | 3193 | mutex_lock(&tty_mutex); |
3172 | list_add(&driver->tty_drivers, &tty_drivers); | 3194 | list_add(&driver->tty_drivers, &tty_drivers); |
@@ -3193,13 +3215,14 @@ err: | |||
3193 | list_del(&driver->tty_drivers); | 3215 | list_del(&driver->tty_drivers); |
3194 | mutex_unlock(&tty_mutex); | 3216 | mutex_unlock(&tty_mutex); |
3195 | 3217 | ||
3218 | err_unreg_char: | ||
3196 | unregister_chrdev_region(dev, driver->num); | 3219 | unregister_chrdev_region(dev, driver->num); |
3197 | driver->ttys = NULL; | 3220 | driver->ttys = NULL; |
3198 | driver->termios = NULL; | 3221 | driver->termios = NULL; |
3222 | err_free_p: /* destruct_tty_driver will free driver->ports */ | ||
3199 | kfree(p); | 3223 | kfree(p); |
3200 | return error; | 3224 | return error; |
3201 | } | 3225 | } |
3202 | |||
3203 | EXPORT_SYMBOL(tty_register_driver); | 3226 | EXPORT_SYMBOL(tty_register_driver); |
3204 | 3227 | ||
3205 | /* | 3228 | /* |