]> git.kaiwu.me - nginx.git/commitdiff
Cache: prefix-based temporary files.
authorMaxim Dounin <mdounin@mdounin.ru>
Thu, 3 Nov 2016 14:10:29 +0000 (17:10 +0300)
committerMaxim Dounin <mdounin@mdounin.ru>
Thu, 3 Nov 2016 14:10:29 +0000 (17:10 +0300)
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).

src/core/ngx_file.c
src/http/ngx_http_cache.h
src/http/ngx_http_file_cache.c
src/http/ngx_http_upstream.c

index 8359c0feee4a232974ebb789675d204ad17629cf..b7dd4bca30c0717e8b9bb5991ae16474ef7050d5 100644 (file)
@@ -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, ngx_path_t *path, ngx_pool_t *pool,
     }
 #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, ngx_path_t *path, ngx_pool_t *pool,
     }
 
     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);
index 70342d0ed376ec69f7528ca335c5b53787e89337..4075f3dec0ec5b9fb1182a395590ab62c4ce4e00 100644 (file)
@@ -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 */
 };
 
 
index ac5c103745edfa482e633b2f9e92d0af4a005450..3c8ad7dab086fab4ff05d6cb8da1bf522b28012f 100644 (file)
@@ -2112,6 +2112,17 @@ ngx_http_file_cache_add_file(ngx_tree_ctx_t *ctx, ngx_str_t *name)
         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 *cf, ngx_command_t *cmd, void *conf)
     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 *cf, ngx_command_t *cmd, void *conf)
         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 *cf, ngx_command_t *cmd, void *conf)
     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;
 
index fbd94d1395ee07b03849bfe0340d23d17d0b15ec..a6dd55e662e0158c2f7f518d134211426bbc13fe 100644 (file)
@@ -2997,8 +2997,9 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
         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