diff options
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r-- | drivers/char/tty_io.c | 39 |
1 files changed, 15 insertions, 24 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index db15f9ba7c0b..d33e5ab06177 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -1111,9 +1111,7 @@ void tty_write_message(struct tty_struct *tty, char *msg) | |||
1111 | * Locks the line discipline as required | 1111 | * Locks the line discipline as required |
1112 | * Writes to the tty driver are serialized by the atomic_write_lock | 1112 | * Writes to the tty driver are serialized by the atomic_write_lock |
1113 | * and are then processed in chunks to the device. The line discipline | 1113 | * and are then processed in chunks to the device. The line discipline |
1114 | * write method will not be involked in parallel for each device | 1114 | * write method will not be invoked in parallel for each device. |
1115 | * The line discipline write method is called under the big | ||
1116 | * kernel lock for historical reasons. New code should not rely on this. | ||
1117 | */ | 1115 | */ |
1118 | 1116 | ||
1119 | static ssize_t tty_write(struct file *file, const char __user *buf, | 1117 | static ssize_t tty_write(struct file *file, const char __user *buf, |
@@ -1213,7 +1211,7 @@ static void tty_line_name(struct tty_driver *driver, int index, char *p) | |||
1213 | * be held until the 'fast-open' is also done. Will change once we | 1211 | * be held until the 'fast-open' is also done. Will change once we |
1214 | * have refcounting in the driver and per driver locking | 1212 | * have refcounting in the driver and per driver locking |
1215 | */ | 1213 | */ |
1216 | struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, | 1214 | static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, |
1217 | struct inode *inode, int idx) | 1215 | struct inode *inode, int idx) |
1218 | { | 1216 | { |
1219 | struct tty_struct *tty; | 1217 | struct tty_struct *tty; |
@@ -2050,7 +2048,6 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg) | |||
2050 | /** | 2048 | /** |
2051 | * tty_do_resize - resize event | 2049 | * tty_do_resize - resize event |
2052 | * @tty: tty being resized | 2050 | * @tty: tty being resized |
2053 | * @real_tty: real tty (not the same as tty if using a pty/tty pair) | ||
2054 | * @rows: rows (character) | 2051 | * @rows: rows (character) |
2055 | * @cols: cols (character) | 2052 | * @cols: cols (character) |
2056 | * | 2053 | * |
@@ -2058,41 +2055,34 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg) | |||
2058 | * peform a terminal resize correctly | 2055 | * peform a terminal resize correctly |
2059 | */ | 2056 | */ |
2060 | 2057 | ||
2061 | int tty_do_resize(struct tty_struct *tty, struct tty_struct *real_tty, | 2058 | int tty_do_resize(struct tty_struct *tty, struct winsize *ws) |
2062 | struct winsize *ws) | ||
2063 | { | 2059 | { |
2064 | struct pid *pgrp, *rpgrp; | 2060 | struct pid *pgrp; |
2065 | unsigned long flags; | 2061 | unsigned long flags; |
2066 | 2062 | ||
2067 | /* For a PTY we need to lock the tty side */ | 2063 | /* Lock the tty */ |
2068 | mutex_lock(&real_tty->termios_mutex); | 2064 | mutex_lock(&tty->termios_mutex); |
2069 | if (!memcmp(ws, &real_tty->winsize, sizeof(*ws))) | 2065 | if (!memcmp(ws, &tty->winsize, sizeof(*ws))) |
2070 | goto done; | 2066 | goto done; |
2071 | /* Get the PID values and reference them so we can | 2067 | /* Get the PID values and reference them so we can |
2072 | avoid holding the tty ctrl lock while sending signals */ | 2068 | avoid holding the tty ctrl lock while sending signals */ |
2073 | spin_lock_irqsave(&tty->ctrl_lock, flags); | 2069 | spin_lock_irqsave(&tty->ctrl_lock, flags); |
2074 | pgrp = get_pid(tty->pgrp); | 2070 | pgrp = get_pid(tty->pgrp); |
2075 | rpgrp = get_pid(real_tty->pgrp); | ||
2076 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 2071 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
2077 | 2072 | ||
2078 | if (pgrp) | 2073 | if (pgrp) |
2079 | kill_pgrp(pgrp, SIGWINCH, 1); | 2074 | kill_pgrp(pgrp, SIGWINCH, 1); |
2080 | if (rpgrp != pgrp && rpgrp) | ||
2081 | kill_pgrp(rpgrp, SIGWINCH, 1); | ||
2082 | |||
2083 | put_pid(pgrp); | 2075 | put_pid(pgrp); |
2084 | put_pid(rpgrp); | ||
2085 | 2076 | ||
2086 | tty->winsize = *ws; | 2077 | tty->winsize = *ws; |
2087 | real_tty->winsize = *ws; | ||
2088 | done: | 2078 | done: |
2089 | mutex_unlock(&real_tty->termios_mutex); | 2079 | mutex_unlock(&tty->termios_mutex); |
2090 | return 0; | 2080 | return 0; |
2091 | } | 2081 | } |
2092 | 2082 | ||
2093 | /** | 2083 | /** |
2094 | * tiocswinsz - implement window size set ioctl | 2084 | * tiocswinsz - implement window size set ioctl |
2095 | * @tty; tty | 2085 | * @tty; tty side of tty |
2096 | * @arg: user buffer for result | 2086 | * @arg: user buffer for result |
2097 | * | 2087 | * |
2098 | * Copies the user idea of the window size to the kernel. Traditionally | 2088 | * Copies the user idea of the window size to the kernel. Traditionally |
@@ -2105,17 +2095,16 @@ done: | |||
2105 | * then calls into the default method. | 2095 | * then calls into the default method. |
2106 | */ | 2096 | */ |
2107 | 2097 | ||
2108 | static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, | 2098 | static int tiocswinsz(struct tty_struct *tty, struct winsize __user *arg) |
2109 | struct winsize __user *arg) | ||
2110 | { | 2099 | { |
2111 | struct winsize tmp_ws; | 2100 | struct winsize tmp_ws; |
2112 | if (copy_from_user(&tmp_ws, arg, sizeof(*arg))) | 2101 | if (copy_from_user(&tmp_ws, arg, sizeof(*arg))) |
2113 | return -EFAULT; | 2102 | return -EFAULT; |
2114 | 2103 | ||
2115 | if (tty->ops->resize) | 2104 | if (tty->ops->resize) |
2116 | return tty->ops->resize(tty, real_tty, &tmp_ws); | 2105 | return tty->ops->resize(tty, &tmp_ws); |
2117 | else | 2106 | else |
2118 | return tty_do_resize(tty, real_tty, &tmp_ws); | 2107 | return tty_do_resize(tty, &tmp_ws); |
2119 | } | 2108 | } |
2120 | 2109 | ||
2121 | /** | 2110 | /** |
@@ -2540,7 +2529,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
2540 | case TIOCGWINSZ: | 2529 | case TIOCGWINSZ: |
2541 | return tiocgwinsz(real_tty, p); | 2530 | return tiocgwinsz(real_tty, p); |
2542 | case TIOCSWINSZ: | 2531 | case TIOCSWINSZ: |
2543 | return tiocswinsz(tty, real_tty, p); | 2532 | return tiocswinsz(real_tty, p); |
2544 | case TIOCCONS: | 2533 | case TIOCCONS: |
2545 | return real_tty != tty ? -EINVAL : tioccons(file); | 2534 | return real_tty != tty ? -EINVAL : tioccons(file); |
2546 | case FIONBIO: | 2535 | case FIONBIO: |
@@ -2785,6 +2774,8 @@ void initialize_tty_struct(struct tty_struct *tty, | |||
2785 | INIT_WORK(&tty->hangup_work, do_tty_hangup); | 2774 | INIT_WORK(&tty->hangup_work, do_tty_hangup); |
2786 | mutex_init(&tty->atomic_read_lock); | 2775 | mutex_init(&tty->atomic_read_lock); |
2787 | mutex_init(&tty->atomic_write_lock); | 2776 | mutex_init(&tty->atomic_write_lock); |
2777 | mutex_init(&tty->output_lock); | ||
2778 | mutex_init(&tty->echo_lock); | ||
2788 | spin_lock_init(&tty->read_lock); | 2779 | spin_lock_init(&tty->read_lock); |
2789 | spin_lock_init(&tty->ctrl_lock); | 2780 | spin_lock_init(&tty->ctrl_lock); |
2790 | INIT_LIST_HEAD(&tty->tty_files); | 2781 | INIT_LIST_HEAD(&tty->tty_files); |