tty: Convert termios_mutex to termios_rwsem
authorPeter Hurley <peter@hurleysoftware.com>
Sat, 15 Jun 2013 13:14:23 +0000 (09:14 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 23 Jul 2013 23:43:01 +0000 (16:43 -0700)
termios is commonly accessed unsafely (especially by N_TTY)
because the existing mutex forces exclusive access.
Convert existing usage.

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/irda/irtty-sir.c
drivers/tty/n_tty.c
drivers/tty/pty.c
drivers/tty/tty_io.c
drivers/tty/tty_ioctl.c
drivers/tty/tty_ldisc.c
drivers/tty/vt/vt.c
include/linux/tty.h

index a41267197839304be5ad0deaa00b93f59e0713e7..177441afeb9680de599905bf75e8c1e10a9c7e0b 100644 (file)
@@ -123,14 +123,14 @@ static int irtty_change_speed(struct sir_dev *dev, unsigned speed)
 
        tty = priv->tty;
 
-       mutex_lock(&tty->termios_mutex);
+       down_write(&tty->termios_rwsem);
        old_termios = tty->termios;
        cflag = tty->termios.c_cflag;
        tty_encode_baud_rate(tty, speed, speed);
        if (tty->ops->set_termios)
                tty->ops->set_termios(tty, &old_termios);
        priv->io.speed = speed;
-       mutex_unlock(&tty->termios_mutex);
+       up_write(&tty->termios_rwsem);
 
        return 0;
 }
@@ -280,7 +280,7 @@ static inline void irtty_stop_receiver(struct tty_struct *tty, int stop)
        struct ktermios old_termios;
        int cflag;
 
-       mutex_lock(&tty->termios_mutex);
+       down_write(&tty->termios_rwsem);
        old_termios = tty->termios;
        cflag = tty->termios.c_cflag;
        
@@ -292,7 +292,7 @@ static inline void irtty_stop_receiver(struct tty_struct *tty, int stop)
        tty->termios.c_cflag = cflag;
        if (tty->ops->set_termios)
                tty->ops->set_termios(tty, &old_termios);
-       mutex_unlock(&tty->termios_mutex);
+       up_write(&tty->termios_rwsem);
 }
 
 /*****************************************************************/
index d159059560e8493c9d3f87ac064917836abefdbe..ab923bb2b262cf6a85b1bcfbc5f8893668fe0d9e 100644 (file)
@@ -1539,7 +1539,7 @@ int is_ignored(int sig)
  *     guaranteed that this function will not be re-entered or in progress
  *     when the ldisc is closed.
  *
- *     Locking: Caller holds tty->termios_mutex
+ *     Locking: Caller holds tty->termios_rwsem
  */
 
 static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
index abfd9908978188ffe3bfd7a9c3aa3e8c6700c5d9..1b39dd639ee9aa0e3290f5b66c17681728f942c0 100644 (file)
@@ -287,7 +287,7 @@ static int pty_resize(struct tty_struct *tty,  struct winsize *ws)
        struct tty_struct *pty = tty->link;
 
        /* For a PTY we need to lock the tty side */
-       mutex_lock(&tty->termios_mutex);
+       down_write(&tty->termios_rwsem);
        if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
                goto done;
 
@@ -314,7 +314,7 @@ static int pty_resize(struct tty_struct *tty,  struct winsize *ws)
        tty->winsize = *ws;
        pty->winsize = *ws;     /* Never used so will go away soon */
 done:
-       mutex_unlock(&tty->termios_mutex);
+       up_write(&tty->termios_rwsem);
        return 0;
 }
 
index 0fa5db4c7a7a9614d055457649f9add9493d95b3..639e24ade9bf349cb86830eae86ddd6cb94e2906 100644 (file)
@@ -604,7 +604,7 @@ static int tty_signal_session_leader(struct tty_struct *tty, int exit_session)
  *               redirect lock for undoing redirection
  *               file list lock for manipulating list of ttys
  *               tty_ldiscs_lock from called functions
- *               termios_mutex resetting termios data
+ *               termios_rwsem resetting termios data
  *               tasklist_lock to walk task list for hangup event
  *                 ->siglock to protect ->signal/->sighand
  */
@@ -2230,7 +2230,7 @@ static int tiocsti(struct tty_struct *tty, char __user *p)
  *
  *     Copies the kernel idea of the window size into the user buffer.
  *
- *     Locking: tty->termios_mutex is taken to ensure the winsize data
+ *     Locking: tty->termios_rwsem is taken to ensure the winsize data
  *             is consistent.
  */
 
@@ -2238,9 +2238,9 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg)
 {
        int err;
 
-       mutex_lock(&tty->termios_mutex);
+       down_read(&tty->termios_rwsem);
        err = copy_to_user(arg, &tty->winsize, sizeof(*arg));
-       mutex_unlock(&tty->termios_mutex);
+       up_read(&tty->termios_rwsem);
 
        return err ? -EFAULT: 0;
 }
@@ -2261,7 +2261,7 @@ int tty_do_resize(struct tty_struct *tty, struct winsize *ws)
        unsigned long flags;
 
        /* Lock the tty */
-       mutex_lock(&tty->termios_mutex);
+       down_write(&tty->termios_rwsem);
        if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
                goto done;
        /* Get the PID values and reference them so we can
@@ -2276,7 +2276,7 @@ int tty_do_resize(struct tty_struct *tty, struct winsize *ws)
 
        tty->winsize = *ws;
 done:
-       mutex_unlock(&tty->termios_mutex);
+       up_write(&tty->termios_rwsem);
        return 0;
 }
 EXPORT_SYMBOL(tty_do_resize);
@@ -3015,7 +3015,7 @@ void initialize_tty_struct(struct tty_struct *tty,
        tty->session = NULL;
        tty->pgrp = NULL;
        mutex_init(&tty->legacy_mutex);
-       mutex_init(&tty->termios_mutex);
+       init_rwsem(&tty->termios_rwsem);
        init_ldsem(&tty->ldisc_sem);
        init_waitqueue_head(&tty->write_wait);
        init_waitqueue_head(&tty->read_wait);
index 3500d41141472394f364b51952f599f31990bd19..9ce20df8a2c8d086a2bbb889d4a47d079008731e 100644 (file)
@@ -94,20 +94,20 @@ EXPORT_SYMBOL(tty_driver_flush_buffer);
  *     @tty: terminal
  *
  *     Indicate that a tty should stop transmitting data down the stack.
- *     Takes the termios mutex to protect against parallel throttle/unthrottle
+ *     Takes the termios rwsem to protect against parallel throttle/unthrottle
  *     and also to ensure the driver can consistently reference its own
  *     termios data at this point when implementing software flow control.
  */
 
 void tty_throttle(struct tty_struct *tty)
 {
-       mutex_lock(&tty->termios_mutex);
+       down_write(&tty->termios_rwsem);
        /* check TTY_THROTTLED first so it indicates our state */
        if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) &&
            tty->ops->throttle)
                tty->ops->throttle(tty);
        tty->flow_change = 0;
-       mutex_unlock(&tty->termios_mutex);
+       up_write(&tty->termios_rwsem);
 }
 EXPORT_SYMBOL(tty_throttle);
 
@@ -116,7 +116,7 @@ EXPORT_SYMBOL(tty_throttle);
  *     @tty: terminal
  *
  *     Indicate that a tty may continue transmitting data down the stack.
- *     Takes the termios mutex to protect against parallel throttle/unthrottle
+ *     Takes the termios rwsem to protect against parallel throttle/unthrottle
  *     and also to ensure the driver can consistently reference its own
  *     termios data at this point when implementing software flow control.
  *
@@ -126,12 +126,12 @@ EXPORT_SYMBOL(tty_throttle);
 
 void tty_unthrottle(struct tty_struct *tty)
 {
-       mutex_lock(&tty->termios_mutex);
+       down_write(&tty->termios_rwsem);
        if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) &&
            tty->ops->unthrottle)
                tty->ops->unthrottle(tty);
        tty->flow_change = 0;
-       mutex_unlock(&tty->termios_mutex);
+       up_write(&tty->termios_rwsem);
 }
 EXPORT_SYMBOL(tty_unthrottle);
 
@@ -151,7 +151,7 @@ int tty_throttle_safe(struct tty_struct *tty)
 {
        int ret = 0;
 
-       mutex_lock(&tty->termios_mutex);
+       down_write(&tty->termios_rwsem);
        if (!test_bit(TTY_THROTTLED, &tty->flags)) {
                if (tty->flow_change != TTY_THROTTLE_SAFE)
                        ret = 1;
@@ -161,7 +161,7 @@ int tty_throttle_safe(struct tty_struct *tty)
                                tty->ops->throttle(tty);
                }
        }
-       mutex_unlock(&tty->termios_mutex);
+       up_write(&tty->termios_rwsem);
 
        return ret;
 }
@@ -182,7 +182,7 @@ int tty_unthrottle_safe(struct tty_struct *tty)
 {
        int ret = 0;
 
-       mutex_lock(&tty->termios_mutex);
+       down_write(&tty->termios_rwsem);
        if (test_bit(TTY_THROTTLED, &tty->flags)) {
                if (tty->flow_change != TTY_UNTHROTTLE_SAFE)
                        ret = 1;
@@ -192,7 +192,7 @@ int tty_unthrottle_safe(struct tty_struct *tty)
                                tty->ops->unthrottle(tty);
                }
        }
-       mutex_unlock(&tty->termios_mutex);
+       up_write(&tty->termios_rwsem);
 
        return ret;
 }
@@ -468,7 +468,7 @@ EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate);
  *     @obad: output baud rate
  *
  *     Update the current termios data for the tty with the new speed
- *     settings. The caller must hold the termios_mutex for the tty in
+ *     settings. The caller must hold the termios_rwsem for the tty in
  *     question.
  */
 
@@ -528,7 +528,7 @@ EXPORT_SYMBOL(tty_termios_hw_change);
  *     is a bit of layering violation here with n_tty in terms of the
  *     internal knowledge of this function.
  *
- *     Locking: termios_mutex
+ *     Locking: termios_rwsem
  */
 
 int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios)
@@ -544,7 +544,7 @@ int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios)
 
        /* FIXME: we need to decide on some locking/ordering semantics
           for the set_termios notification eventually */
-       mutex_lock(&tty->termios_mutex);
+       down_write(&tty->termios_rwsem);
        old_termios = tty->termios;
        tty->termios = *new_termios;
        unset_locked_termios(&tty->termios, &old_termios, &tty->termios_locked);
@@ -586,7 +586,7 @@ int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios)
                        (ld->ops->set_termios)(tty, &old_termios);
                tty_ldisc_deref(ld);
        }
-       mutex_unlock(&tty->termios_mutex);
+       up_write(&tty->termios_rwsem);
        return 0;
 }
 EXPORT_SYMBOL_GPL(tty_set_termios);
@@ -601,7 +601,7 @@ EXPORT_SYMBOL_GPL(tty_set_termios);
  *     functions before using tty_set_termios to do the actual changes.
  *
  *     Locking:
- *             Called functions take ldisc and termios_mutex locks
+ *             Called functions take ldisc and termios_rwsem locks
  */
 
 static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
@@ -613,9 +613,9 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
        if (retval)
                return retval;
 
-       mutex_lock(&tty->termios_mutex);
+       down_read(&tty->termios_rwsem);
        tmp_termios = tty->termios;
-       mutex_unlock(&tty->termios_mutex);
+       up_read(&tty->termios_rwsem);
 
        if (opt & TERMIOS_TERMIO) {
                if (user_termio_to_kernel_termios(&tmp_termios,
@@ -667,16 +667,16 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
 
 static void copy_termios(struct tty_struct *tty, struct ktermios *kterm)
 {
-       mutex_lock(&tty->termios_mutex);
+       down_read(&tty->termios_rwsem);
        *kterm = tty->termios;
-       mutex_unlock(&tty->termios_mutex);
+       up_read(&tty->termios_rwsem);
 }
 
 static void copy_termios_locked(struct tty_struct *tty, struct ktermios *kterm)
 {
-       mutex_lock(&tty->termios_mutex);
+       down_read(&tty->termios_rwsem);
        *kterm = tty->termios_locked;
-       mutex_unlock(&tty->termios_mutex);
+       up_read(&tty->termios_rwsem);
 }
 
 static int get_termio(struct tty_struct *tty, struct termio __user *termio)
@@ -723,10 +723,10 @@ static int set_termiox(struct tty_struct *tty, void __user *arg, int opt)
                        return -ERESTARTSYS;
        }
 
-       mutex_lock(&tty->termios_mutex);
+       down_write(&tty->termios_rwsem);
        if (tty->ops->set_termiox)
                tty->ops->set_termiox(tty, &tnew);
-       mutex_unlock(&tty->termios_mutex);
+       up_write(&tty->termios_rwsem);
        return 0;
 }
 
@@ -761,13 +761,13 @@ static int get_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
 {
        struct sgttyb tmp;
 
-       mutex_lock(&tty->termios_mutex);
+       down_read(&tty->termios_rwsem);
        tmp.sg_ispeed = tty->termios.c_ispeed;
        tmp.sg_ospeed = tty->termios.c_ospeed;
        tmp.sg_erase = tty->termios.c_cc[VERASE];
        tmp.sg_kill = tty->termios.c_cc[VKILL];
        tmp.sg_flags = get_sgflags(tty);
-       mutex_unlock(&tty->termios_mutex);
+       up_read(&tty->termios_rwsem);
 
        return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
 }
@@ -806,7 +806,7 @@ static void set_sgflags(struct ktermios *termios, int flags)
  *     Updates a terminal from the legacy BSD style terminal information
  *     structure.
  *
- *     Locking: termios_mutex
+ *     Locking: termios_rwsem
  */
 
 static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
@@ -822,7 +822,7 @@ static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
        if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
                return -EFAULT;
 
-       mutex_lock(&tty->termios_mutex);
+       down_write(&tty->termios_rwsem);
        termios = tty->termios;
        termios.c_cc[VERASE] = tmp.sg_erase;
        termios.c_cc[VKILL] = tmp.sg_kill;
@@ -832,7 +832,7 @@ static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
        tty_termios_encode_baud_rate(&termios, termios.c_ispeed,
                                                termios.c_ospeed);
 #endif
-       mutex_unlock(&tty->termios_mutex);
+       up_write(&tty->termios_rwsem);
        tty_set_termios(tty, &termios);
        return 0;
 }
@@ -843,14 +843,14 @@ static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars)
 {
        struct tchars tmp;
 
-       mutex_lock(&tty->termios_mutex);
+       down_read(&tty->termios_rwsem);
        tmp.t_intrc = tty->termios.c_cc[VINTR];
        tmp.t_quitc = tty->termios.c_cc[VQUIT];
        tmp.t_startc = tty->termios.c_cc[VSTART];
        tmp.t_stopc = tty->termios.c_cc[VSTOP];
        tmp.t_eofc = tty->termios.c_cc[VEOF];
        tmp.t_brkc = tty->termios.c_cc[VEOL2];  /* what is brkc anyway? */
-       mutex_unlock(&tty->termios_mutex);
+       up_read(&tty->termios_rwsem);
        return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
 }
 
@@ -860,14 +860,14 @@ static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars)
 
        if (copy_from_user(&tmp, tchars, sizeof(tmp)))
                return -EFAULT;
-       mutex_lock(&tty->termios_mutex);
+       down_write(&tty->termios_rwsem);
        tty->termios.c_cc[VINTR] = tmp.t_intrc;
        tty->termios.c_cc[VQUIT] = tmp.t_quitc;
        tty->termios.c_cc[VSTART] = tmp.t_startc;
        tty->termios.c_cc[VSTOP] = tmp.t_stopc;
        tty->termios.c_cc[VEOF] = tmp.t_eofc;
        tty->termios.c_cc[VEOL2] = tmp.t_brkc;  /* what is brkc anyway? */
-       mutex_unlock(&tty->termios_mutex);
+       up_write(&tty->termios_rwsem);
        return 0;
 }
 #endif
@@ -877,7 +877,7 @@ static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
 {
        struct ltchars tmp;
 
-       mutex_lock(&tty->termios_mutex);
+       down_read(&tty->termios_rwsem);
        tmp.t_suspc = tty->termios.c_cc[VSUSP];
        /* what is dsuspc anyway? */
        tmp.t_dsuspc = tty->termios.c_cc[VSUSP];
@@ -886,7 +886,7 @@ static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
        tmp.t_flushc = tty->termios.c_cc[VEOL2];
        tmp.t_werasc = tty->termios.c_cc[VWERASE];
        tmp.t_lnextc = tty->termios.c_cc[VLNEXT];
-       mutex_unlock(&tty->termios_mutex);
+       up_read(&tty->termios_rwsem);
        return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
 }
 
@@ -897,7 +897,7 @@ static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
        if (copy_from_user(&tmp, ltchars, sizeof(tmp)))
                return -EFAULT;
 
-       mutex_lock(&tty->termios_mutex);
+       down_write(&tty->termios_rwsem);
        tty->termios.c_cc[VSUSP] = tmp.t_suspc;
        /* what is dsuspc anyway? */
        tty->termios.c_cc[VEOL2] = tmp.t_dsuspc;
@@ -906,7 +906,7 @@ static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
        tty->termios.c_cc[VEOL2] = tmp.t_flushc;
        tty->termios.c_cc[VWERASE] = tmp.t_werasc;
        tty->termios.c_cc[VLNEXT] = tmp.t_lnextc;
-       mutex_unlock(&tty->termios_mutex);
+       up_write(&tty->termios_rwsem);
        return 0;
 }
 #endif
@@ -946,7 +946,7 @@ static int send_prio_char(struct tty_struct *tty, char ch)
  *     @arg: enable/disable CLOCAL
  *
  *     Perform a change to the CLOCAL state and call into the driver
- *     layer to make it visible. All done with the termios mutex
+ *     layer to make it visible. All done with the termios rwsem
  */
 
 static int tty_change_softcar(struct tty_struct *tty, int arg)
@@ -955,7 +955,7 @@ static int tty_change_softcar(struct tty_struct *tty, int arg)
        int bit = arg ? CLOCAL : 0;
        struct ktermios old;
 
-       mutex_lock(&tty->termios_mutex);
+       down_write(&tty->termios_rwsem);
        old = tty->termios;
        tty->termios.c_cflag &= ~CLOCAL;
        tty->termios.c_cflag |= bit;
@@ -963,7 +963,7 @@ static int tty_change_softcar(struct tty_struct *tty, int arg)
                tty->ops->set_termios(tty, &old);
        if ((tty->termios.c_cflag & CLOCAL) != bit)
                ret = -EINVAL;
-       mutex_unlock(&tty->termios_mutex);
+       up_write(&tty->termios_rwsem);
        return ret;
 }
 
@@ -1066,9 +1066,9 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
                if (user_termios_to_kernel_termios(&kterm,
                                               (struct termios __user *) arg))
                        return -EFAULT;
-               mutex_lock(&real_tty->termios_mutex);
+               down_write(&real_tty->termios_rwsem);
                real_tty->termios_locked = kterm;
-               mutex_unlock(&real_tty->termios_mutex);
+               up_write(&real_tty->termios_rwsem);
                return 0;
 #else
        case TIOCGLCKTRMIOS:
@@ -1083,9 +1083,9 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
                if (user_termios_to_kernel_termios_1(&kterm,
                                               (struct termios __user *) arg))
                        return -EFAULT;
-               mutex_lock(&real_tty->termios_mutex);
+               down_write(&real_tty->termios_rwsem);
                real_tty->termios_locked = kterm;
-               mutex_unlock(&real_tty->termios_mutex);
+               up_write(&real_tty->termios_rwsem);
                return ret;
 #endif
 #ifdef TCGETX
@@ -1093,9 +1093,9 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
                struct termiox ktermx;
                if (real_tty->termiox == NULL)
                        return -EINVAL;
-               mutex_lock(&real_tty->termios_mutex);
+               down_read(&real_tty->termios_rwsem);
                memcpy(&ktermx, real_tty->termiox, sizeof(struct termiox));
-               mutex_unlock(&real_tty->termios_mutex);
+               up_read(&real_tty->termios_rwsem);
                if (copy_to_user(p, &ktermx, sizeof(struct termiox)))
                        ret = -EFAULT;
                return ret;
index e52d615735538b53c785fe8153a83d5bfd56a18c..6458e11e8e9d656daef35b0a5aaddc21dcfd1804 100644 (file)
@@ -415,14 +415,14 @@ EXPORT_SYMBOL_GPL(tty_ldisc_flush);
  *     they are not on hot paths so a little discipline won't do
  *     any harm.
  *
- *     Locking: takes termios_mutex
+ *     Locking: takes termios_rwsem
  */
 
 static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
 {
-       mutex_lock(&tty->termios_mutex);
+       down_write(&tty->termios_rwsem);
        tty->termios.c_line = num;
-       mutex_unlock(&tty->termios_mutex);
+       up_write(&tty->termios_rwsem);
 }
 
 /**
@@ -602,11 +602,11 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
 
 static void tty_reset_termios(struct tty_struct *tty)
 {
-       mutex_lock(&tty->termios_mutex);
+       down_write(&tty->termios_rwsem);
        tty->termios = tty->driver->init_termios;
        tty->termios.c_ispeed = tty_termios_input_baud_rate(&tty->termios);
        tty->termios.c_ospeed = tty_termios_baud_rate(&tty->termios);
-       mutex_unlock(&tty->termios_mutex);
+       up_write(&tty->termios_rwsem);
 }
 
 
index c677829baa8b0d54adfefe1a9276c62ed9f3f03d..02af6ccefe6aca0299efcd86a886303c28e6057e 100644 (file)
@@ -828,7 +828,7 @@ static inline int resize_screen(struct vc_data *vc, int width, int height,
  *     If the caller passes a tty structure then update the termios winsize
  *     information and perform any necessary signal handling.
  *
- *     Caller must hold the console semaphore. Takes the termios mutex and
+ *     Caller must hold the console semaphore. Takes the termios rwsem and
  *     ctrl_lock of the tty IFF a tty is passed.
  */
 
@@ -972,7 +972,7 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int rows)
  *     the actual work.
  *
  *     Takes the console sem and the called methods then take the tty
- *     termios_mutex and the tty ctrl_lock in that order.
+ *     termios_rwsem and the tty ctrl_lock in that order.
  */
 static int vt_resize(struct tty_struct *tty, struct winsize *ws)
 {
index 8323ee4f95b9966afeb38f57e6685943f6e5e719..d3042076d163860f93a8d162766917bfd1136731 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/mutex.h>
 #include <linux/tty_flags.h>
 #include <uapi/linux/tty.h>
+#include <linux/rwsem.h>
 
 
 
@@ -243,9 +244,9 @@ struct tty_struct {
 
        struct mutex atomic_write_lock;
        struct mutex legacy_mutex;
-       struct mutex termios_mutex;
+       struct rw_semaphore termios_rwsem;
        spinlock_t ctrl_lock;
-       /* Termios values are protected by the termios mutex */
+       /* Termios values are protected by the termios rwsem */
        struct ktermios termios, termios_locked;
        struct termiox *termiox;        /* May be NULL for unsupported */
        char name[64];
@@ -253,7 +254,7 @@ struct tty_struct {
        struct pid *session;
        unsigned long flags;
        int count;
-       struct winsize winsize;         /* termios mutex */
+       struct winsize winsize;         /* termios rwsem */
        unsigned char stopped:1, hw_stopped:1, flow_stopped:1, packet:1;
        unsigned char ctrl_status;      /* ctrl_lock */
        unsigned int receive_room;      /* Bytes free for queue */