diff options
author | Arnd Bergmann <arnd@arndb.de> | 2010-06-01 16:53:01 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-08-10 16:47:43 -0400 |
commit | ec79d6056de58511d8e46d9ae59d3878f958dc3e (patch) | |
tree | 8e73cf399c4cb3c31dbf3caced385cfc018a706a /drivers/char/tty_io.c | |
parent | 3f582b8c11014e4ce310d9839fb335164195333f (diff) |
tty: replace BKL with a new tty_lock
As a preparation for replacing the big kernel lock
in the TTY layer, wrap all the callers in new
macros tty_lock, tty_lock_nested and tty_unlock.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r-- | drivers/char/tty_io.c | 115 |
1 files changed, 64 insertions, 51 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 507441ac6edb..5ee9081a560f 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -149,6 +149,7 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd, | |||
149 | #else | 149 | #else |
150 | #define tty_compat_ioctl NULL | 150 | #define tty_compat_ioctl NULL |
151 | #endif | 151 | #endif |
152 | static int __tty_fasync(int fd, struct file *filp, int on); | ||
152 | static int tty_fasync(int fd, struct file *filp, int on); | 153 | static int tty_fasync(int fd, struct file *filp, int on); |
153 | static void release_tty(struct tty_struct *tty, int idx); | 154 | static void release_tty(struct tty_struct *tty, int idx); |
154 | static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); | 155 | static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); |
@@ -483,7 +484,7 @@ EXPORT_SYMBOL_GPL(tty_wakeup); | |||
483 | * remains intact. | 484 | * remains intact. |
484 | * | 485 | * |
485 | * Locking: | 486 | * Locking: |
486 | * BKL | 487 | * BTM |
487 | * redirect lock for undoing redirection | 488 | * redirect lock for undoing redirection |
488 | * file list lock for manipulating list of ttys | 489 | * file list lock for manipulating list of ttys |
489 | * tty_ldisc_lock from called functions | 490 | * tty_ldisc_lock from called functions |
@@ -513,8 +514,11 @@ static void do_tty_hangup(struct work_struct *work) | |||
513 | } | 514 | } |
514 | spin_unlock(&redirect_lock); | 515 | spin_unlock(&redirect_lock); |
515 | 516 | ||
516 | /* inuse_filps is protected by the single kernel lock */ | 517 | /* inuse_filps is protected by the single tty lock, |
517 | lock_kernel(); | 518 | this really needs to change if we want to flush the |
519 | workqueue with the lock held */ | ||
520 | tty_lock_nested(); /* called with BTM held from pty_close and | ||
521 | others */ | ||
518 | check_tty_count(tty, "do_tty_hangup"); | 522 | check_tty_count(tty, "do_tty_hangup"); |
519 | 523 | ||
520 | file_list_lock(); | 524 | file_list_lock(); |
@@ -525,7 +529,7 @@ static void do_tty_hangup(struct work_struct *work) | |||
525 | if (filp->f_op->write != tty_write) | 529 | if (filp->f_op->write != tty_write) |
526 | continue; | 530 | continue; |
527 | closecount++; | 531 | closecount++; |
528 | tty_fasync(-1, filp, 0); /* can't block */ | 532 | __tty_fasync(-1, filp, 0); /* can't block */ |
529 | filp->f_op = &hung_up_tty_fops; | 533 | filp->f_op = &hung_up_tty_fops; |
530 | } | 534 | } |
531 | file_list_unlock(); | 535 | file_list_unlock(); |
@@ -594,7 +598,7 @@ static void do_tty_hangup(struct work_struct *work) | |||
594 | */ | 598 | */ |
595 | set_bit(TTY_HUPPED, &tty->flags); | 599 | set_bit(TTY_HUPPED, &tty->flags); |
596 | tty_ldisc_enable(tty); | 600 | tty_ldisc_enable(tty); |
597 | unlock_kernel(); | 601 | tty_unlock(); |
598 | if (f) | 602 | if (f) |
599 | fput(f); | 603 | fput(f); |
600 | } | 604 | } |
@@ -696,7 +700,8 @@ static void session_clear_tty(struct pid *session) | |||
696 | * exiting; it is 0 if called by the ioctl TIOCNOTTY. | 700 | * exiting; it is 0 if called by the ioctl TIOCNOTTY. |
697 | * | 701 | * |
698 | * Locking: | 702 | * Locking: |
699 | * BKL is taken for hysterical raisins | 703 | * BTM is taken for hysterical raisins, and held when |
704 | * called from no_tty(). | ||
700 | * tty_mutex is taken to protect tty | 705 | * tty_mutex is taken to protect tty |
701 | * ->siglock is taken to protect ->signal/->sighand | 706 | * ->siglock is taken to protect ->signal/->sighand |
702 | * tasklist_lock is taken to walk process list for sessions | 707 | * tasklist_lock is taken to walk process list for sessions |
@@ -714,10 +719,10 @@ void disassociate_ctty(int on_exit) | |||
714 | tty = get_current_tty(); | 719 | tty = get_current_tty(); |
715 | if (tty) { | 720 | if (tty) { |
716 | tty_pgrp = get_pid(tty->pgrp); | 721 | tty_pgrp = get_pid(tty->pgrp); |
717 | lock_kernel(); | 722 | tty_lock_nested(); /* see above */ |
718 | if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) | 723 | if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) |
719 | tty_vhangup(tty); | 724 | tty_vhangup(tty); |
720 | unlock_kernel(); | 725 | tty_unlock(); |
721 | tty_kref_put(tty); | 726 | tty_kref_put(tty); |
722 | } else if (on_exit) { | 727 | } else if (on_exit) { |
723 | struct pid *old_pgrp; | 728 | struct pid *old_pgrp; |
@@ -774,9 +779,9 @@ void disassociate_ctty(int on_exit) | |||
774 | void no_tty(void) | 779 | void no_tty(void) |
775 | { | 780 | { |
776 | struct task_struct *tsk = current; | 781 | struct task_struct *tsk = current; |
777 | lock_kernel(); | 782 | tty_lock(); |
778 | disassociate_ctty(0); | 783 | disassociate_ctty(0); |
779 | unlock_kernel(); | 784 | tty_unlock(); |
780 | proc_clear_tty(tsk); | 785 | proc_clear_tty(tsk); |
781 | } | 786 | } |
782 | 787 | ||
@@ -1013,19 +1018,19 @@ out: | |||
1013 | * We don't put it into the syslog queue right now maybe in the future if | 1018 | * We don't put it into the syslog queue right now maybe in the future if |
1014 | * really needed. | 1019 | * really needed. |
1015 | * | 1020 | * |
1016 | * We must still hold the BKL and test the CLOSING flag for the moment. | 1021 | * We must still hold the BTM and test the CLOSING flag for the moment. |
1017 | */ | 1022 | */ |
1018 | 1023 | ||
1019 | void tty_write_message(struct tty_struct *tty, char *msg) | 1024 | void tty_write_message(struct tty_struct *tty, char *msg) |
1020 | { | 1025 | { |
1021 | if (tty) { | 1026 | if (tty) { |
1022 | mutex_lock(&tty->atomic_write_lock); | 1027 | mutex_lock(&tty->atomic_write_lock); |
1023 | lock_kernel(); | 1028 | tty_lock(); |
1024 | if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) { | 1029 | if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) { |
1025 | unlock_kernel(); | 1030 | tty_unlock(); |
1026 | tty->ops->write(tty, msg, strlen(msg)); | 1031 | tty->ops->write(tty, msg, strlen(msg)); |
1027 | } else | 1032 | } else |
1028 | unlock_kernel(); | 1033 | tty_unlock(); |
1029 | tty_write_unlock(tty); | 1034 | tty_write_unlock(tty); |
1030 | } | 1035 | } |
1031 | return; | 1036 | return; |
@@ -1208,18 +1213,18 @@ static int tty_driver_install_tty(struct tty_driver *driver, | |||
1208 | int ret; | 1213 | int ret; |
1209 | 1214 | ||
1210 | if (driver->ops->install) { | 1215 | if (driver->ops->install) { |
1211 | lock_kernel(); | 1216 | tty_lock_nested(); /* already called with BTM held */ |
1212 | ret = driver->ops->install(driver, tty); | 1217 | ret = driver->ops->install(driver, tty); |
1213 | unlock_kernel(); | 1218 | tty_unlock(); |
1214 | return ret; | 1219 | return ret; |
1215 | } | 1220 | } |
1216 | 1221 | ||
1217 | if (tty_init_termios(tty) == 0) { | 1222 | if (tty_init_termios(tty) == 0) { |
1218 | lock_kernel(); | 1223 | tty_lock_nested(); |
1219 | tty_driver_kref_get(driver); | 1224 | tty_driver_kref_get(driver); |
1220 | tty->count++; | 1225 | tty->count++; |
1221 | driver->ttys[idx] = tty; | 1226 | driver->ttys[idx] = tty; |
1222 | unlock_kernel(); | 1227 | tty_unlock(); |
1223 | return 0; | 1228 | return 0; |
1224 | } | 1229 | } |
1225 | return -ENOMEM; | 1230 | return -ENOMEM; |
@@ -1312,14 +1317,15 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, | |||
1312 | struct tty_struct *tty; | 1317 | struct tty_struct *tty; |
1313 | int retval; | 1318 | int retval; |
1314 | 1319 | ||
1315 | lock_kernel(); | 1320 | tty_lock_nested(); /* always called with tty lock held already */ |
1321 | |||
1316 | /* Check if pty master is being opened multiple times */ | 1322 | /* Check if pty master is being opened multiple times */ |
1317 | if (driver->subtype == PTY_TYPE_MASTER && | 1323 | if (driver->subtype == PTY_TYPE_MASTER && |
1318 | (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) { | 1324 | (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) { |
1319 | unlock_kernel(); | 1325 | tty_unlock(); |
1320 | return ERR_PTR(-EIO); | 1326 | return ERR_PTR(-EIO); |
1321 | } | 1327 | } |
1322 | unlock_kernel(); | 1328 | tty_unlock(); |
1323 | 1329 | ||
1324 | /* | 1330 | /* |
1325 | * First time open is complex, especially for PTY devices. | 1331 | * First time open is complex, especially for PTY devices. |
@@ -1363,9 +1369,9 @@ release_mem_out: | |||
1363 | if (printk_ratelimit()) | 1369 | if (printk_ratelimit()) |
1364 | printk(KERN_INFO "tty_init_dev: ldisc open failed, " | 1370 | printk(KERN_INFO "tty_init_dev: ldisc open failed, " |
1365 | "clearing slot %d\n", idx); | 1371 | "clearing slot %d\n", idx); |
1366 | lock_kernel(); | 1372 | tty_lock_nested(); |
1367 | release_tty(tty, idx); | 1373 | release_tty(tty, idx); |
1368 | unlock_kernel(); | 1374 | tty_unlock(); |
1369 | return ERR_PTR(retval); | 1375 | return ERR_PTR(retval); |
1370 | } | 1376 | } |
1371 | 1377 | ||
@@ -1512,10 +1518,10 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1512 | if (tty_paranoia_check(tty, inode, "tty_release_dev")) | 1518 | if (tty_paranoia_check(tty, inode, "tty_release_dev")) |
1513 | return 0; | 1519 | return 0; |
1514 | 1520 | ||
1515 | lock_kernel(); | 1521 | tty_lock(); |
1516 | check_tty_count(tty, "tty_release_dev"); | 1522 | check_tty_count(tty, "tty_release_dev"); |
1517 | 1523 | ||
1518 | tty_fasync(-1, filp, 0); | 1524 | __tty_fasync(-1, filp, 0); |
1519 | 1525 | ||
1520 | idx = tty->index; | 1526 | idx = tty->index; |
1521 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 1527 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
@@ -1527,18 +1533,18 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1527 | if (idx < 0 || idx >= tty->driver->num) { | 1533 | if (idx < 0 || idx >= tty->driver->num) { |
1528 | printk(KERN_DEBUG "tty_release_dev: bad idx when trying to " | 1534 | printk(KERN_DEBUG "tty_release_dev: bad idx when trying to " |
1529 | "free (%s)\n", tty->name); | 1535 | "free (%s)\n", tty->name); |
1530 | unlock_kernel(); | 1536 | tty_unlock(); |
1531 | return 0; | 1537 | return 0; |
1532 | } | 1538 | } |
1533 | if (!devpts) { | 1539 | if (!devpts) { |
1534 | if (tty != tty->driver->ttys[idx]) { | 1540 | if (tty != tty->driver->ttys[idx]) { |
1535 | unlock_kernel(); | 1541 | tty_unlock(); |
1536 | printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty " | 1542 | printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty " |
1537 | "for (%s)\n", idx, tty->name); | 1543 | "for (%s)\n", idx, tty->name); |
1538 | return 0; | 1544 | return 0; |
1539 | } | 1545 | } |
1540 | if (tty->termios != tty->driver->termios[idx]) { | 1546 | if (tty->termios != tty->driver->termios[idx]) { |
1541 | unlock_kernel(); | 1547 | tty_unlock(); |
1542 | printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios " | 1548 | printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios " |
1543 | "for (%s)\n", | 1549 | "for (%s)\n", |
1544 | idx, tty->name); | 1550 | idx, tty->name); |
@@ -1556,21 +1562,21 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1556 | if (tty->driver->other && | 1562 | if (tty->driver->other && |
1557 | !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { | 1563 | !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { |
1558 | if (o_tty != tty->driver->other->ttys[idx]) { | 1564 | if (o_tty != tty->driver->other->ttys[idx]) { |
1559 | unlock_kernel(); | 1565 | tty_unlock(); |
1560 | printk(KERN_DEBUG "tty_release_dev: other->table[%d] " | 1566 | printk(KERN_DEBUG "tty_release_dev: other->table[%d] " |
1561 | "not o_tty for (%s)\n", | 1567 | "not o_tty for (%s)\n", |
1562 | idx, tty->name); | 1568 | idx, tty->name); |
1563 | return 0 ; | 1569 | return 0 ; |
1564 | } | 1570 | } |
1565 | if (o_tty->termios != tty->driver->other->termios[idx]) { | 1571 | if (o_tty->termios != tty->driver->other->termios[idx]) { |
1566 | unlock_kernel(); | 1572 | tty_unlock(); |
1567 | printk(KERN_DEBUG "tty_release_dev: other->termios[%d] " | 1573 | printk(KERN_DEBUG "tty_release_dev: other->termios[%d] " |
1568 | "not o_termios for (%s)\n", | 1574 | "not o_termios for (%s)\n", |
1569 | idx, tty->name); | 1575 | idx, tty->name); |
1570 | return 0; | 1576 | return 0; |
1571 | } | 1577 | } |
1572 | if (o_tty->link != tty) { | 1578 | if (o_tty->link != tty) { |
1573 | unlock_kernel(); | 1579 | tty_unlock(); |
1574 | printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n"); | 1580 | printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n"); |
1575 | return 0; | 1581 | return 0; |
1576 | } | 1582 | } |
@@ -1579,7 +1585,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1579 | if (tty->ops->close) | 1585 | if (tty->ops->close) |
1580 | tty->ops->close(tty, filp); | 1586 | tty->ops->close(tty, filp); |
1581 | 1587 | ||
1582 | unlock_kernel(); | 1588 | tty_unlock(); |
1583 | /* | 1589 | /* |
1584 | * Sanity check: if tty->count is going to zero, there shouldn't be | 1590 | * Sanity check: if tty->count is going to zero, there shouldn't be |
1585 | * any waiters on tty->read_wait or tty->write_wait. We test the | 1591 | * any waiters on tty->read_wait or tty->write_wait. We test the |
@@ -1602,7 +1608,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1602 | opens on /dev/tty */ | 1608 | opens on /dev/tty */ |
1603 | 1609 | ||
1604 | mutex_lock(&tty_mutex); | 1610 | mutex_lock(&tty_mutex); |
1605 | lock_kernel(); | 1611 | tty_lock(); |
1606 | tty_closing = tty->count <= 1; | 1612 | tty_closing = tty->count <= 1; |
1607 | o_tty_closing = o_tty && | 1613 | o_tty_closing = o_tty && |
1608 | (o_tty->count <= (pty_master ? 1 : 0)); | 1614 | (o_tty->count <= (pty_master ? 1 : 0)); |
@@ -1633,7 +1639,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1633 | 1639 | ||
1634 | printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue " | 1640 | printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue " |
1635 | "active!\n", tty_name(tty, buf)); | 1641 | "active!\n", tty_name(tty, buf)); |
1636 | unlock_kernel(); | 1642 | tty_unlock(); |
1637 | mutex_unlock(&tty_mutex); | 1643 | mutex_unlock(&tty_mutex); |
1638 | schedule(); | 1644 | schedule(); |
1639 | } | 1645 | } |
@@ -1698,7 +1704,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1698 | 1704 | ||
1699 | /* check whether both sides are closing ... */ | 1705 | /* check whether both sides are closing ... */ |
1700 | if (!tty_closing || (o_tty && !o_tty_closing)) { | 1706 | if (!tty_closing || (o_tty && !o_tty_closing)) { |
1701 | unlock_kernel(); | 1707 | tty_unlock(); |
1702 | return 0; | 1708 | return 0; |
1703 | } | 1709 | } |
1704 | 1710 | ||
@@ -1718,7 +1724,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1718 | /* Make this pty number available for reallocation */ | 1724 | /* Make this pty number available for reallocation */ |
1719 | if (devpts) | 1725 | if (devpts) |
1720 | devpts_kill_index(inode, idx); | 1726 | devpts_kill_index(inode, idx); |
1721 | unlock_kernel(); | 1727 | tty_unlock(); |
1722 | return 0; | 1728 | return 0; |
1723 | } | 1729 | } |
1724 | 1730 | ||
@@ -1760,12 +1766,12 @@ retry_open: | |||
1760 | retval = 0; | 1766 | retval = 0; |
1761 | 1767 | ||
1762 | mutex_lock(&tty_mutex); | 1768 | mutex_lock(&tty_mutex); |
1763 | lock_kernel(); | 1769 | tty_lock(); |
1764 | 1770 | ||
1765 | if (device == MKDEV(TTYAUX_MAJOR, 0)) { | 1771 | if (device == MKDEV(TTYAUX_MAJOR, 0)) { |
1766 | tty = get_current_tty(); | 1772 | tty = get_current_tty(); |
1767 | if (!tty) { | 1773 | if (!tty) { |
1768 | unlock_kernel(); | 1774 | tty_unlock(); |
1769 | mutex_unlock(&tty_mutex); | 1775 | mutex_unlock(&tty_mutex); |
1770 | return -ENXIO; | 1776 | return -ENXIO; |
1771 | } | 1777 | } |
@@ -1797,14 +1803,14 @@ retry_open: | |||
1797 | goto got_driver; | 1803 | goto got_driver; |
1798 | } | 1804 | } |
1799 | } | 1805 | } |
1800 | unlock_kernel(); | 1806 | tty_unlock(); |
1801 | mutex_unlock(&tty_mutex); | 1807 | mutex_unlock(&tty_mutex); |
1802 | return -ENODEV; | 1808 | return -ENODEV; |
1803 | } | 1809 | } |
1804 | 1810 | ||
1805 | driver = get_tty_driver(device, &index); | 1811 | driver = get_tty_driver(device, &index); |
1806 | if (!driver) { | 1812 | if (!driver) { |
1807 | unlock_kernel(); | 1813 | tty_unlock(); |
1808 | mutex_unlock(&tty_mutex); | 1814 | mutex_unlock(&tty_mutex); |
1809 | return -ENODEV; | 1815 | return -ENODEV; |
1810 | } | 1816 | } |
@@ -1814,7 +1820,7 @@ got_driver: | |||
1814 | tty = tty_driver_lookup_tty(driver, inode, index); | 1820 | tty = tty_driver_lookup_tty(driver, inode, index); |
1815 | 1821 | ||
1816 | if (IS_ERR(tty)) { | 1822 | if (IS_ERR(tty)) { |
1817 | unlock_kernel(); | 1823 | tty_unlock(); |
1818 | mutex_unlock(&tty_mutex); | 1824 | mutex_unlock(&tty_mutex); |
1819 | return PTR_ERR(tty); | 1825 | return PTR_ERR(tty); |
1820 | } | 1826 | } |
@@ -1830,7 +1836,7 @@ got_driver: | |||
1830 | mutex_unlock(&tty_mutex); | 1836 | mutex_unlock(&tty_mutex); |
1831 | tty_driver_kref_put(driver); | 1837 | tty_driver_kref_put(driver); |
1832 | if (IS_ERR(tty)) { | 1838 | if (IS_ERR(tty)) { |
1833 | unlock_kernel(); | 1839 | tty_unlock(); |
1834 | return PTR_ERR(tty); | 1840 | return PTR_ERR(tty); |
1835 | } | 1841 | } |
1836 | 1842 | ||
@@ -1862,11 +1868,11 @@ got_driver: | |||
1862 | #endif | 1868 | #endif |
1863 | tty_release(inode, filp); | 1869 | tty_release(inode, filp); |
1864 | if (retval != -ERESTARTSYS) { | 1870 | if (retval != -ERESTARTSYS) { |
1865 | unlock_kernel(); | 1871 | tty_unlock(); |
1866 | return retval; | 1872 | return retval; |
1867 | } | 1873 | } |
1868 | if (signal_pending(current)) { | 1874 | if (signal_pending(current)) { |
1869 | unlock_kernel(); | 1875 | tty_unlock(); |
1870 | return retval; | 1876 | return retval; |
1871 | } | 1877 | } |
1872 | schedule(); | 1878 | schedule(); |
@@ -1875,14 +1881,14 @@ got_driver: | |||
1875 | */ | 1881 | */ |
1876 | if (filp->f_op == &hung_up_tty_fops) | 1882 | if (filp->f_op == &hung_up_tty_fops) |
1877 | filp->f_op = &tty_fops; | 1883 | filp->f_op = &tty_fops; |
1878 | unlock_kernel(); | 1884 | tty_unlock(); |
1879 | goto retry_open; | 1885 | goto retry_open; |
1880 | } | 1886 | } |
1881 | unlock_kernel(); | 1887 | tty_unlock(); |
1882 | 1888 | ||
1883 | 1889 | ||
1884 | mutex_lock(&tty_mutex); | 1890 | mutex_lock(&tty_mutex); |
1885 | lock_kernel(); | 1891 | tty_lock(); |
1886 | spin_lock_irq(¤t->sighand->siglock); | 1892 | spin_lock_irq(¤t->sighand->siglock); |
1887 | if (!noctty && | 1893 | if (!noctty && |
1888 | current->signal->leader && | 1894 | current->signal->leader && |
@@ -1890,7 +1896,7 @@ got_driver: | |||
1890 | tty->session == NULL) | 1896 | tty->session == NULL) |
1891 | __proc_set_tty(current, tty); | 1897 | __proc_set_tty(current, tty); |
1892 | spin_unlock_irq(¤t->sighand->siglock); | 1898 | spin_unlock_irq(¤t->sighand->siglock); |
1893 | unlock_kernel(); | 1899 | tty_unlock(); |
1894 | mutex_unlock(&tty_mutex); | 1900 | mutex_unlock(&tty_mutex); |
1895 | return 0; | 1901 | return 0; |
1896 | } | 1902 | } |
@@ -1926,13 +1932,12 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait) | |||
1926 | return ret; | 1932 | return ret; |
1927 | } | 1933 | } |
1928 | 1934 | ||
1929 | static int tty_fasync(int fd, struct file *filp, int on) | 1935 | static int __tty_fasync(int fd, struct file *filp, int on) |
1930 | { | 1936 | { |
1931 | struct tty_struct *tty; | 1937 | struct tty_struct *tty; |
1932 | unsigned long flags; | 1938 | unsigned long flags; |
1933 | int retval = 0; | 1939 | int retval = 0; |
1934 | 1940 | ||
1935 | lock_kernel(); | ||
1936 | tty = (struct tty_struct *)filp->private_data; | 1941 | tty = (struct tty_struct *)filp->private_data; |
1937 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync")) | 1942 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync")) |
1938 | goto out; | 1943 | goto out; |
@@ -1966,7 +1971,15 @@ static int tty_fasync(int fd, struct file *filp, int on) | |||
1966 | } | 1971 | } |
1967 | retval = 0; | 1972 | retval = 0; |
1968 | out: | 1973 | out: |
1969 | unlock_kernel(); | 1974 | return retval; |
1975 | } | ||
1976 | |||
1977 | static int tty_fasync(int fd, struct file *filp, int on) | ||
1978 | { | ||
1979 | int retval; | ||
1980 | tty_lock(); | ||
1981 | retval = __tty_fasync(fd, filp, on); | ||
1982 | tty_unlock(); | ||
1970 | return retval; | 1983 | return retval; |
1971 | } | 1984 | } |
1972 | 1985 | ||