Use more precise stat.st_blocks to account cache size on Unix
instead of file length rounded to a file system block size.
There is no similar way on Windows, so rounding to a cache->bsize is kept.
diff --git a/src/core/ngx_open_file_cache.c b/src/core/ngx_open_file_cache.c
index a9c4532..a70385c 100644
--- a/src/core/ngx_open_file_cache.c
+++ b/src/core/ngx_open_file_cache.c
@@ -155,6 +155,7 @@
of->uniq = ngx_file_uniq(&fi);
of->mtime = ngx_file_mtime(&fi);
of->size = ngx_file_size(&fi);
+ of->fs_size = ngx_file_fs_size(&fi);
of->is_dir = ngx_is_dir(&fi);
of->is_file = ngx_is_file(&fi);
of->is_link = ngx_is_link(&fi);
@@ -557,6 +558,7 @@
of->uniq = ngx_file_uniq(&fi);
of->mtime = ngx_file_mtime(&fi);
of->size = ngx_file_size(&fi);
+ of->fs_size = ngx_file_fs_size(&fi);
of->is_dir = ngx_is_dir(&fi);
of->is_file = ngx_is_file(&fi);
of->is_link = ngx_is_link(&fi);
diff --git a/src/core/ngx_open_file_cache.h b/src/core/ngx_open_file_cache.h
index f56dfcc..638bc5d 100644
--- a/src/core/ngx_open_file_cache.h
+++ b/src/core/ngx_open_file_cache.h
@@ -20,6 +20,7 @@
ngx_file_uniq_t uniq;
time_t mtime;
off_t size;
+ off_t fs_size;
off_t directio;
size_t read_ahead;
diff --git a/src/http/ngx_http_cache.h b/src/http/ngx_http_cache.h
index b511a0b..3cf113f 100644
--- a/src/http/ngx_http_cache.h
+++ b/src/http/ngx_http_cache.h
@@ -50,7 +50,7 @@
time_t expire;
time_t valid_sec;
size_t body_start;
- off_t length;
+ off_t fs_size;
} ngx_http_file_cache_node_t;
@@ -68,6 +68,7 @@
size_t header_start;
size_t body_start;
off_t length;
+ off_t fs_size;
ngx_uint_t min_uses;
ngx_uint_t error;
diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c
index f26fcbc..fb1ab98 100644
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -349,6 +349,7 @@
c->file.log = r->connection->log;
c->uniq = of.uniq;
c->length = of.size;
+ c->fs_size = (of.fs_size + cache->bsize - 1) / cache->bsize;
c->buf = ngx_create_temp_buf(r->pool, c->body_start);
if (c->buf == NULL) {
@@ -411,7 +412,7 @@
c->node->exists = 1;
c->node->uniq = c->uniq;
- cache->sh->size += (c->length + cache->bsize - 1) / cache->bsize;
+ cache->sh->size += c->fs_size;
}
ngx_shmtx_unlock(&cache->shpool->mutex);
@@ -594,7 +595,7 @@
fcn->valid_sec = 0;
fcn->uniq = 0;
fcn->body_start = 0;
- fcn->length = 0;
+ fcn->fs_size = 0;
done:
@@ -777,7 +778,7 @@
void
ngx_http_file_cache_update(ngx_http_request_t *r, ngx_temp_file_t *tf)
{
- off_t size, length;
+ off_t fs_size;
ngx_int_t rc;
ngx_file_uniq_t uniq;
ngx_file_info_t fi;
@@ -800,7 +801,7 @@
cache = c->file_cache;
uniq = 0;
- length = 0;
+ fs_size = 0;
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http file cache rename: \"%s\" to \"%s\"",
@@ -825,23 +826,18 @@
} else {
uniq = ngx_file_uniq(&fi);
- length = ngx_file_size(&fi);
+ fs_size = (ngx_file_fs_size(&fi) + cache->bsize - 1) / cache->bsize;
}
}
- size = (length + cache->bsize - 1) / cache->bsize;
-
ngx_shmtx_lock(&cache->shpool->mutex);
c->node->count--;
c->node->uniq = uniq;
c->node->body_start = c->body_start;
- size = size - (c->node->length + cache->bsize - 1) / cache->bsize;
-
- c->node->length = length;
-
- cache->sh->size += size;
+ cache->sh->size += fs_size - c->node->fs_size;
+ c->node->fs_size = fs_size;
if (rc == NGX_OK) {
c->node->exists = 1;
@@ -1148,7 +1144,7 @@
fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue);
if (fcn->exists) {
- cache->sh->size -= (fcn->length + cache->bsize - 1) / cache->bsize;
+ cache->sh->size -= fcn->fs_size;
path = cache->path;
p = name + path->name.len + 1 + path->len;
@@ -1371,6 +1367,8 @@
return NGX_ERROR;
}
+ cache = ctx->data;
+
if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
ngx_fd_info_n " \"%s\" failed", name->data);
@@ -1381,6 +1379,7 @@
c.valid_msec = h.valid_msec;
c.body_start = h.body_start;
c.length = ngx_file_size(&fi);
+ c.fs_size = (ngx_file_fs_size(&fi) + cache->bsize - 1) / cache->bsize;
}
if (ngx_close_file(fd) == NGX_FILE_ERROR) {
@@ -1406,8 +1405,6 @@
c.key[i] = (u_char) n;
}
- cache = ctx->data;
-
return ngx_http_file_cache_add(cache, &c);
}
@@ -1447,9 +1444,9 @@
fcn->uniq = c->uniq;
fcn->valid_sec = c->valid_sec;
fcn->body_start = c->body_start;
- fcn->length = c->length;
+ fcn->fs_size = c->fs_size;
- cache->sh->size += (c->length + cache->bsize - 1) / cache->bsize;
+ cache->sh->size += c->fs_size;
} else {
ngx_queue_remove(&fcn->queue);
diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h
index b7bfff1..037c9a1 100644
--- a/src/os/unix/ngx_files.h
+++ b/src/os/unix/ngx_files.h
@@ -157,6 +157,7 @@
#define ngx_is_exec(sb) (((sb)->st_mode & S_IXUSR) == S_IXUSR)
#define ngx_file_access(sb) ((sb)->st_mode & 0777)
#define ngx_file_size(sb) (sb)->st_size
+#define ngx_file_fs_size(sb) ((sb)->st_blocks * 512)
#define ngx_file_mtime(sb) (sb)->st_mtime
#define ngx_file_uniq(sb) (sb)->st_ino
diff --git a/src/os/win32/ngx_files.h b/src/os/win32/ngx_files.h
index fe77605..06f399d 100644
--- a/src/os/win32/ngx_files.h
+++ b/src/os/win32/ngx_files.h
@@ -154,6 +154,7 @@
#define ngx_file_size(fi) \
(((off_t) (fi)->nFileSizeHigh << 32) | (fi)->nFileSizeLow)
+#define ngx_file_fs_size(fi) ngx_file_size(fi)
#define ngx_file_uniq(fi) (*(ngx_file_uniq_t *) &(fi)->nFileIndexHigh)