]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - drivers/tty/tty_ioctl.c
tty: Convert termios_mutex to termios_rwsem
[mirror_ubuntu-artful-kernel.git] / drivers / tty / tty_ioctl.c
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;