summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2012-08-18 01:46:20 +0200
committerLennart Poettering <lennart@poettering.net>2012-08-18 01:46:20 +0200
commit84168d8068bb67dcd5468ab3b376535d81643aef (patch)
tree134286a4aedea80c2775faf54ea708dff29db330
parentfb9a24b6b1ed5b1f42e6e350ccdb7e11800a83bd (diff)
mmap: resize arrays dynamically
-rw-r--r--src/journal/journal-file.c5
-rw-r--r--src/journal/journald.c2
-rw-r--r--src/journal/mmap-cache.c55
-rw-r--r--src/journal/mmap-cache.h2
-rw-r--r--src/journal/sd-journal.c5
5 files changed, 48 insertions, 21 deletions
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index df991a4a07..c6b25ce54b 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -2003,10 +2003,7 @@ int journal_file_open(
if (mmap_cache)
f->mmap = mmap_cache_ref(mmap_cache);
else {
- /* One context for each type, plus the zeroth catchall
- * context. One fd for the file plus one for each type
- * (which we need during verification */
- f->mmap = mmap_cache_new(_OBJECT_TYPE_MAX, 1 + _OBJECT_TYPE_MAX);
+ f->mmap = mmap_cache_new();
if (!f->mmap) {
r = -ENOMEM;
goto fail;
diff --git a/src/journal/journald.c b/src/journal/journald.c
index d431953f07..f74c46158a 100644
--- a/src/journal/journald.c
+++ b/src/journal/journald.c
@@ -2794,7 +2794,7 @@ static int server_init(Server *s) {
if (!s->user_journals)
return log_oom();
- s->mmap = mmap_cache_new(_OBJECT_TYPE_MAX, USER_JOURNALS_MAX + 2);
+ s->mmap = mmap_cache_new();
if (!s->mmap)
return log_oom();
diff --git a/src/journal/mmap-cache.c b/src/journal/mmap-cache.c
index 9782139f5a..69efb20ade 100644
--- a/src/journal/mmap-cache.c
+++ b/src/journal/mmap-cache.c
@@ -30,7 +30,10 @@
#include "mmap-cache.h"
#define WINDOW_SIZE (8ULL*1024ULL*1024ULL)
-#define WINDOWS_MAX 32
+
+#define DEFAULT_WINDOWS_MAX 64
+#define DEFAULT_FDS_MAX 32
+#define DEFAULT_CONTEXTS_MAX 32
typedef struct Window {
int fd;
@@ -236,19 +239,16 @@ static void mmap_cache_free(MMapCache *m) {
free(m);
}
-MMapCache* mmap_cache_new(unsigned contexts_max, unsigned fds_max) {
+MMapCache* mmap_cache_new(void) {
MMapCache *m;
- assert(contexts_max > 0);
- assert(fds_max > 0);
-
m = new0(MMapCache, 1);
if (!m)
return NULL;
- m->contexts_max = contexts_max;
- m->fds_max = fds_max;
- m->windows_max = MAX(m->contexts_max, WINDOWS_MAX);
+ m->contexts_max = DEFAULT_CONTEXTS_MAX;
+ m->fds_max = DEFAULT_FDS_MAX;
+ m->windows_max = DEFAULT_WINDOWS_MAX;
m->n_ref = 1;
m->lru_first = (unsigned) -1;
m->lru_last = (unsigned) -1;
@@ -465,8 +465,18 @@ static int mmap_cache_get_fd_index(MMapCache *m, int fd, unsigned *fd_index) {
if (r != 0)
return r;
- if (m->n_fds >= m->fds_max)
- return -E2BIG;
+ if (m->n_fds >= m->fds_max) {
+ unsigned k;
+ FileDescriptor *n;
+
+ k = m->n_fds * 2;
+ n = realloc(m->by_fd, sizeof(FileDescriptor) * k);
+ if (!n)
+ return -ENOMEM;
+
+ m->fds_max = k;
+ m->by_fd = n;
+ }
j = m->by_fd + m->n_fds ++;
j->fd = fd;
@@ -580,10 +590,33 @@ int mmap_cache_get(
assert(m);
assert(fd >= 0);
- assert(context < m->contexts_max);
assert(size > 0);
assert(ret);
+ if (context >= m->contexts_max) {
+ unsigned k, *n;
+ Window *w;
+
+ /* Increase the number of contexts if necessary, and
+ * make sure we have twice the number of windows */
+
+ k = context * 2;
+ n = realloc(m->by_context, sizeof(unsigned) * k);
+ if (!n)
+ return -ENOMEM;
+ memset(n + m->contexts_max, -1, (k - m->contexts_max) * sizeof(unsigned));
+ m->contexts_max = k;
+ m->by_context = n;
+
+ k = MAX(m->windows_max, m->contexts_max*2);
+ w = realloc(m->windows, sizeof(Window) * k);
+ if (!w)
+ return -ENOMEM;
+
+ m->windows_max = k;
+ m->windows = w;
+ }
+
/* Maybe the current pointer for this context is already the
* right one? */
r = mmap_cache_current(m, fd, context, offset, size, ret);
diff --git a/src/journal/mmap-cache.h b/src/journal/mmap-cache.h
index 984b759960..aae4544357 100644
--- a/src/journal/mmap-cache.h
+++ b/src/journal/mmap-cache.h
@@ -25,7 +25,7 @@
typedef struct MMapCache MMapCache;
-MMapCache* mmap_cache_new(unsigned contexts_max, unsigned fds_max);
+MMapCache* mmap_cache_new(void);
MMapCache* mmap_cache_ref(MMapCache *m);
MMapCache* mmap_cache_unref(MMapCache *m);
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index 41526b35bf..725c979c87 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -1439,10 +1439,7 @@ static sd_journal *journal_new(int flags, const char *path) {
return NULL;
}
- /* One context for each type, plus the zeroth catchall
- * context. One fd for each file plus one for each type, which
- * is need when verifying things */
- j->mmap = mmap_cache_new(_OBJECT_TYPE_MAX, JOURNAL_FILES_MAX + _OBJECT_TYPE_MAX);
+ j->mmap = mmap_cache_new();
if (!j->mmap) {
hashmap_free(j->files);
hashmap_free(j->directories_by_path);