Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 52bce7f8 authored by Peter Hurley's avatar Peter Hurley Committed by Greg Kroah-Hartman
Browse files

pty, n_tty: Simplify input processing on final close



When releasing one end of a pty pair, that end may just have written
to the other, which the input processing worker, flush_to_ldisc(), is
still working on but has not completed the copy to the other end's
read buffer. So input may not appear to be available to a waiting
reader but yet TTY_OTHER_CLOSED is now observed. The n_tty line
discipline has worked around this by waiting for input processing
to complete and then re-checking if input is available before
exiting with -EIO.

Since the tty/ldisc lock reordering, the wait for input processing
to complete can now occur during final close before setting
TTY_OTHER_CLOSED. In this way, a waiting reader is guaranteed to
see input available (if any) before observing TTY_OTHER_CLOSED.

Reviewed-by: default avatarAlan Cox <alan@linux.intel.com>
Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 1bb95415
Loading
Loading
Loading
Loading
+20 −26
Original line number Diff line number Diff line
@@ -2197,14 +2197,9 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,

		if (!input_available_p(tty, 0)) {
			if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
				up_read(&tty->termios_rwsem);
				tty_flush_to_ldisc(tty);
				down_read(&tty->termios_rwsem);
				if (!input_available_p(tty, 0)) {
				retval = -EIO;
				break;
			}
			} else {
			if (tty_hung_up_p(file))
				break;
			if (!timeout)
@@ -2225,7 +2220,6 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
			down_read(&tty->termios_rwsem);
			continue;
		}
		}
		__set_current_state(TASK_RUNNING);

		if (ldata->icanon && !L_EXTPROC(tty)) {
+1 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
	/* Review - krefs on tty_link ?? */
	if (!tty->link)
		return;
	tty_flush_to_ldisc(tty->link);
	set_bit(TTY_OTHER_CLOSED, &tty->link->flags);
	wake_up_interruptible(&tty->link->read_wait);
	wake_up_interruptible(&tty->link->write_wait);