@@ -1491,10 +1491,14 @@ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp,
14911491 * canonical mode and don't have a newline yet!
14921492 */
14931493 while (1 ) {
1494+ int throttled ;
14941495 tty_set_flow_change (tty , TTY_THROTTLE_SAFE );
14951496 if (receive_room (tty ) >= TTY_THRESHOLD_THROTTLE )
14961497 break ;
1497- if (!tty_throttle_safe (tty ))
1498+ up_read (& tty -> termios_rwsem );
1499+ throttled = tty_throttle_safe (tty );
1500+ down_read (& tty -> termios_rwsem );
1501+ if (!throttled )
14981502 break ;
14991503 }
15001504 __tty_set_flow_change (tty , 0 );
@@ -1503,7 +1507,9 @@ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp,
15031507static void n_tty_receive_buf (struct tty_struct * tty , const unsigned char * cp ,
15041508 char * fp , int count )
15051509{
1510+ down_read (& tty -> termios_rwsem );
15061511 __receive_buf (tty , cp , fp , count );
1512+ up_read (& tty -> termios_rwsem );
15071513}
15081514
15091515static int n_tty_receive_buf2 (struct tty_struct * tty , const unsigned char * cp ,
@@ -1512,13 +1518,17 @@ static int n_tty_receive_buf2(struct tty_struct *tty, const unsigned char *cp,
15121518 struct n_tty_data * ldata = tty -> disc_data ;
15131519 int room ;
15141520
1521+ down_read (& tty -> termios_rwsem );
1522+
15151523 tty -> receive_room = room = receive_room (tty );
15161524 if (!room )
15171525 ldata -> no_room = 1 ;
15181526 count = min (count , room );
15191527 if (count )
15201528 __receive_buf (tty , cp , fp , count );
15211529
1530+ up_read (& tty -> termios_rwsem );
1531+
15221532 return count ;
15231533}
15241534
@@ -1934,6 +1944,8 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
19341944 if (c < 0 )
19351945 return c ;
19361946
1947+ down_read (& tty -> termios_rwsem );
1948+
19371949 minimum = time = 0 ;
19381950 timeout = MAX_SCHEDULE_TIMEOUT ;
19391951 if (!ldata -> icanon ) {
@@ -1955,11 +1967,15 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
19551967 * Internal serialization of reads.
19561968 */
19571969 if (file -> f_flags & O_NONBLOCK ) {
1958- if (!mutex_trylock (& ldata -> atomic_read_lock ))
1970+ if (!mutex_trylock (& ldata -> atomic_read_lock )) {
1971+ up_read (& tty -> termios_rwsem );
19591972 return - EAGAIN ;
1973+ }
19601974 } else {
1961- if (mutex_lock_interruptible (& ldata -> atomic_read_lock ))
1975+ if (mutex_lock_interruptible (& ldata -> atomic_read_lock )) {
1976+ up_read (& tty -> termios_rwsem );
19621977 return - ERESTARTSYS ;
1978+ }
19631979 }
19641980 packet = tty -> packet ;
19651981
@@ -2009,7 +2025,11 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
20092025 break ;
20102026 }
20112027 n_tty_set_room (tty );
2028+ up_read (& tty -> termios_rwsem );
2029+
20122030 timeout = schedule_timeout (timeout );
2031+
2032+ down_read (& tty -> termios_rwsem );
20132033 continue ;
20142034 }
20152035 __set_current_state (TASK_RUNNING );
@@ -2048,13 +2068,17 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
20482068 * we won't get any more characters.
20492069 */
20502070 while (1 ) {
2071+ int unthrottled ;
20512072 tty_set_flow_change (tty , TTY_UNTHROTTLE_SAFE );
20522073 if (chars_in_buffer (tty ) > TTY_THRESHOLD_UNTHROTTLE )
20532074 break ;
20542075 if (!tty -> count )
20552076 break ;
20562077 n_tty_set_room (tty );
2057- if (!tty_unthrottle_safe (tty ))
2078+ up_read (& tty -> termios_rwsem );
2079+ unthrottled = tty_unthrottle_safe (tty );
2080+ down_read (& tty -> termios_rwsem );
2081+ if (!unthrottled )
20582082 break ;
20592083 }
20602084 __tty_set_flow_change (tty , 0 );
@@ -2076,10 +2100,13 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
20762100 retval = size ;
20772101 if (nr )
20782102 clear_bit (TTY_PUSH , & tty -> flags );
2079- } else if (test_and_clear_bit (TTY_PUSH , & tty -> flags ))
2103+ } else if (test_and_clear_bit (TTY_PUSH , & tty -> flags )) {
2104+ up_read (& tty -> termios_rwsem );
20802105 goto do_it_again ;
2106+ }
20812107
20822108 n_tty_set_room (tty );
2109+ up_read (& tty -> termios_rwsem );
20832110 return retval ;
20842111}
20852112
@@ -2120,6 +2147,8 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file,
21202147 return retval ;
21212148 }
21222149
2150+ down_read (& tty -> termios_rwsem );
2151+
21232152 /* Write out any echoed characters that are still pending */
21242153 process_echoes (tty );
21252154
@@ -2173,13 +2202,18 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file,
21732202 retval = - EAGAIN ;
21742203 break ;
21752204 }
2205+ up_read (& tty -> termios_rwsem );
2206+
21762207 schedule ();
2208+
2209+ down_read (& tty -> termios_rwsem );
21772210 }
21782211break_out :
21792212 __set_current_state (TASK_RUNNING );
21802213 remove_wait_queue (& tty -> write_wait , & wait );
21812214 if (b - buf != nr && tty -> fasync )
21822215 set_bit (TTY_DO_WRITE_WAKEUP , & tty -> flags );
2216+ up_read (& tty -> termios_rwsem );
21832217 return (b - buf ) ? b - buf : retval ;
21842218}
21852219
0 commit comments