journal-file.c revision 294330896d1ad26c10eecf6c3bf20d73b5ec624b
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering This file is part of systemd.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Copyright 2011 Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is free software; you can redistribute it and/or modify it
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering under the terms of the GNU Lesser General Public License as published by
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (at your option) any later version.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is distributed in the hope that it will be useful, but
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Lesser General Public License for more details.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering You should have received a copy of the GNU Lesser General Public License
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#define DEFAULT_DATA_HASH_TABLE_SIZE (2047ULL*sizeof(HashItem))
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering#define DEFAULT_FIELD_HASH_TABLE_SIZE (333ULL*sizeof(HashItem))
b93312f5960b276bae915906ccde36f545bae3e0Zbigniew Jędrzejewski-Szmek#define COMPRESSION_SIZE_THRESHOLD (512ULL)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/* This is the minimum journal file size */
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering#define JOURNAL_FILE_SIZE_MIN (4ULL*1024ULL*1024ULL) /* 4 MiB */
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering/* These are the lower and upper bounds if we deduce the max_use value
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering * from the file system size */
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering#define DEFAULT_MAX_USE_LOWER (1ULL*1024ULL*1024ULL) /* 1 MiB */
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering#define DEFAULT_MAX_USE_UPPER (4ULL*1024ULL*1024ULL*1024ULL) /* 4 GiB */
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering/* This is the upper bound if we deduce max_size from max_use */
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering#define DEFAULT_MAX_SIZE_UPPER (128ULL*1024ULL*1024ULL) /* 128 MiB */
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering/* This is the upper bound if we deduce the keep_free value from the
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering * file system size */
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering#define DEFAULT_KEEP_FREE_UPPER (4ULL*1024ULL*1024ULL*1024ULL) /* 4 GiB */
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering/* This is the keep_free value when we can't determine the system
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering#define DEFAULT_KEEP_FREE (1024ULL*1024ULL) /* 1 MB */
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering/* n_data was the first entry we added after the initial file format design */
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering#define HEADER_SIZE_MIN ALIGN64(offsetof(Header, n_data))
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering/* How many entries to keep in the entry array chain cache at max */
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering/* How much to increase the journal file size at once each time we allocate something new. */
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering#define FILE_SIZE_INCREASE (8ULL*1024ULL*1024ULL) /* 8MB */
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poetteringstatic int journal_file_set_online(JournalFile *f) {
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poetteringint journal_file_set_offline(JournalFile *f) {
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering /* Write the final tag */
8ac4e9e1e54397f6d1745c2a7a806132418c7da2Lennart Poettering /* Sync everything to disk, before we mark the file offline */
2e276efc7b0398a3086629a52970bdd4ab7252f9Zbigniew Jędrzejewski-Szmek munmap(f->header, PAGE_ALIGN(sizeof(Header)));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering ordered_hashmap_free_free(f->chain_cache);
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering munmap(f->fss_file, PAGE_ALIGN(f->fss_file_size));
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmekstatic int journal_file_init_header(JournalFile *f, JournalFile *template) {
42cc2eebb01056beb7acd3ecfe8e533558237f84Lennart Poettering memcpy(h.signature, HEADER_SIGNATURE, 8);
abf126a355e2f2b62b6c51ab3bb37895d1e3eee7Tom Gundersen f->compress_xz * HEADER_INCOMPATIBLE_COMPRESSED_XZ |
abf126a355e2f2b62b6c51ab3bb37895d1e3eee7Tom Gundersen f->compress_lz4 * HEADER_INCOMPATIBLE_COMPRESSED_LZ4);
42cc2eebb01056beb7acd3ecfe8e533558237f84Lennart Poettering h.seqnum_id = template->header->seqnum_id;
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmek h.tail_entry_seqnum = template->header->tail_entry_seqnum;
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmek if (k != sizeof(h))
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmekstatic int journal_file_refresh_header(JournalFile *f) {
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek r = sd_id128_get_machine(&f->header->machine_id);
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersen if (sd_id128_equal(boot_id, f->header->boot_id))
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen /* Sync the online state to disk */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int journal_file_verify_header(JournalFile *f) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (memcmp(f->header->signature, HEADER_SIGNATURE, 8))
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering /* In both read and write mode we refuse to open files with
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering * incompatible flags we don't know */
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering flags = le32toh(f->header->incompatible_flags);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (flags & ~HEADER_INCOMPATIBLE_SUPPORTED) {
36d9205d669bcdcb04fa730d1f3549a9fc9a9001Tom Gundersen log_debug("Journal file %s has unknown incompatible flags %"PRIx32,
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering f->path, flags & ~HEADER_INCOMPATIBLE_ANY);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering flags = (flags & HEADER_INCOMPATIBLE_ANY) & ~HEADER_INCOMPATIBLE_SUPPORTED;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering log_debug("Journal file %s uses incompatible flags %"PRIx32
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering " disabled at compilation time.", f->path, flags);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering /* When open for writing we refuse to open files with
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering * compatible flags, too */
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering flags = le32toh(f->header->compatible_flags);
8bf52d3d17d364438191077d0750b8b80b5dc53aLennart Poettering if (f->writable && (flags & ~HEADER_COMPATIBLE_SUPPORTED)) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("Journal file %s has unknown compatible flags %"PRIx32,
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering f->path, flags & ~HEADER_COMPATIBLE_ANY);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering flags = (flags & HEADER_COMPATIBLE_ANY) & ~HEADER_COMPATIBLE_SUPPORTED;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering log_debug("Journal file %s uses compatible flags %"PRIx32
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering " disabled at compilation time.", f->path, flags);
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering /* The first addition was n_data, so check that we are at least this large */
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (le64toh(f->header->header_size) < HEADER_SIZE_MIN)
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering if (JOURNAL_HEADER_SEALED(f->header) && !JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays))
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering if ((le64toh(f->header->header_size) + le64toh(f->header->arena_size)) > (uint64_t) f->last_stat.st_size)
if (le64toh(f->header->tail_object_offset) > (le64toh(f->header->header_size) + le64toh(f->header->arena_size)))
return -ENODATA;
return -ENODATA;
if (f->writable) {
return -EHOSTDOWN;
return -EBUSY;
return -ESHUTDOWN;
return -EBUSY;
assert(f);
old_size =
return -E2BIG;
available = 0;
return -E2BIG;
return -errno;
static int journal_file_move_to(JournalFile *f, int context, bool keep_always, uint64_t offset, uint64_t size, void **ret) {
assert(f);
if (size <= 0)
return -EINVAL;
return -EADDRNOTAVAIL;
return mmap_cache_get(f->mmap, f->fd, f->prot, context, keep_always, offset, size, &f->last_stat, ret, NULL);
return sizeof(ObjectHeader);
Object *o;
uint64_t s;
assert(f);
return -EFAULT;
o = (Object*) t;
if (s < sizeof(ObjectHeader))
return -EBADMSG;
return -EBADMSG;
if (s < minimum_header_size(o))
return -EBADMSG;
return -EBADMSG;
if (s > sizeof(ObjectHeader)) {
o = (Object*) t;
*ret = o;
uint64_t r;
assert(f);
if (seqnum) {
*seqnum = r;
int journal_file_append_object(JournalFile *f, int type, uint64_t size, Object **ret, uint64_t *offset) {
uint64_t p;
assert(f);
r = journal_file_set_online(f);
o = (Object*) t;
*ret = o;
*offset = p;
uint64_t s, p;
Object *o;
assert(f);
if (s < DEFAULT_DATA_HASH_TABLE_SIZE)
r = journal_file_append_object(f,
uint64_t s, p;
Object *o;
assert(f);
r = journal_file_append_object(f,
uint64_t s, p;
assert(f);
r = journal_file_move_to(f,
f->data_hash_table = t;
uint64_t s, p;
assert(f);
r = journal_file_move_to(f,
f->field_hash_table = t;
static int journal_file_link_field(
JournalFile *f,
Object *o,
uint64_t p, h;
assert(f);
assert(o);
return -EINVAL;
static int journal_file_link_data(
JournalFile *f,
Object *o,
uint64_t p, h;
assert(f);
assert(o);
return -EINVAL;
JournalFile *f,
assert(f);
return -EBADMSG;
Object *o;
if (ret)
*ret = o;
if (offset)
*offset = p;
JournalFile *f,
assert(f);
return journal_file_find_field_object_with_hash(f,
JournalFile *f,
assert(f);
return -EBADMSG;
Object *o;
goto next;
uint64_t l;
return -EBADMSG;
if (ret)
*ret = o;
if (offset)
*offset = p;
return -EPROTONOSUPPORT;
if (ret)
*ret = o;
if (offset)
*offset = p;
next:
JournalFile *f,
assert(f);
return journal_file_find_data_object_with_hash(f,
static int journal_file_append_field(
JournalFile *f,
Object *o;
assert(f);
if (ret)
*ret = o;
if (offset)
*offset = p;
#ifdef HAVE_GCRYPT
if (ret)
*ret = o;
if (offset)
*offset = p;
static int journal_file_append_data(
JournalFile *f,
Object *o;
int r, compression = 0;
const void *eq;
assert(f);
if (ret)
*ret = o;
if (offset)
*offset = p;
if (f->compress_xz &&
if (compression) {
if (!data)
#ifdef HAVE_GCRYPT
if (ret)
*ret = o;
if (offset)
*offset = p;
assert(o);
assert(o);
assert(o);
uint64_t p) {
Object *o;
assert(f);
assert(p > 0);
n = journal_file_entry_array_n_items(o);
ap = a;
if (hidx > n)
#ifdef HAVE_GCRYPT
if (ap == 0)
uint64_t p) {
assert(f);
assert(p > 0);
if (*idx == 0)
le64_t i;
uint64_t p;
assert(f);
assert(o);
return -EINVAL;
return link_entry_into_array_plus_one(f,
offset);
uint64_t n, i;
assert(f);
assert(o);
return -EINVAL;
r = link_entry_into_array(f,
offset);
/* log_debug("=> %s seqnr=%"PRIu64" n_entries=%"PRIu64, f->path, o->entry.seqnum, f->header->n_entries); */
f->tail_entry_monotonic_valid = true;
n = journal_file_entry_n_items(o);
static int journal_file_append_entry_internal(
JournalFile *f,
Object *o;
assert(f);
#ifdef HAVE_GCRYPT
if (ret)
*ret = o;
if (offset)
assert(f);
int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const struct iovec iovec[], unsigned n_iovec, uint64_t *seqnum, Object **ret, uint64_t *offset) {
assert(f);
if (!ts) {
if (f->tail_entry_monotonic_valid &&
return -EINVAL;
#ifdef HAVE_GCRYPT
for (i = 0; i < n_iovec; i++) {
uint64_t p;
Object *o;
typedef struct ChainCacheItem {
static void chain_cache_put(
OrderedHashmap *h,
if (!ci) {
if (!ci)
static int generic_array_get(
JournalFile *f,
uint64_t i,
Object *o;
uint64_t p = 0, a, t = 0;
assert(f);
a = first;
uint64_t k;
k = journal_file_entry_array_n_items(o);
goto found;
if (ret)
*ret = o;
if (offset)
*offset = p;
static int generic_array_get_plus_one(
JournalFile *f,
uint64_t i,
Object *o;
assert(f);
if (ret)
*ret = o;
if (offset)
static int generic_array_bisect(
JournalFile *f,
uint64_t n,
bool subtract_one = false;
assert(f);
a = first;
if (r == TEST_LEFT) {
if (right <= 0)
return -EBADMSG;
if (r == TEST_FOUND)
if (r == TEST_RIGHT) {
left = 0;
if (last_index > 0) {
return -EBADMSG;
if (r == TEST_FOUND)
if (r == TEST_RIGHT)
right = x;
return -EBADMSG;
if (r == TEST_FOUND)
if (r == TEST_RIGHT)
right = y;
subtract_one = true;
i = left;
goto found;
return -EBADMSG;
if (r == TEST_FOUND)
if (r == TEST_RIGHT)
right = i;
subtract_one = true;
goto found;
if (subtract_one && t == 0 && i == 0)
chain_cache_put(f->chain_cache, ci, first, a, le64toh(array->entry_array.items[0]), t, subtract_one ? (i > 0 ? i-1 : (uint64_t) -1) : i);
if (subtract_one && i == 0)
p = last_p;
else if (subtract_one)
if (ret)
*ret = o;
if (offset)
*offset = p;
if (idx)
static int generic_array_bisect_plus_one(
JournalFile *f,
uint64_t n,
bool step_back = false;
Object *o;
assert(f);
if (r == TEST_FOUND)
if (r == TEST_LEFT)
if (r == TEST_RIGHT) {
goto found;
if (r == 0 && step_back)
goto found;
if (r > 0 && idx)
(*idx) ++;
if (ret)
*ret = o;
if (offset)
if (idx)
*idx = 0;
assert(f);
assert(p > 0);
if (p == needle)
return TEST_FOUND;
else if (p < needle)
return TEST_LEFT;
return TEST_RIGHT;
JournalFile *f,
uint64_t p,
return generic_array_bisect(f,
Object *o;
assert(f);
assert(p > 0);
return TEST_FOUND;
return TEST_LEFT;
return TEST_RIGHT;
JournalFile *f,
return generic_array_bisect(f,
Object *o;
assert(f);
assert(p > 0);
return TEST_FOUND;
return TEST_LEFT;
return TEST_RIGHT;
JournalFile *f,
return generic_array_bisect(f,
Object *o;
assert(f);
assert(p > 0);
return TEST_FOUND;
return TEST_LEFT;
return TEST_RIGHT;
static inline int find_data_object_by_boot_id(
JournalFile *f,
Object **o,
uint64_t *b) {
JournalFile *f,
Object *o;
assert(f);
return -ENOENT;
return generic_array_bisect_plus_one(f,
JournalFile *f,
assert(f);
assert(p > 0 || !o);
return -EINVAL;
r = generic_array_bisect(f,
r = generic_array_get(f,
f->path, i);
return -EBADMSG;
if (offset)
JournalFile *f,
uint64_t i, n;
assert(f);
assert(o);
assert(p > 0);
return -EINVAL;
r = generic_array_bisect(f,
if (skip < 0) {
return -EBADMSG;
return generic_array_get(f,
JournalFile *f,
uint64_t n, i;
Object *d;
assert(f);
assert(p > 0 || !o);
return -EINVAL;
return generic_array_get_plus_one(f,
JournalFile *f,
uint64_t p,
Object *d;
assert(f);
return generic_array_bisect_plus_one(f,
JournalFile *f,
Object *o, *d;
uint64_t b, z;
assert(f);
return -ENOENT;
uint64_t p, q;
if (ret)
if (offset)
*offset = q;
JournalFile *f,
Object *d;
assert(f);
return generic_array_bisect_plus_one(f,
JournalFile *f,
Object *d;
assert(f);
return generic_array_bisect_plus_one(f,
Object *o;
uint64_t p;
assert(f);
goto fail;
case OBJECT_UNUSED:
case OBJECT_DATA:
case OBJECT_FIELD:
case OBJECT_ENTRY:
case OBJECT_FIELD_HASH_TABLE:
case OBJECT_DATA_HASH_TABLE:
case OBJECT_ENTRY_ARRAY:
case OBJECT_TAG:
fail:
assert(f);
f->path,
100.0 * (double) le64toh(f->header->n_data) / ((double) (le64toh(f->header->data_hash_table_size) / sizeof(HashItem))));
100.0 * (double) le64toh(f->header->n_fields) / ((double) (le64toh(f->header->field_hash_table_size) / sizeof(HashItem))));
int journal_file_open(
const char *fname,
int flags,
bool compress,
bool seal,
JournalFile *f;
bool newly_created = false;
return -EINVAL;
return -EINVAL;
return -ENOMEM;
#if defined(HAVE_LZ4)
#ifdef HAVE_GCRYPT
if (mmap_cache)
if (!f->mmap) {
r = -ENOMEM;
goto fail;
if (!f->path) {
r = -ENOMEM;
goto fail;
if (!f->chain_cache) {
r = -ENOMEM;
goto fail;
if (f->fd < 0) {
r = -errno;
goto fail;
r = -errno;
goto fail;
#ifdef HAVE_GCRYPT
if (f->seal) {
r = journal_file_fss_load(f);
f->seal = false;
goto fail;
r = -errno;
goto fail;
newly_created = true;
r = -EIO;
goto fail;
r = -errno;
goto fail;
if (!newly_created) {
r = journal_file_verify_header(f);
goto fail;
#ifdef HAVE_GCRYPT
r = journal_file_fss_load(f);
goto fail;
if (f->writable) {
if (metrics) {
} else if (template)
r = journal_file_refresh_header(f);
goto fail;
#ifdef HAVE_GCRYPT
r = journal_file_hmac_setup(f);
goto fail;
if (newly_created) {
goto fail;
goto fail;
#ifdef HAVE_GCRYPT
r = journal_file_append_first_tag(f);
goto fail;
goto fail;
r = journal_file_map_data_hash_table(f);
goto fail;
*ret = f;
fail:
size_t l;
assert(f);
assert(*f);
old_file = *f;
return -EINVAL;
return -EINVAL;
return -ENOMEM;
return -errno;
r = journal_file_open(old_file->path, old_file->flags, old_file->mode, compress, seal, NULL, old_file->mmap, old_file, &new_file);
*f = new_file;
const char *fname,
int flags,
bool compress,
bool seal,
size_t l;
random_u64()) < 0)
return -ENOMEM;
return -errno;
int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint64_t p, uint64_t *seqnum, Object **ret, uint64_t *offset) {
uint64_t i, n;
assert(o);
assert(p);
return -EPERM;
n = journal_file_entry_n_items(o);
uint64_t l, h;
size_t t;
void *data;
Object *u;
return -EBADMSG;
t = (size_t) l;
if ((uint64_t) t != l)
return -E2BIG;
l = rsize;
return -EPROTONOSUPPORT;
assert(m);
if (fs_size > 0) {
if (fs_size > 0) {
assert(f);
if (from) {
return -ENOENT;
if (to) {
return -ENOENT;
int journal_file_get_cutoff_monotonic_usec(JournalFile *f, sd_id128_t boot_id, usec_t *from, usec_t *to) {
Object *o;
uint64_t p;
assert(f);
if (from) {
if (to) {
r = generic_array_get_plus_one(f,
&o, NULL);
assert(f);
if (le64toh(f->header->n_data) * 4ULL > (le64toh(f->header->data_hash_table_size) / sizeof(HashItem)) * 3ULL) {
log_debug("Data hash table of %s has a fill level at %.1f (%"PRIu64" of %"PRIu64" items, %llu file size, %"PRIu64" bytes per hash table item), suggesting rotation.",
f->path,
100.0 * (double) le64toh(f->header->n_data) / ((double) (le64toh(f->header->data_hash_table_size) / sizeof(HashItem))),
if (le64toh(f->header->n_fields) * 4ULL > (le64toh(f->header->field_hash_table_size) / sizeof(HashItem)) * 3ULL) {
log_debug("Field hash table of %s has a fill level at %.1f (%"PRIu64" of %"PRIu64" items), suggesting rotation.",
f->path,
100.0 * (double) le64toh(f->header->n_fields) / ((double) (le64toh(f->header->field_hash_table_size) / sizeof(HashItem))),
if (max_file_usec > 0) {
usec_t t, h;
if (h > 0 && t > h + max_file_usec)