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);