Skip to content

Commit a73d3d6

Browse files
peterhurleygregkh
authored andcommitted
n_tty: Replace canon_data with index comparison
canon_data represented the # of lines which had been copied to the receive buffer but not yet copied to the user buffer. The value was tested to determine if input was available in canonical mode (and also to force input overrun if the receive buffer was full but a newline had not been received). However, the actual count was irrelevent; only whether it was non-zero (meaning 'is there any input to transfer?'). This shared count is unnecessary and unsafe with a lockless algorithm. The same check is made by comparing canon_head with read_tail instead. Signed-off-by: Peter Hurley <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 9356b53 commit a73d3d6

File tree

1 file changed

+6
-16
lines changed

1 file changed

+6
-16
lines changed

drivers/tty/n_tty.c

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ struct n_tty_data {
104104
unsigned int echo_pos;
105105
unsigned int echo_cnt;
106106

107-
int canon_data;
108107
size_t canon_head;
109108
unsigned int canon_column;
110109

@@ -158,7 +157,7 @@ static int receive_room(struct tty_struct *tty)
158157
* characters will be beeped.
159158
*/
160159
if (left <= 0)
161-
left = ldata->icanon && !ldata->canon_data;
160+
left = ldata->icanon && ldata->canon_head == ldata->read_tail;
162161

163162
return left;
164163
}
@@ -237,14 +236,14 @@ static void reset_buffer_flags(struct n_tty_data *ldata)
237236
unsigned long flags;
238237

239238
raw_spin_lock_irqsave(&ldata->read_lock, flags);
240-
ldata->read_head = ldata->read_tail = 0;
239+
ldata->read_head = ldata->canon_head = ldata->read_tail = 0;
241240
raw_spin_unlock_irqrestore(&ldata->read_lock, flags);
242241

243242
mutex_lock(&ldata->echo_lock);
244243
ldata->echo_pos = ldata->echo_cnt = ldata->echo_overrun = 0;
245244
mutex_unlock(&ldata->echo_lock);
246245

247-
ldata->canon_head = ldata->canon_data = ldata->erasing = 0;
246+
ldata->erasing = 0;
248247
bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE);
249248
}
250249

@@ -1360,7 +1359,6 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
13601359
set_bit(ldata->read_head & (N_TTY_BUF_SIZE - 1), ldata->read_flags);
13611360
put_tty_queue_nolock(c, ldata);
13621361
ldata->canon_head = ldata->read_head;
1363-
ldata->canon_data++;
13641362
raw_spin_unlock_irqrestore(&ldata->read_lock, flags);
13651363
kill_fasync(&tty->fasync, SIGIO, POLL_IN);
13661364
if (waitqueue_active(&tty->read_wait))
@@ -1562,7 +1560,6 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
15621560
if (canon_change) {
15631561
bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE);
15641562
ldata->canon_head = ldata->read_tail;
1565-
ldata->canon_data = 0;
15661563
ldata->erasing = 0;
15671564
}
15681565

@@ -1713,7 +1710,7 @@ static inline int input_available_p(struct tty_struct *tty, int amt)
17131710

17141711
tty_flush_to_ldisc(tty);
17151712
if (ldata->icanon && !L_EXTPROC(tty)) {
1716-
if (ldata->canon_data)
1713+
if (ldata->canon_head != ldata->read_tail)
17171714
return 1;
17181715
} else if (read_cnt(ldata) >= (amt ? amt : 1))
17191716
return 1;
@@ -1850,15 +1847,8 @@ static int canon_copy_from_read_buf(struct tty_struct *tty,
18501847

18511848
raw_spin_lock_irqsave(&ldata->read_lock, flags);
18521849
ldata->read_tail += c;
1853-
if (found) {
1850+
if (found)
18541851
__clear_bit(eol, ldata->read_flags);
1855-
/* this test should be redundant:
1856-
* we shouldn't be reading data if
1857-
* canon_data is 0
1858-
*/
1859-
if (--ldata->canon_data < 0)
1860-
ldata->canon_data = 0;
1861-
}
18621852
raw_spin_unlock_irqrestore(&ldata->read_lock, flags);
18631853

18641854
if (found)
@@ -2264,7 +2254,7 @@ static unsigned long inq_canon(struct n_tty_data *ldata)
22642254
{
22652255
size_t nr, head, tail;
22662256

2267-
if (!ldata->canon_data)
2257+
if (ldata->canon_head == ldata->read_tail)
22682258
return 0;
22692259
head = ldata->canon_head;
22702260
tail = ldata->read_tail;

0 commit comments

Comments
 (0)