Mercurial > hg > nginx
comparison src/os/unix/ngx_linux_sendfile_chain.c @ 7948:a2613fc1bce5
Fixed sendfile() limit handling on Linux.
On Linux starting with 2.6.16, sendfile() silently limits all operations
to MAX_RW_COUNT, defined as (INT_MAX & PAGE_MASK). This incorrectly
triggered the interrupt check, and resulted in 0-sized writev() on the
next loop iteration.
Fix is to make sure the limit is always checked, so we will return from
the loop if the limit is already reached even if number of bytes sent is
not exactly equal to the number of bytes we've tried to send.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Fri, 29 Oct 2021 20:21:51 +0300 |
parents | 400a3412b1e3 |
children | 555533169506 |
comparison
equal
deleted
inserted
replaced
7947:51a260276425 | 7948:a2613fc1bce5 |
---|---|
36 * Linux 2.4.21 has the new sendfile64() syscall #239. | 36 * Linux 2.4.21 has the new sendfile64() syscall #239. |
37 * | 37 * |
38 * On Linux up to 2.6.16 sendfile() does not allow to pass the count parameter | 38 * On Linux up to 2.6.16 sendfile() does not allow to pass the count parameter |
39 * more than 2G-1 bytes even on 64-bit platforms: it returns EINVAL, | 39 * more than 2G-1 bytes even on 64-bit platforms: it returns EINVAL, |
40 * so we limit it to 2G-1 bytes. | 40 * so we limit it to 2G-1 bytes. |
41 * | |
42 * On Linux 2.6.16 and later, sendfile() silently limits the count parameter | |
43 * to 2G minus the page size, even on 64-bit platforms. | |
41 */ | 44 */ |
42 | 45 |
43 #define NGX_SENDFILE_MAXSIZE 2147483647L | 46 #define NGX_SENDFILE_MAXSIZE 2147483647L |
44 | 47 |
45 | 48 |
214 * than we are prepared to send now, since it was started in | 217 * than we are prepared to send now, since it was started in |
215 * some point in the past, so we again have to retry | 218 * some point in the past, so we again have to retry |
216 */ | 219 */ |
217 | 220 |
218 send = prev_send + sent; | 221 send = prev_send + sent; |
219 continue; | |
220 } | 222 } |
221 | 223 |
222 if (send >= limit || in == NULL) { | 224 if (send >= limit || in == NULL) { |
223 return in; | 225 return in; |
224 } | 226 } |