From: Lennart Poettering Date: Fri, 17 Aug 2012 23:46:20 +0000 (+0200) Subject: mmap: resize arrays dynamically X-Git-Tag: v189~43 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=84168d8068bb67dcd5468ab3b376535d81643aef;ds=inline mmap: resize arrays dynamically --- diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index df991a4a0..c6b25ce54 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 d431953f0..f74c46158 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 9782139f5..69efb20ad 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 984b75996..aae454435 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 41526b35b..725c979c8 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);