mirror of
https://github.com/nginx/nginx.git
synced 2025-01-24 15:16:39 -06:00
directio
This commit is contained in:
parent
7494490978
commit
385af28642
@ -170,3 +170,23 @@ if [ $ngx_found = no ]; then
|
||||
CRYPT_LIB="-lcrypt"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
ngx_feature="O_DIRECT"
|
||||
ngx_feature_name="NGX_HAVE_O_DIRECT"
|
||||
ngx_feature_run=no
|
||||
ngx_feature_incs="#include <fcntl.h>"
|
||||
ngx_feature_path=
|
||||
ngx_feature_libs=
|
||||
ngx_feature_test="fcntl(0, F_SETFL, O_DIRECT);"
|
||||
. auto/feature
|
||||
|
||||
|
||||
ngx_feature="F_NOCACHE"
|
||||
ngx_feature_name="NGX_HAVE_F_NOCACHE"
|
||||
ngx_feature_run=no
|
||||
ngx_feature_incs="#include <fcntl.h>"
|
||||
ngx_feature_path=
|
||||
ngx_feature_libs=
|
||||
ngx_feature_test="fcntl(0, F_NOCACHE, 1);"
|
||||
. auto/feature
|
||||
|
@ -497,6 +497,13 @@ ngx_open_and_stat_file(u_char *name, ngx_open_file_info_t *of, ngx_log_t *log)
|
||||
|
||||
} else {
|
||||
of->fd = fd;
|
||||
|
||||
if (of->directio <= ngx_file_size(&fi)) {
|
||||
if (ngx_directio(fd) == -1) {
|
||||
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
|
||||
ngx_directio_n " \"%s\" failed", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
@ -17,6 +17,7 @@ typedef struct {
|
||||
ngx_file_uniq_t uniq;
|
||||
time_t mtime;
|
||||
off_t size;
|
||||
off_t directio;
|
||||
ngx_err_t err;
|
||||
|
||||
time_t valid;
|
||||
|
@ -32,6 +32,7 @@ ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in)
|
||||
size_t size;
|
||||
ngx_int_t rc, last;
|
||||
ngx_uint_t recycled;
|
||||
ngx_buf_t *b;
|
||||
ngx_chain_t *cl, *out, **last_out;
|
||||
|
||||
if (ctx->in == NULL && ctx->busy == NULL) {
|
||||
@ -161,13 +162,29 @@ ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in)
|
||||
}
|
||||
}
|
||||
|
||||
ctx->buf = ngx_create_temp_buf(ctx->pool, size);
|
||||
if (ctx->buf == NULL) {
|
||||
b = ngx_calloc_buf(ctx->pool);
|
||||
if (b == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ctx->buf->tag = ctx->tag;
|
||||
ctx->buf->recycled = recycled;
|
||||
/*
|
||||
* allocate block aligned to a disk sector size
|
||||
* to enable O_DIRECT
|
||||
*/
|
||||
|
||||
b->start = ngx_pmemalign(ctx->pool, size, 512);
|
||||
if (b->start == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
b->pos = b->start;
|
||||
b->last = b->start;
|
||||
b->end = b->last + size;
|
||||
b->temporary = 1;
|
||||
b->tag = ctx->tag;
|
||||
b->recycled = recycled;
|
||||
|
||||
ctx->buf = b;
|
||||
ctx->allocated++;
|
||||
}
|
||||
}
|
||||
|
@ -195,17 +195,35 @@ ngx_palloc_large(ngx_pool_t *pool, size_t size)
|
||||
void *p;
|
||||
ngx_pool_large_t *large;
|
||||
|
||||
#if 0
|
||||
p = ngx_memalign(ngx_pagesize, size, pool->log);
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
p = ngx_alloc(size, pool->log);
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
|
||||
if (large == NULL) {
|
||||
ngx_free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
large->alloc = p;
|
||||
large->next = pool->large;
|
||||
pool->large = large;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment)
|
||||
{
|
||||
void *p;
|
||||
ngx_pool_large_t *large;
|
||||
|
||||
p = ngx_memalign(alignment, size, pool->log);
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
|
||||
if (large == NULL) {
|
||||
|
@ -77,6 +77,7 @@ void ngx_destroy_pool(ngx_pool_t *pool);
|
||||
void *ngx_palloc(ngx_pool_t *pool, size_t size);
|
||||
void *ngx_pnalloc(ngx_pool_t *pool, size_t size);
|
||||
void *ngx_pcalloc(ngx_pool_t *pool, size_t size);
|
||||
void *ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment);
|
||||
ngx_int_t ngx_pfree(ngx_pool_t *pool, void *p);
|
||||
|
||||
|
||||
|
@ -107,6 +107,7 @@ ngx_http_flv_handler(ngx_http_request_t *r)
|
||||
|
||||
ngx_memzero(&of, sizeof(ngx_open_file_info_t));
|
||||
|
||||
of.directio = clcf->directio;
|
||||
of.valid = clcf->open_file_cache_valid;
|
||||
of.min_uses = clcf->open_file_cache_min_uses;
|
||||
of.errors = clcf->open_file_cache_errors;
|
||||
|
@ -121,6 +121,7 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
|
||||
|
||||
ngx_memzero(&of, sizeof(ngx_open_file_info_t));
|
||||
|
||||
of.directio = clcf->directio;
|
||||
of.valid = clcf->open_file_cache_valid;
|
||||
of.min_uses = clcf->open_file_cache_min_uses;
|
||||
of.errors = clcf->open_file_cache_errors;
|
||||
|
@ -210,6 +210,7 @@ ngx_http_index_handler(ngx_http_request_t *r)
|
||||
|
||||
ngx_memzero(&of, sizeof(ngx_open_file_info_t));
|
||||
|
||||
of.directio = clcf->directio;
|
||||
of.valid = clcf->open_file_cache_valid;
|
||||
of.min_uses = clcf->open_file_cache_min_uses;
|
||||
of.errors = clcf->open_file_cache_errors;
|
||||
|
@ -98,6 +98,7 @@ ngx_http_static_handler(ngx_http_request_t *r)
|
||||
|
||||
ngx_memzero(&of, sizeof(ngx_open_file_info_t));
|
||||
|
||||
of.directio = clcf->directio;
|
||||
of.valid = clcf->open_file_cache_valid;
|
||||
of.min_uses = clcf->open_file_cache_min_uses;
|
||||
of.errors = clcf->open_file_cache_errors;
|
||||
|
@ -652,6 +652,7 @@ sendfile(r, filename, offset = -1, bytes = 0)
|
||||
|
||||
ngx_memzero(&of, sizeof(ngx_open_file_info_t));
|
||||
|
||||
of.directio = clcf->directio;
|
||||
of.valid = clcf->open_file_cache_valid;
|
||||
of.min_uses = clcf->open_file_cache_min_uses;
|
||||
of.errors = clcf->open_file_cache_errors;
|
||||
|
@ -54,6 +54,8 @@ static char *ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
static char *ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
static char *ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static char *ngx_http_core_directio(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static char *ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
@ -353,6 +355,13 @@ static ngx_command_t ngx_http_core_commands[] = {
|
||||
offsetof(ngx_http_core_loc_conf_t, sendfile_max_chunk),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("directio"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
ngx_http_core_directio,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("tcp_nopush"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_flag_slot,
|
||||
@ -2586,6 +2595,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
|
||||
lcf->client_body_in_file_only = NGX_CONF_UNSET;
|
||||
lcf->sendfile = NGX_CONF_UNSET;
|
||||
lcf->sendfile_max_chunk = NGX_CONF_UNSET_SIZE;
|
||||
lcf->directio = NGX_CONF_UNSET;
|
||||
lcf->tcp_nopush = NGX_CONF_UNSET;
|
||||
lcf->tcp_nodelay = NGX_CONF_UNSET;
|
||||
lcf->send_timeout = NGX_CONF_UNSET_MSEC;
|
||||
@ -2774,6 +2784,8 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0);
|
||||
ngx_conf_merge_size_value(conf->sendfile_max_chunk,
|
||||
prev->sendfile_max_chunk, 0);
|
||||
ngx_conf_merge_off_value(conf->directio, prev->directio,
|
||||
NGX_MAX_OFF_T_VALUE);
|
||||
ngx_conf_merge_value(conf->tcp_nopush, prev->tcp_nopush, 0);
|
||||
ngx_conf_merge_value(conf->tcp_nodelay, prev->tcp_nodelay, 1);
|
||||
|
||||
@ -3339,6 +3351,33 @@ ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_core_directio(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_core_loc_conf_t *clcf = conf;
|
||||
|
||||
ngx_str_t *value;
|
||||
|
||||
if (clcf->directio != NGX_CONF_UNSET) {
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
if (ngx_strcmp(value[1].data, "off") == 0) {
|
||||
clcf->directio = NGX_MAX_OFF_T_VALUE;
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
clcf->directio = ngx_parse_offset(&value[1]);
|
||||
if (clcf->directio == (off_t) NGX_ERROR) {
|
||||
return "invalid value";
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
|
@ -265,6 +265,7 @@ struct ngx_http_core_loc_conf_s {
|
||||
ngx_str_t default_type;
|
||||
|
||||
off_t client_max_body_size; /* client_max_body_size */
|
||||
off_t directio; /* directio */
|
||||
|
||||
size_t client_body_buffer_size; /* client_body_buffer_size */
|
||||
size_t send_lowat; /* send_lowat */
|
||||
|
@ -996,6 +996,7 @@ ngx_http_script_file_code(ngx_http_script_engine_t *e)
|
||||
|
||||
ngx_memzero(&of, sizeof(ngx_open_file_info_t));
|
||||
|
||||
of.directio = clcf->directio;
|
||||
of.valid = clcf->open_file_cache_valid;
|
||||
of.min_uses = clcf->open_file_cache_min_uses;
|
||||
of.errors = clcf->open_file_cache_errors;
|
||||
|
@ -21,8 +21,8 @@ void *ngx_calloc(size_t size, ngx_log_t *log);
|
||||
/*
|
||||
* Linux has memalign() or posix_memalign()
|
||||
* Solaris has memalign()
|
||||
* FreeBSD has not memalign() or posix_memalign() but its malloc() alignes
|
||||
* allocations bigger than page size at the page boundary.
|
||||
* FreeBSD 7.0 has posix_memalign(), besides, early version's malloc()
|
||||
* aligns allocations bigger than page size at the page boundary
|
||||
*/
|
||||
|
||||
#if (NGX_HAVE_POSIX_MEMALIGN || NGX_HAVE_MEMALIGN)
|
||||
|
@ -351,3 +351,22 @@ ngx_unlock_fd(ngx_fd_t fd)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if (NGX_HAVE_O_DIRECT)
|
||||
|
||||
ngx_int_t
|
||||
ngx_directio(ngx_fd_t fd)
|
||||
{
|
||||
int flags;
|
||||
|
||||
flags = fcntl(fd, F_GETFL);
|
||||
|
||||
if (flags == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fcntl(fd, F_SETFL, flags | O_DIRECT);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -189,4 +189,22 @@ ngx_err_t ngx_unlock_fd(ngx_fd_t fd);
|
||||
#define ngx_unlock_fd_n "fcntl(F_SETLK, F_UNLCK)"
|
||||
|
||||
|
||||
#if (NGX_HAVE_O_DIRECT)
|
||||
|
||||
ngx_int_t ngx_directio(ngx_fd_t fd);
|
||||
#define ngx_directio_n "fcntl(O_DIRECT)"
|
||||
|
||||
#elif (NGX_HAVE_F_NOCACHE)
|
||||
|
||||
#define ngx_directio(fd) fcntl(fd, F_NOCACHE, 1)
|
||||
#define ngx_directio_n "fcntl(F_NOCACHE)"
|
||||
|
||||
#else
|
||||
|
||||
#define ngx_directio(fd) 0
|
||||
#define ngx_directio_n "ngx_directio_n"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _NGX_FILES_H_INCLUDED_ */
|
||||
|
@ -200,7 +200,7 @@ typedef struct {
|
||||
|
||||
|
||||
ngx_int_t ngx_open_glob(ngx_glob_t *gl);
|
||||
#define ngx_open_glob_n "FindFirstFile()"
|
||||
#define ngx_open_glob_n "FindFirstFile()"
|
||||
|
||||
ngx_int_t ngx_read_glob(ngx_glob_t *gl, ngx_str_t *name);
|
||||
void ngx_close_glob(ngx_glob_t *gl);
|
||||
@ -216,4 +216,8 @@ ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *ce,
|
||||
off_t offset, ngx_pool_t *pool);
|
||||
|
||||
|
||||
#define ngx_directio(fd) 0
|
||||
#define ngx_directio_n "ngx_directio_n"
|
||||
|
||||
|
||||
#endif /* _NGX_FILES_H_INCLUDED_ */
|
||||
|
Loading…
Reference in New Issue
Block a user