From: Yu Watanabe Date: Sat, 30 Sep 2023 03:03:13 +0000 (+0900) Subject: sd-journal: introduce journal_file_pin_object() X-Git-Tag: v255-rc1~11^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a1b8d21fab0708d055aeb63e17f83c2df501c185;p=thirdparty%2Fsystemd.git sd-journal: introduce journal_file_pin_object() Previously, OBJECT_UNUSED was used for 'pinning' the mmap cache for an object. But, OBJECT_UNUSED is also used for reading object when type cannot be determined before read, e.g. when reading the tail object. Let's introduce another category for pinning mmap cache, and use it when we want to temporary pin an object. --- diff --git a/src/libsystemd/sd-journal/journal-file.c b/src/libsystemd/sd-journal/journal-file.c index 44661427842..d803bbfca30 100644 --- a/src/libsystemd/sd-journal/journal-file.c +++ b/src/libsystemd/sd-journal/journal-file.c @@ -1125,6 +1125,16 @@ int journal_file_move_to_object(JournalFile *f, ObjectType type, uint64_t offset return 0; } +int journal_file_pin_object(JournalFile *f, Object *o) { + assert(f); + assert(o); + + /* This attaches the mmap window that provides the object to the 'pinning' category. So, reading + * another object with the same type will not invalidate the object, until this function is called + * for another object. */ + return mmap_cache_fd_pin(f->cache_fd, type_to_category(o->object.type), o, le64toh(o->object.size)); +} + int journal_file_read_object_header(JournalFile *f, ObjectType type, uint64_t offset, Object *ret) { ssize_t n; Object o; diff --git a/src/libsystemd/sd-journal/journal-file.h b/src/libsystemd/sd-journal/journal-file.h index 6c46dff4c45..183a5e43bb4 100644 --- a/src/libsystemd/sd-journal/journal-file.h +++ b/src/libsystemd/sd-journal/journal-file.h @@ -208,6 +208,7 @@ static inline bool VALID_EPOCH(uint64_t u) { FLAGS_SET(le32toh((h)->incompatible_flags), HEADER_INCOMPATIBLE_COMPACT) int journal_file_move_to_object(JournalFile *f, ObjectType type, uint64_t offset, Object **ret); +int journal_file_pin_object(JournalFile *f, Object *o); int journal_file_read_object_header(JournalFile *f, ObjectType type, uint64_t offset, Object *ret); int journal_file_tail_end_by_pread(JournalFile *f, uint64_t *ret_offset); diff --git a/src/libsystemd/sd-journal/mmap-cache.c b/src/libsystemd/sd-journal/mmap-cache.c index 3f22d83b282..973ade64c0f 100644 --- a/src/libsystemd/sd-journal/mmap-cache.c +++ b/src/libsystemd/sd-journal/mmap-cache.c @@ -384,6 +384,49 @@ found: return 0; } +int mmap_cache_fd_pin( + MMapFileDescriptor *f, + MMapCacheCategory c, + void *addr, + size_t size) { + + MMapCache *m = mmap_cache_fd_cache(f); + Window *w; + + assert(addr); + assert(c >= 0 && c < _MMAP_CACHE_CATEGORY_MAX); + assert(size > 0); + + if (f->sigbus) + return -EIO; + + /* Check if the current category is the right one. */ + if (window_matches_by_addr(m->windows_by_category[c], f, addr, size)) { + m->n_category_cache_hit++; + w = m->windows_by_category[c]; + goto found; + } + + /* Search for a matching mmap. */ + LIST_FOREACH(windows, i, f->windows) + if (window_matches_by_addr(i, f, addr, size)) { + m->n_window_list_hit++; + w = i; + goto found; + } + + m->n_missed++; + return -EADDRNOTAVAIL; /* Not found. */ + +found: + if (FLAGS_SET(w->flags, WINDOW_KEEP_ALWAYS)) + return 0; /* The window will never unmapped. */ + + /* Attach the window to the 'pinning' category. */ + category_attach_window(m, MMAP_CACHE_CATEGORY_PIN, w); + return 1; +} + void mmap_cache_stats_log_debug(MMapCache *m) { assert(m); diff --git a/src/libsystemd/sd-journal/mmap-cache.h b/src/libsystemd/sd-journal/mmap-cache.h index 7568746e932..1fbc236bda9 100644 --- a/src/libsystemd/sd-journal/mmap-cache.h +++ b/src/libsystemd/sd-journal/mmap-cache.h @@ -20,6 +20,7 @@ typedef enum MMapCacheCategory { MMAP_CACHE_CATEGORY_ENTRY_ARRAY = OBJECT_ENTRY_ARRAY, MMAP_CACHE_CATEGORY_TAG = OBJECT_TAG, MMAP_CACHE_CATEGORY_HEADER, /* for reading file header */ + MMAP_CACHE_CATEGORY_PIN, /* for temporary pinning a object */ _MMAP_CACHE_CATEGORY_MAX, _MMAP_CACHE_CATEGORY_INVALID = -EINVAL, } MMapCacheCategory; @@ -43,6 +44,13 @@ int mmap_cache_fd_get( size_t size, struct stat *st, void **ret); + +int mmap_cache_fd_pin( + MMapFileDescriptor *f, + MMapCacheCategory c, + void *addr, + size_t size); + int mmap_cache_add_fd(MMapCache *m, int fd, int prot, MMapFileDescriptor **ret); MMapCache* mmap_cache_fd_cache(MMapFileDescriptor *f); MMapFileDescriptor* mmap_cache_fd_free(MMapFileDescriptor *f); diff --git a/src/libsystemd/sd-journal/sd-journal.c b/src/libsystemd/sd-journal/sd-journal.c index c61573f8606..73a65da7502 100644 --- a/src/libsystemd/sd-journal/sd-journal.c +++ b/src/libsystemd/sd-journal/sd-journal.c @@ -3190,20 +3190,14 @@ _public_ int sd_journal_enumerate_unique( continue; } - /* We do not use OBJECT_DATA context here, but OBJECT_UNUSED - * instead, so that we can look at this data object at the same - * time as one on another file */ - r = journal_file_move_to_object(j->unique_file, OBJECT_UNUSED, j->unique_offset, &o); + r = journal_file_move_to_object(j->unique_file, OBJECT_DATA, j->unique_offset, &o); if (r < 0) return r; - /* Let's do the type check by hand, since we used 0 context above. */ - if (o->object.type != OBJECT_DATA) - return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), - "%s:offset " OFSfmt ": object has type %d, expected %d", - j->unique_file->path, - j->unique_offset, - o->object.type, OBJECT_DATA); + /* Let's pin the data object, so we can look at it at the same time as one on another file. */ + r = journal_file_pin_object(j->unique_file, o); + if (r < 0) + return r; r = journal_file_data_payload(j->unique_file, o, j->unique_offset, NULL, 0, j->data_threshold, &odata, &ol);