@@ -96,8 +96,8 @@ struct n_tty_data {
96
96
DECLARE_BITMAP (read_flags , N_TTY_BUF_SIZE );
97
97
98
98
char * read_buf ;
99
- int read_head ;
100
- int read_tail ;
99
+ size_t read_head ;
100
+ size_t read_tail ;
101
101
int read_cnt ;
102
102
int minimum_to_wake ;
103
103
@@ -106,7 +106,7 @@ struct n_tty_data {
106
106
unsigned int echo_cnt ;
107
107
108
108
int canon_data ;
109
- unsigned long canon_head ;
109
+ size_t canon_head ;
110
110
unsigned int canon_column ;
111
111
112
112
struct mutex atomic_read_lock ;
@@ -120,6 +120,16 @@ static inline size_t read_cnt(struct n_tty_data *ldata)
120
120
return ldata -> read_cnt ;
121
121
}
122
122
123
+ static inline unsigned char read_buf (struct n_tty_data * ldata , size_t i )
124
+ {
125
+ return ldata -> read_buf [i & (N_TTY_BUF_SIZE - 1 )];
126
+ }
127
+
128
+ static inline unsigned char * read_buf_addr (struct n_tty_data * ldata , size_t i )
129
+ {
130
+ return & ldata -> read_buf [i & (N_TTY_BUF_SIZE - 1 )];
131
+ }
132
+
123
133
static inline int tty_put_user (struct tty_struct * tty , unsigned char x ,
124
134
unsigned char __user * ptr )
125
135
{
@@ -186,8 +196,8 @@ static void n_tty_set_room(struct tty_struct *tty)
186
196
static void put_tty_queue_nolock (unsigned char c , struct n_tty_data * ldata )
187
197
{
188
198
if (read_cnt (ldata ) < N_TTY_BUF_SIZE ) {
189
- ldata -> read_buf [ ldata -> read_head ] = c ;
190
- ldata -> read_head = ( ldata -> read_head + 1 ) & ( N_TTY_BUF_SIZE - 1 ) ;
199
+ * read_buf_addr ( ldata , ldata -> read_head ) = c ;
200
+ ldata -> read_head ++ ;
191
201
ldata -> read_cnt ++ ;
192
202
}
193
203
}
@@ -289,13 +299,10 @@ static ssize_t chars_in_buffer(struct tty_struct *tty)
289
299
ssize_t n = 0 ;
290
300
291
301
raw_spin_lock_irqsave (& ldata -> read_lock , flags );
292
- if (!ldata -> icanon ) {
302
+ if (!ldata -> icanon )
293
303
n = read_cnt (ldata );
294
- } else if (ldata -> canon_data ) {
295
- n = (ldata -> canon_head > ldata -> read_tail ) ?
296
- ldata -> canon_head - ldata -> read_tail :
297
- ldata -> canon_head + (N_TTY_BUF_SIZE - ldata -> read_tail );
298
- }
304
+ else
305
+ n = ldata -> canon_head - ldata -> read_tail ;
299
306
raw_spin_unlock_irqrestore (& ldata -> read_lock , flags );
300
307
return n ;
301
308
}
@@ -918,7 +925,9 @@ static void eraser(unsigned char c, struct tty_struct *tty)
918
925
{
919
926
struct n_tty_data * ldata = tty -> disc_data ;
920
927
enum { ERASE , WERASE , KILL } kill_type ;
921
- int head , seen_alnums , cnt ;
928
+ size_t head ;
929
+ size_t cnt ;
930
+ int seen_alnums ;
922
931
unsigned long flags ;
923
932
924
933
/* FIXME: locking needed ? */
@@ -962,8 +971,8 @@ static void eraser(unsigned char c, struct tty_struct *tty)
962
971
963
972
/* erase a single possibly multibyte character */
964
973
do {
965
- head = ( head - 1 ) & ( N_TTY_BUF_SIZE - 1 ) ;
966
- c = ldata -> read_buf [ head ] ;
974
+ head -- ;
975
+ c = read_buf ( ldata , head ) ;
967
976
} while (is_continuation (c , tty ) && head != ldata -> canon_head );
968
977
969
978
/* do not partially erase */
@@ -977,7 +986,7 @@ static void eraser(unsigned char c, struct tty_struct *tty)
977
986
else if (seen_alnums )
978
987
break ;
979
988
}
980
- cnt = ( ldata -> read_head - head ) & ( N_TTY_BUF_SIZE - 1 ) ;
989
+ cnt = ldata -> read_head - head ;
981
990
raw_spin_lock_irqsave (& ldata -> read_lock , flags );
982
991
ldata -> read_head = head ;
983
992
ldata -> read_cnt -= cnt ;
@@ -991,17 +1000,16 @@ static void eraser(unsigned char c, struct tty_struct *tty)
991
1000
/* if cnt > 1, output a multi-byte character */
992
1001
echo_char (c , tty );
993
1002
while (-- cnt > 0 ) {
994
- head = (head + 1 ) & (N_TTY_BUF_SIZE - 1 );
995
- echo_char_raw (ldata -> read_buf [head ],
996
- ldata );
1003
+ head ++ ;
1004
+ echo_char_raw (read_buf (ldata , head ), ldata );
997
1005
echo_move_back_col (ldata );
998
1006
}
999
1007
} else if (kill_type == ERASE && !L_ECHOE (tty )) {
1000
1008
echo_char (ERASE_CHAR (tty ), tty );
1001
1009
} else if (c == '\t' ) {
1002
1010
unsigned int num_chars = 0 ;
1003
1011
int after_tab = 0 ;
1004
- unsigned long tail = ldata -> read_head ;
1012
+ size_t tail = ldata -> read_head ;
1005
1013
1006
1014
/*
1007
1015
* Count the columns used for characters
@@ -1011,8 +1019,8 @@ static void eraser(unsigned char c, struct tty_struct *tty)
1011
1019
* number of columns.
1012
1020
*/
1013
1021
while (tail != ldata -> canon_head ) {
1014
- tail = ( tail - 1 ) & ( N_TTY_BUF_SIZE - 1 ) ;
1015
- c = ldata -> read_buf [ tail ] ;
1022
+ tail -- ;
1023
+ c = read_buf ( ldata , tail ) ;
1016
1024
if (c == '\t' ) {
1017
1025
after_tab = 1 ;
1018
1026
break ;
@@ -1296,14 +1304,14 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
1296
1304
}
1297
1305
if (c == REPRINT_CHAR (tty ) && L_ECHO (tty ) &&
1298
1306
L_IEXTEN (tty )) {
1299
- unsigned long tail = ldata -> canon_head ;
1307
+ size_t tail = ldata -> canon_head ;
1300
1308
1301
1309
finish_erasing (ldata );
1302
1310
echo_char (c , tty );
1303
1311
echo_char_raw ('\n' , ldata );
1304
1312
while (tail != ldata -> read_head ) {
1305
- echo_char (ldata -> read_buf [ tail ] , tty );
1306
- tail = ( tail + 1 ) & ( N_TTY_BUF_SIZE - 1 ) ;
1313
+ echo_char (read_buf ( ldata , tail ) , tty );
1314
+ tail ++ ;
1307
1315
}
1308
1316
process_echoes (tty );
1309
1317
return ;
@@ -1356,7 +1364,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
1356
1364
1357
1365
handle_newline :
1358
1366
raw_spin_lock_irqsave (& ldata -> read_lock , flags );
1359
- set_bit (ldata -> read_head , ldata -> read_flags );
1367
+ set_bit (ldata -> read_head & ( N_TTY_BUF_SIZE - 1 ) , ldata -> read_flags );
1360
1368
put_tty_queue_nolock (c , ldata );
1361
1369
ldata -> canon_head = ldata -> read_head ;
1362
1370
ldata -> canon_data ++ ;
@@ -1436,19 +1444,19 @@ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp,
1436
1444
if (ldata -> real_raw ) {
1437
1445
raw_spin_lock_irqsave (& ldata -> read_lock , cpuflags );
1438
1446
i = min (N_TTY_BUF_SIZE - read_cnt (ldata ),
1439
- N_TTY_BUF_SIZE - ldata -> read_head );
1447
+ N_TTY_BUF_SIZE - ( ldata -> read_head & ( N_TTY_BUF_SIZE - 1 )) );
1440
1448
i = min (count , i );
1441
- memcpy (ldata -> read_buf + ldata -> read_head , cp , i );
1442
- ldata -> read_head = ( ldata -> read_head + i ) & ( N_TTY_BUF_SIZE - 1 ) ;
1449
+ memcpy (read_buf_addr ( ldata , ldata -> read_head ) , cp , i );
1450
+ ldata -> read_head += i ;
1443
1451
ldata -> read_cnt += i ;
1444
1452
cp += i ;
1445
1453
count -= i ;
1446
1454
1447
1455
i = min (N_TTY_BUF_SIZE - read_cnt (ldata ),
1448
- N_TTY_BUF_SIZE - ldata -> read_head );
1456
+ N_TTY_BUF_SIZE - ( ldata -> read_head & ( N_TTY_BUF_SIZE - 1 )) );
1449
1457
i = min (count , i );
1450
- memcpy (ldata -> read_buf + ldata -> read_head , cp , i );
1451
- ldata -> read_head = ( ldata -> read_head + i ) & ( N_TTY_BUF_SIZE - 1 ) ;
1458
+ memcpy (read_buf_addr ( ldata , ldata -> read_head ) , cp , i );
1459
+ ldata -> read_head += i ;
1452
1460
ldata -> read_cnt += i ;
1453
1461
raw_spin_unlock_irqrestore (& ldata -> read_lock , cpuflags );
1454
1462
} else {
@@ -1739,21 +1747,21 @@ static int copy_from_read_buf(struct tty_struct *tty,
1739
1747
size_t n ;
1740
1748
unsigned long flags ;
1741
1749
bool is_eof ;
1750
+ size_t tail = ldata -> read_tail & (N_TTY_BUF_SIZE - 1 );
1742
1751
1743
1752
retval = 0 ;
1744
1753
raw_spin_lock_irqsave (& ldata -> read_lock , flags );
1745
- n = min (read_cnt (ldata ), N_TTY_BUF_SIZE - ldata -> read_tail );
1754
+ n = min (read_cnt (ldata ), N_TTY_BUF_SIZE - tail );
1746
1755
n = min (* nr , n );
1747
1756
raw_spin_unlock_irqrestore (& ldata -> read_lock , flags );
1748
1757
if (n ) {
1749
- retval = copy_to_user (* b , & ldata -> read_buf [ ldata -> read_tail ] , n );
1758
+ retval = copy_to_user (* b , read_buf_addr ( ldata , tail ) , n );
1750
1759
n -= retval ;
1751
- is_eof = n == 1 &&
1752
- ldata -> read_buf [ldata -> read_tail ] == EOF_CHAR (tty );
1753
- tty_audit_add_data (tty , & ldata -> read_buf [ldata -> read_tail ], n ,
1760
+ is_eof = n == 1 && read_buf (ldata , tail ) == EOF_CHAR (tty );
1761
+ tty_audit_add_data (tty , read_buf_addr (ldata , tail ), n ,
1754
1762
ldata -> icanon );
1755
1763
raw_spin_lock_irqsave (& ldata -> read_lock , flags );
1756
- ldata -> read_tail = ( ldata -> read_tail + n ) & ( N_TTY_BUF_SIZE - 1 ) ;
1764
+ ldata -> read_tail += n ;
1757
1765
ldata -> read_cnt -= n ;
1758
1766
/* Turn single EOF into zero-length read */
1759
1767
if (L_EXTPROC (tty ) && ldata -> icanon && is_eof && !read_cnt (ldata ))
@@ -1785,8 +1793,9 @@ static int canon_copy_from_read_buf(struct tty_struct *tty,
1785
1793
struct n_tty_data * ldata = tty -> disc_data ;
1786
1794
unsigned long flags ;
1787
1795
size_t n , size , more , c ;
1788
- unsigned long eol ;
1789
- int ret , tail , found = 0 ;
1796
+ size_t eol ;
1797
+ size_t tail ;
1798
+ int ret , found = 0 ;
1790
1799
1791
1800
/* N.B. avoid overrun if nr == 0 */
1792
1801
@@ -1798,10 +1807,10 @@ static int canon_copy_from_read_buf(struct tty_struct *tty,
1798
1807
return 0 ;
1799
1808
}
1800
1809
1801
- tail = ldata -> read_tail ;
1810
+ tail = ldata -> read_tail & ( N_TTY_BUF_SIZE - 1 ) ;
1802
1811
size = min_t (size_t , tail + n , N_TTY_BUF_SIZE );
1803
1812
1804
- n_tty_trace ("%s: nr:%zu tail:%d n:%zu size:%zu\n" ,
1813
+ n_tty_trace ("%s: nr:%zu tail:%zu n:%zu size:%zu\n" ,
1805
1814
__func__ , * nr , tail , n , size );
1806
1815
1807
1816
eol = find_next_bit (ldata -> read_flags , size , tail );
@@ -1818,29 +1827,29 @@ static int canon_copy_from_read_buf(struct tty_struct *tty,
1818
1827
n = (found + eol + size ) & (N_TTY_BUF_SIZE - 1 );
1819
1828
c = n ;
1820
1829
1821
- if (found && ldata -> read_buf [ eol ] == __DISABLED_CHAR )
1830
+ if (found && read_buf ( ldata , eol ) == __DISABLED_CHAR )
1822
1831
n -- ;
1823
1832
1824
- n_tty_trace ("%s: eol:%lu found:%d n:%zu c:%zu size:%zu more:%zu\n" ,
1833
+ n_tty_trace ("%s: eol:%zu found:%d n:%zu c:%zu size:%zu more:%zu\n" ,
1825
1834
__func__ , eol , found , n , c , size , more );
1826
1835
1827
1836
raw_spin_unlock_irqrestore (& ldata -> read_lock , flags );
1828
1837
1829
1838
if (n > size ) {
1830
- ret = copy_to_user (* b , & ldata -> read_buf [ tail ] , size );
1839
+ ret = copy_to_user (* b , read_buf_addr ( ldata , tail ) , size );
1831
1840
if (ret )
1832
1841
return - EFAULT ;
1833
1842
ret = copy_to_user (* b + size , ldata -> read_buf , n - size );
1834
1843
} else
1835
- ret = copy_to_user (* b , & ldata -> read_buf [ tail ] , n );
1844
+ ret = copy_to_user (* b , read_buf_addr ( ldata , tail ) , n );
1836
1845
1837
1846
if (ret )
1838
1847
return - EFAULT ;
1839
1848
* b += n ;
1840
1849
* nr -= n ;
1841
1850
1842
1851
raw_spin_lock_irqsave (& ldata -> read_lock , flags );
1843
- ldata -> read_tail = ( ldata -> read_tail + c ) & ( N_TTY_BUF_SIZE - 1 ) ;
1852
+ ldata -> read_tail += c ;
1844
1853
ldata -> read_cnt -= c ;
1845
1854
if (found ) {
1846
1855
__clear_bit (eol , ldata -> read_flags );
@@ -2230,19 +2239,19 @@ static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file,
2230
2239
2231
2240
static unsigned long inq_canon (struct n_tty_data * ldata )
2232
2241
{
2233
- int nr , head , tail ;
2242
+ size_t nr , head , tail ;
2234
2243
2235
2244
if (!ldata -> canon_data )
2236
2245
return 0 ;
2237
2246
head = ldata -> canon_head ;
2238
2247
tail = ldata -> read_tail ;
2239
- nr = ( head - tail ) & ( N_TTY_BUF_SIZE - 1 ) ;
2248
+ nr = head - tail ;
2240
2249
/* Skip EOF-chars.. */
2241
2250
while (head != tail ) {
2242
- if (test_bit (tail , ldata -> read_flags ) &&
2243
- ldata -> read_buf [ tail ] == __DISABLED_CHAR )
2251
+ if (test_bit (tail & ( N_TTY_BUF_SIZE - 1 ) , ldata -> read_flags ) &&
2252
+ read_buf ( ldata , tail ) == __DISABLED_CHAR )
2244
2253
nr -- ;
2245
- tail = ( tail + 1 ) & ( N_TTY_BUF_SIZE - 1 ) ;
2254
+ tail ++ ;
2246
2255
}
2247
2256
return nr ;
2248
2257
}
0 commit comments