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;
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);
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);
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;
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);
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);