mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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: Alan Cox <alan@linux.intel.com> Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
		
							parent
							
								
									1bb954153a
								
							
						
					
					
						commit
						52bce7f8d4
					
				
					 2 changed files with 22 additions and 27 deletions
				
			
		| 
						 | 
				
			
			@ -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)) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue