Mercurial > hg > nginx
comparison src/core/ngx_file.c @ 6795:1a917932db96
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).
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 03 Nov 2016 17:10:29 +0300 |
parents | 1606a817c1d4 |
children | d48c8cdac201 |
comparison
equal
deleted
inserted
replaced
6794:93b294c5d581 | 6795:1a917932db96 |
---|---|
139 | 139 |
140 ngx_int_t | 140 ngx_int_t |
141 ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, ngx_pool_t *pool, | 141 ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, ngx_pool_t *pool, |
142 ngx_uint_t persistent, ngx_uint_t clean, ngx_uint_t access) | 142 ngx_uint_t persistent, ngx_uint_t clean, ngx_uint_t access) |
143 { | 143 { |
144 size_t levels; | |
145 u_char *p; | |
144 uint32_t n; | 146 uint32_t n; |
145 ngx_err_t err; | 147 ngx_err_t err; |
148 ngx_str_t name; | |
149 ngx_uint_t prefix; | |
146 ngx_pool_cleanup_t *cln; | 150 ngx_pool_cleanup_t *cln; |
147 ngx_pool_cleanup_file_t *clnf; | 151 ngx_pool_cleanup_file_t *clnf; |
148 | 152 |
149 file->name.len = path->name.len + 1 + path->len + 10; | 153 if (file->name.len) { |
154 name = file->name; | |
155 levels = 0; | |
156 prefix = 1; | |
157 | |
158 } else { | |
159 name = path->name; | |
160 levels = path->len; | |
161 prefix = 0; | |
162 } | |
163 | |
164 file->name.len = name.len + 1 + levels + 10; | |
150 | 165 |
151 file->name.data = ngx_pnalloc(pool, file->name.len + 1); | 166 file->name.data = ngx_pnalloc(pool, file->name.len + 1); |
152 if (file->name.data == NULL) { | 167 if (file->name.data == NULL) { |
153 return NGX_ERROR; | 168 return NGX_ERROR; |
154 } | 169 } |
157 for (i = 0; i < file->name.len; i++) { | 172 for (i = 0; i < file->name.len; i++) { |
158 file->name.data[i] = 'X'; | 173 file->name.data[i] = 'X'; |
159 } | 174 } |
160 #endif | 175 #endif |
161 | 176 |
162 ngx_memcpy(file->name.data, path->name.data, path->name.len); | 177 p = ngx_cpymem(file->name.data, name.data, name.len); |
178 | |
179 if (prefix) { | |
180 *p = '.'; | |
181 } | |
182 | |
183 p += 1 + levels; | |
163 | 184 |
164 n = (uint32_t) ngx_next_temp_number(0); | 185 n = (uint32_t) ngx_next_temp_number(0); |
165 | 186 |
166 cln = ngx_pool_cleanup_add(pool, sizeof(ngx_pool_cleanup_file_t)); | 187 cln = ngx_pool_cleanup_add(pool, sizeof(ngx_pool_cleanup_file_t)); |
167 if (cln == NULL) { | 188 if (cln == NULL) { |
168 return NGX_ERROR; | 189 return NGX_ERROR; |
169 } | 190 } |
170 | 191 |
171 for ( ;; ) { | 192 for ( ;; ) { |
172 (void) ngx_sprintf(file->name.data + path->name.len + 1 + path->len, | 193 (void) ngx_sprintf(p, "%010uD%Z", n); |
173 "%010uD%Z", n); | 194 |
174 | 195 if (!prefix) { |
175 ngx_create_hashed_filename(path, file->name.data, file->name.len); | 196 ngx_create_hashed_filename(path, file->name.data, file->name.len); |
197 } | |
176 | 198 |
177 ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0, | 199 ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0, |
178 "hashed path: %s", file->name.data); | 200 "hashed path: %s", file->name.data); |
179 | 201 |
180 file->fd = ngx_open_tempfile(file->name.data, persistent, access); | 202 file->fd = ngx_open_tempfile(file->name.data, persistent, access); |