diff --git a/src/libsystemd/sd-journal/mmap-cache.c b/src/libsystemd/sd-journal/mmap-cache.c index 11b1abd8b7..fc80862021 100644 --- a/src/libsystemd/sd-journal/mmap-cache.c +++ b/src/libsystemd/sd-journal/mmap-cache.c @@ -147,14 +147,11 @@ static bool window_matches(Window *w, MMapFileDescriptor *f, uint64_t offset, si offset + size <= w->offset + w->size; } -static Window *window_add(MMapCache *m, MMapFileDescriptor *f, bool keep_always, uint64_t offset, size_t size, void *ptr) { +static Window* window_add(MMapFileDescriptor *f, uint64_t offset, size_t size, void *ptr) { + MMapCache *m = mmap_cache_fd_cache(f); Window *w; - assert(m); - assert(f); - if (!m->last_unused || m->n_windows <= WINDOWS_MIN) { - /* Allocate a new window */ w = new(Window, 1); if (!w) @@ -167,15 +164,12 @@ static Window *window_add(MMapCache *m, MMapFileDescriptor *f, bool keep_always, *w = (Window) { .cache = m, .fd = f, - .keep_always = keep_always, .offset = offset, .size = size, .ptr = ptr, }; - LIST_PREPEND(by_fd, f->windows, w); - - return w; + return LIST_PREPEND(by_fd, f->windows, w); } static void context_detach_window(MMapCache *m, Context *c) { @@ -246,79 +240,6 @@ static MMapCache* mmap_cache_free(MMapCache *m) { DEFINE_TRIVIAL_REF_UNREF_FUNC(MMapCache, mmap_cache, mmap_cache_free); -static int try_context( - MMapFileDescriptor *f, - Context *c, - bool keep_always, - uint64_t offset, - size_t size, - void **ret) { - - assert(f); - assert(f->cache); - assert(f->cache->n_ref > 0); - assert(c); - assert(size > 0); - assert(ret); - - if (!c->window) - return 0; - - if (!window_matches(c->window, f, offset, size)) { - - /* Drop the reference to the window, since it's unnecessary now */ - context_detach_window(f->cache, c); - return 0; - } - - if (c->window->fd->sigbus) - return -EIO; - - c->window->keep_always = c->window->keep_always || keep_always; - - *ret = (uint8_t*) c->window->ptr + (offset - c->window->offset); - f->cache->n_context_cache_hit++; - - return 1; -} - -static int find_mmap( - MMapFileDescriptor *f, - Context *c, - bool keep_always, - uint64_t offset, - size_t size, - void **ret) { - - Window *found = NULL; - - assert(f); - assert(f->cache); - assert(f->cache->n_ref > 0); - assert(c); - assert(size > 0); - - if (f->sigbus) - return -EIO; - - LIST_FOREACH(by_fd, w, f->windows) - if (window_matches(w, f, offset, size)) { - found = w; - break; - } - - if (!found) - return 0; - - context_attach_window(f->cache, c, found); - found->keep_always = found->keep_always || keep_always; - - *ret = (uint8_t*) found->ptr + (offset - found->offset); - f->cache->n_window_list_hit++; - - return 1; -} - static int mmap_try_harder(MMapFileDescriptor *f, void *addr, int flags, uint64_t offset, size_t size, void **ret) { MMapCache *m = mmap_cache_fd_cache(f); @@ -346,12 +267,10 @@ static int mmap_try_harder(MMapFileDescriptor *f, void *addr, int flags, uint64_ static int add_mmap( MMapFileDescriptor *f, - Context *c, - bool keep_always, uint64_t offset, size_t size, struct stat *st, - void **ret) { + Window **ret) { uint64_t woffset, wsize; Window *w; @@ -359,9 +278,6 @@ static int add_mmap( int r; assert(f); - assert(f->cache); - assert(f->cache->n_ref > 0); - assert(c); assert(size > 0); assert(ret); @@ -397,19 +313,14 @@ static int add_mmap( if (r < 0) return r; - w = window_add(f->cache, f, keep_always, woffset, wsize, d); - if (!w) - goto outofmem; + w = window_add(f, woffset, wsize, d); + if (!w) { + (void) munmap(d, wsize); + return -ENOMEM; + } - context_attach_window(f->cache, c, w); - - *ret = (uint8_t*) w->ptr + (offset - w->offset); - - return 1; - -outofmem: - (void) munmap(d, wsize); - return -ENOMEM; + *ret = w; + return 0; } int mmap_cache_fd_get( @@ -421,32 +332,50 @@ int mmap_cache_fd_get( struct stat *st, void **ret) { + MMapCache *m = mmap_cache_fd_cache(f); Context *c; + Window *w; int r; - assert(f); - assert(f->cache); - assert(f->cache->n_ref > 0); + assert(context < MMAP_CACHE_MAX_CONTEXTS); assert(size > 0); assert(ret); - assert(context < MMAP_CACHE_MAX_CONTEXTS); + + if (f->sigbus) + return -EIO; c = &f->cache->contexts[context]; /* Check whether the current context is the right one already */ - r = try_context(f, c, keep_always, offset, size, ret); - if (r != 0) - return r; + if (window_matches(c->window, f, offset, size)) { + m->n_context_cache_hit++; + w = c->window; + goto found; + } + + /* Drop the reference to the window, since it's unnecessary now */ + context_detach_window(m, c); /* Search for a matching mmap */ - r = find_mmap(f, c, keep_always, offset, size, ret); - if (r != 0) - return r; + LIST_FOREACH(by_fd, i, f->windows) + if (window_matches(i, f, offset, size)) { + m->n_window_list_hit++; + w = i; + goto found; + } - f->cache->n_missed++; + m->n_missed++; /* Create a new mmap */ - return add_mmap(f, c, keep_always, offset, size, st, ret); + r = add_mmap(f, offset, size, st, &w); + if (r < 0) + return r; + +found: + w->keep_always = w->keep_always || keep_always; + context_attach_window(m, c, w); + *ret = (uint8_t*) w->ptr + (offset - w->offset); + return 0; } void mmap_cache_stats_log_debug(MMapCache *m) {