aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/tty/pty.c4
-rw-r--r--drivers/tty/tty_io.c11
-rw-r--r--include/linux/tty.h3
3 files changed, 10 insertions, 8 deletions
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
index b940127ba1c..25c9bc78372 100644
--- a/drivers/tty/pty.c
+++ b/drivers/tty/pty.c
@@ -281,7 +281,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 */
- down_write(&tty->termios_rwsem);
+ mutex_lock(&tty->winsize_mutex);
if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
goto done;
@@ -308,7 +308,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:
- up_write(&tty->termios_rwsem);
+ mutex_unlock(&tty->winsize_mutex);
return 0;
}
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 2174698dd6f..26bb78c30a0 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -2229,7 +2229,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_rwsem is taken to ensure the winsize data
+ * Locking: tty->winsize_mutex is taken to ensure the winsize data
* is consistent.
*/
@@ -2237,9 +2237,9 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg)
{
int err;
- down_read(&tty->termios_rwsem);
+ mutex_lock(&tty->winsize_mutex);
err = copy_to_user(arg, &tty->winsize, sizeof(*arg));
- up_read(&tty->termios_rwsem);
+ mutex_unlock(&tty->winsize_mutex);
return err ? -EFAULT: 0;
}
@@ -2260,7 +2260,7 @@ int tty_do_resize(struct tty_struct *tty, struct winsize *ws)
unsigned long flags;
/* Lock the tty */
- down_write(&tty->termios_rwsem);
+ mutex_lock(&tty->winsize_mutex);
if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
goto done;
/* Get the PID values and reference them so we can
@@ -2275,7 +2275,7 @@ int tty_do_resize(struct tty_struct *tty, struct winsize *ws)
tty->winsize = *ws;
done:
- up_write(&tty->termios_rwsem);
+ mutex_unlock(&tty->winsize_mutex);
return 0;
}
EXPORT_SYMBOL(tty_do_resize);
@@ -3016,6 +3016,7 @@ void initialize_tty_struct(struct tty_struct *tty,
mutex_init(&tty->legacy_mutex);
mutex_init(&tty->throttle_mutex);
init_rwsem(&tty->termios_rwsem);
+ mutex_init(&tty->winsize_mutex);
init_ldsem(&tty->ldisc_sem);
init_waitqueue_head(&tty->write_wait);
init_waitqueue_head(&tty->read_wait);
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 554b732d8b5..64f864651d8 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -245,6 +245,7 @@ struct tty_struct {
struct mutex legacy_mutex;
struct mutex throttle_mutex;
struct rw_semaphore termios_rwsem;
+ struct mutex winsize_mutex;
spinlock_t ctrl_lock;
/* Termios values are protected by the termios rwsem */
struct ktermios termios, termios_locked;
@@ -254,7 +255,7 @@ struct tty_struct {
struct pid *session;
unsigned long flags;
int count;
- struct winsize winsize; /* termios rwsem */
+ struct winsize winsize; /* winsize_mutex */
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 */