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 }