Welcome! Log In Create A New Profile

Advanced

[nginx] Cache: prefix-based temporary files.

Maxim Dounin
November 03, 2016 10:16AM
details: http://hg.nginx.org/nginx/rev/1a917932db96
branches:
changeset: 6795:1a917932db96
user: Maxim Dounin <mdounin@mdounin.ru>
date: Thu Nov 03 17:10:29 2016 +0300
description:
Cache: prefix-based temporary files.

On Linux, the rename syscall can be slow due to a global file system lock,
acquired for the entire rename operation, unless both old and new files are
in the same directory. To address this temporary files are now created
in the same directory as the expected resulting cache file when using the
"use_temp_path=off" parameter.

This change mostly reverts 99639bfdfa2a and 3281de8142f5, restoring the
behaviour as of a9138c35120d (with minor changes).

diffstat:

src/core/ngx_file.c | 32 +++++++++++++++++++++++++----
src/http/ngx_http_cache.h | 4 ++-
src/http/ngx_http_file_cache.c | 45 ++++++++++++-----------------------------
src/http/ngx_http_upstream.c | 5 ++-
4 files changed, 46 insertions(+), 40 deletions(-)

diffs (174 lines):

diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c
--- a/src/core/ngx_file.c
+++ b/src/core/ngx_file.c
@@ -141,12 +141,27 @@ ngx_int_t
ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, ngx_pool_t *pool,
ngx_uint_t persistent, ngx_uint_t clean, ngx_uint_t access)
{
+ size_t levels;
+ u_char *p;
uint32_t n;
ngx_err_t err;
+ ngx_str_t name;
+ ngx_uint_t prefix;
ngx_pool_cleanup_t *cln;
ngx_pool_cleanup_file_t *clnf;

- file->name.len = path->name.len + 1 + path->len + 10;
+ if (file->name.len) {
+ name = file->name;
+ levels = 0;
+ prefix = 1;
+
+ } else {
+ name = path->name;
+ levels = path->len;
+ prefix = 0;
+ }
+
+ file->name.len = name.len + 1 + levels + 10;

file->name.data = ngx_pnalloc(pool, file->name.len + 1);
if (file->name.data == NULL) {
@@ -159,7 +174,13 @@ ngx_create_temp_file(ngx_file_t *file, n
}
#endif

- ngx_memcpy(file->name.data, path->name.data, path->name.len);
+ p = ngx_cpymem(file->name.data, name.data, name.len);
+
+ if (prefix) {
+ *p = '.';
+ }
+
+ p += 1 + levels;

n = (uint32_t) ngx_next_temp_number(0);

@@ -169,10 +190,11 @@ ngx_create_temp_file(ngx_file_t *file, n
}

for ( ;; ) {
- (void) ngx_sprintf(file->name.data + path->name.len + 1 + path->len,
- "%010uD%Z", n);
+ (void) ngx_sprintf(p, "%010uD%Z", n);

- ngx_create_hashed_filename(path, file->name.data, file->name.len);
+ if (!prefix) {
+ ngx_create_hashed_filename(path, file->name.data, file->name.len);
+ }

ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0,
"hashed path: %s", file->name.data);
diff --git a/src/http/ngx_http_cache.h b/src/http/ngx_http_cache.h
--- a/src/http/ngx_http_cache.h
+++ b/src/http/ngx_http_cache.h
@@ -151,7 +151,6 @@ struct ngx_http_file_cache_s {
ngx_slab_pool_t *shpool;

ngx_path_t *path;
- ngx_path_t *temp_path;

off_t max_size;
size_t bsize;
@@ -171,6 +170,9 @@ struct ngx_http_file_cache_s {
ngx_msec_t manager_threshold;

ngx_shm_zone_t *shm_zone;
+
+ ngx_uint_t use_temp_path;
+ /* unsigned use_temp_path:1 */
};


diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -2112,6 +2112,17 @@ ngx_http_file_cache_add_file(ngx_tree_ct
return NGX_ERROR;
}

+ /*
+ * Temporary files in cache have a suffix consisting of a dot
+ * followed by 10 digits.
+ */
+
+ if (name->len >= 2 * NGX_HTTP_CACHE_KEY_LEN + 1 + 10
+ && name->data[name->len - 10 - 1] == '.')
+ {
+ return NGX_OK;
+ }
+
if (ctx->size < (off_t) sizeof(ngx_http_file_cache_header_t)) {
ngx_log_error(NGX_LOG_CRIT, ctx->log, 0,
"cache file \"%s\" is too small", name->data);
@@ -2256,7 +2267,6 @@ ngx_http_file_cache_set_slot(ngx_conf_t
off_t max_size;
u_char *last, *p;
time_t inactive;
- size_t len;
ssize_t size;
ngx_str_t s, name, *value;
ngx_int_t loader_files, manager_files;
@@ -2529,37 +2539,6 @@ ngx_http_file_cache_set_slot(ngx_conf_t
return NGX_CONF_ERROR;
}

- if (!use_temp_path) {
- cache->temp_path = ngx_pcalloc(cf->pool, sizeof(ngx_path_t));
- if (cache->temp_path == NULL) {
- return NGX_CONF_ERROR;
- }
-
- len = cache->path->name.len + sizeof("/temp") - 1;
-
- p = ngx_pnalloc(cf->pool, len + 1);
- if (p == NULL) {
- return NGX_CONF_ERROR;
- }
-
- cache->temp_path->name.len = len;
- cache->temp_path->name.data = p;
-
- p = ngx_cpymem(p, cache->path->name.data, cache->path->name.len);
- ngx_memcpy(p, "/temp", sizeof("/temp"));
-
- ngx_memcpy(&cache->temp_path->level, &cache->path->level,
- NGX_MAX_PATH_LEVEL * sizeof(size_t));
-
- cache->temp_path->len = cache->path->len;
- cache->temp_path->conf_file = cf->conf_file->file.name.data;
- cache->temp_path->line = cf->conf_file->line;
-
- if (ngx_add_path(cf, &cache->temp_path) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- }
-
cache->shm_zone = ngx_shared_memory_add(cf, &name, size, cmd->post);
if (cache->shm_zone == NULL) {
return NGX_CONF_ERROR;
@@ -2575,6 +2554,8 @@ ngx_http_file_cache_set_slot(ngx_conf_t
cache->shm_zone->init = ngx_http_file_cache_init;
cache->shm_zone->data = cache;

+ cache->use_temp_path = use_temp_path;
+
cache->inactive = inactive;
cache->max_size = max_size;

diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -2997,8 +2997,9 @@ ngx_http_upstream_send_response(ngx_http
p->temp_file->persistent = 1;

#if (NGX_HTTP_CACHE)
- if (r->cache && r->cache->file_cache->temp_path) {
- p->temp_file->path = r->cache->file_cache->temp_path;
+ if (r->cache && !r->cache->file_cache->use_temp_path) {
+ p->temp_file->path = r->cache->file_cache->path;
+ p->temp_file->file.name = r->cache->file.name;
}
#endif


_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[nginx] Cache: prefix-based temporary files.

Maxim Dounin 438 November 03, 2016 10:16AM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 255
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready