comparison src/os/unix/ngx_linux_sendfile_chain.c @ 6437:4df3d9fcdee8

Truncation detection in sendfile() on Linux. This addresses connection hangs as observed in ticket #504, and CPU hogs with "aio threads; sendfile on" as reported in the mailing list, see http://mailman.nginx.org/pipermail/nginx-ru/2016-March/057638.html. The alert is identical to one used on FreeBSD.
author Maxim Dounin <mdounin@mdounin.ru>
date Tue, 15 Mar 2016 18:26:17 +0300
parents 3b9c6b91d988
children 248aa2757332
comparison
equal deleted inserted replaced
6436:8f038068f4bc 6437:4df3d9fcdee8
290 ngx_connection_error(c, err, "sendfile() failed"); 290 ngx_connection_error(c, err, "sendfile() failed");
291 return NGX_ERROR; 291 return NGX_ERROR;
292 } 292 }
293 } 293 }
294 294
295 if (n == 0) {
296 /*
297 * if sendfile returns zero, then someone has truncated the file,
298 * so the offset became beyond the end of the file
299 */
300
301 ngx_log_error(NGX_LOG_ALERT, c->log, 0,
302 "sendfile() reported that \"%s\" was truncated at %O",
303 file->file->name.data, file->file_pos);
304
305 return NGX_ERROR;
306 }
307
295 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, "sendfile: %z of %uz @%O", 308 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, "sendfile: %z of %uz @%O",
296 n, size, file->file_pos); 309 n, size, file->file_pos);
297 310
298 return n; 311 return n;
299 } 312 }
352 wev->error = 1; 365 wev->error = 1;
353 ngx_connection_error(c, ctx->err, "sendfile() failed"); 366 ngx_connection_error(c, ctx->err, "sendfile() failed");
354 return NGX_ERROR; 367 return NGX_ERROR;
355 } 368 }
356 369
370 if (ctx->sent == 0) {
371 /*
372 * if sendfile returns zero, then someone has truncated the file,
373 * so the offset became beyond the end of the file
374 */
375
376 ngx_log_error(NGX_LOG_ALERT, c->log, 0,
377 "sendfile() reported that \"%s\" was truncated at %O",
378 file->file->name.data, file->file_pos);
379
380 return NGX_ERROR;
381 }
382
357 *sent = ctx->sent; 383 *sent = ctx->sent;
358 384
359 return (ctx->sent == ctx->size) ? NGX_DONE : NGX_AGAIN; 385 return (ctx->sent == ctx->size) ? NGX_DONE : NGX_AGAIN;
360 } 386 }
361 387