/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include <errno.h>
#include <fcntl.h>
#include <linux/fs.h>
#include <linux/magic.h>
#include <pthread.h>
#include <stddef.h>
#include <sys/mman.h>
#include <sys/statvfs.h>
#include <sys/uio.h>
#include <unistd.h>

#include "sd-event.h"

#include "alloc-util.h"
#include "chattr-util.h"
#include "compress.h"
#include "env-util.h"
#include "fd-util.h"
#include "format-util.h"
#include "fs-util.h"
#include "id128-util.h"
#if HAVE_GCRYPT
#include "journal-authenticate.h"
#endif
#include "journal-def.h"
#include "journal-file.h"
#include "journal-internal.h"
#include "lookup3.h"
#include "memory-util.h"
#include "path-util.h"
#include "random-util.h"
#include "set.h"
#include "sort-util.h"
#include "stat-util.h"
#include "string-table.h"
#include "string-util.h"
#include "strv.h"
#include "sync-util.h"
#include "user-util.h"
#include "xattr-util.h"

#define DEFAULT_DATA_HASH_TABLE_SIZE (2047ULL*sizeof(HashItem))
#define DEFAULT_FIELD_HASH_TABLE_SIZE (333ULL*sizeof(HashItem))

#define DEFAULT_COMPRESS_THRESHOLD (512ULL)
#define MIN_COMPRESS_THRESHOLD (8ULL)

/* This is the minimum journal file size */
#define JOURNAL_FILE_SIZE_MIN (512 * 1024ULL)             /* 512 KiB */
#define JOURNAL_COMPACT_SIZE_MAX UINT32_MAX               /* 4 GiB */

/* These are the lower and upper bounds if we deduce the max_use value
 * from the file system size */
#define MAX_USE_LOWER (1 * 1024 * 1024ULL)                /* 1 MiB */
#define MAX_USE_UPPER (4 * 1024 * 1024 * 1024ULL)         /* 4 GiB */

/* Those are the lower and upper bounds for the minimal use limit,
 * i.e. how much we'll use even if keep_free suggests otherwise. */
#define MIN_USE_LOW (1 * 1024 * 1024ULL)                  /* 1 MiB */
#define MIN_USE_HIGH (16 * 1024 * 1024ULL)                /* 16 MiB */

/* This is the upper bound if we deduce max_size from max_use */
#define MAX_SIZE_UPPER (128 * 1024 * 1024ULL)             /* 128 MiB */

/* This is the upper bound if we deduce the keep_free value from the
 * file system size */
#define KEEP_FREE_UPPER (4 * 1024 * 1024 * 1024ULL)       /* 4 GiB */

/* This is the keep_free value when we can't determine the system
 * size */
#define DEFAULT_KEEP_FREE (1024 * 1024ULL)                /* 1 MB */

/* This is the default maximum number of journal files to keep around. */
#define DEFAULT_N_MAX_FILES 100

/* n_data was the first entry we added after the initial file format design */
#define HEADER_SIZE_MIN ALIGN64(offsetof(Header, n_data))

/* How many entries to keep in the entry array chain cache at max */
#define CHAIN_CACHE_MAX 20

/* How much to increase the journal file size at once each time we allocate something new. */
#define FILE_SIZE_INCREASE (8 * 1024 * 1024ULL)          /* 8MB */

/* Reread fstat() of the file for detecting deletions at least this often */
#define LAST_STAT_REFRESH_USEC (5*USEC_PER_SEC)

/* The mmap context to use for the header we pick as one above the last defined typed */
#define CONTEXT_HEADER _OBJECT_TYPE_MAX

/* Longest hash chain to rotate after */
#define HASH_CHAIN_DEPTH_MAX 100

#ifdef __clang__
#  pragma GCC diagnostic ignored "-Waddress-of-packed-member"
#endif

static int mmap_prot_from_open_flags(int flags) {
        switch (flags & O_ACCMODE) {
        case O_RDONLY:
                return PROT_READ;
        case O_WRONLY:
                return PROT_WRITE;
        case O_RDWR:
                return PROT_READ|PROT_WRITE;
        default:
                assert_not_reached();
        }
}

int journal_file_tail_end_by_pread(JournalFile *f, uint64_t *ret_offset) {
        uint64_t p;
        int r;

        assert(f);
        assert(f->header);
        assert(ret_offset);

        /* Same as journal_file_tail_end_by_mmap() below, but operates with pread() to avoid the mmap cache
         * (and thus is thread safe) */

        p = le64toh(f->header->tail_object_offset);
        if (p == 0)
                p = le64toh(f->header->header_size);
        else {
                Object tail;
                uint64_t sz;

                r = journal_file_read_object_header(f, OBJECT_UNUSED, p, &tail);
                if (r < 0)
                        return r;

                sz = le64toh(tail.object.size);
                if (sz > UINT64_MAX - sizeof(uint64_t) + 1)
                        return -EBADMSG;

                sz = ALIGN64(sz);
                if (p > UINT64_MAX - sz)
                        return -EBADMSG;

                p += sz;
        }

        *ret_offset = p;

        return 0;
}

int journal_file_tail_end_by_mmap(JournalFile *f, uint64_t *ret_offset) {
        uint64_t p;
        int r;

        assert(f);
        assert(f->header);
        assert(ret_offset);

        /* Same as journal_file_tail_end_by_pread() above, but operates with the usual mmap logic */

        p = le64toh(f->header->tail_object_offset);
        if (p == 0)
                p = le64toh(f->header->header_size);
        else {
                Object *tail;
                uint64_t sz;

                r = journal_file_move_to_object(f, OBJECT_UNUSED, p, &tail);
                if (r < 0)
                        return r;

                sz = le64toh(READ_NOW(tail->object.size));
                if (sz > UINT64_MAX - sizeof(uint64_t) + 1)
                        return -EBADMSG;

                sz = ALIGN64(sz);
                if (p > UINT64_MAX - sz)
                        return -EBADMSG;

                p += sz;
        }

        *ret_offset = p;

        return 0;
}

int journal_file_set_offline_thread_join(JournalFile *f) {
        int r;

        assert(f);

        if (f->offline_state == OFFLINE_JOINED)
                return 0;

        r = pthread_join(f->offline_thread, NULL);
        if (r)
                return -r;

        f->offline_state = OFFLINE_JOINED;

        if (mmap_cache_fd_got_sigbus(f->cache_fd))
                return -EIO;

        return 0;
}

static int journal_file_set_online(JournalFile *f) {
        bool wait = true;

        assert(f);

        if (!journal_file_writable(f))
                return -EPERM;

        if (f->fd < 0 || !f->header)
                return -EINVAL;

        while (wait) {
                switch (f->offline_state) {
                case OFFLINE_JOINED:
                        /* No offline thread, no need to wait. */
                        wait = false;
                        break;

                case OFFLINE_SYNCING: {
                                OfflineState tmp_state = OFFLINE_SYNCING;
                                if (!__atomic_compare_exchange_n(&f->offline_state, &tmp_state, OFFLINE_CANCEL,
                                    false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST))
                                        continue;
                        }
                        /* Canceled syncing prior to offlining, no need to wait. */
                        wait = false;
                        break;

                case OFFLINE_AGAIN_FROM_SYNCING: {
                                OfflineState tmp_state = OFFLINE_AGAIN_FROM_SYNCING;
                                if (!__atomic_compare_exchange_n(&f->offline_state, &tmp_state, OFFLINE_CANCEL,
                                    false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST))
                                        continue;
                        }
                        /* Canceled restart from syncing, no need to wait. */
                        wait = false;
                        break;

                case OFFLINE_AGAIN_FROM_OFFLINING: {
                                OfflineState tmp_state = OFFLINE_AGAIN_FROM_OFFLINING;
                                if (!__atomic_compare_exchange_n(&f->offline_state, &tmp_state, OFFLINE_CANCEL,
                                    false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST))
                                        continue;
                        }
                        /* Canceled restart from offlining, must wait for offlining to complete however. */
                        _fallthrough_;
                default: {
                        int r;

                        r = journal_file_set_offline_thread_join(f);
                        if (r < 0)
                                return r;

                        wait = false;
                        break;
                }
                }
        }

        if (mmap_cache_fd_got_sigbus(f->cache_fd))
                return -EIO;

        switch (f->header->state) {
                case STATE_ONLINE:
                        return 0;

                case STATE_OFFLINE:
                        f->header->state = STATE_ONLINE;
                        (void) fsync(f->fd);
                        return 0;

                default:
                        return -EINVAL;
        }
}

JournalFile* journal_file_close(JournalFile *f) {
        if (!f)
                return NULL;

        if (f->cache_fd)
                mmap_cache_fd_free(f->cache_fd);

        if (f->close_fd)
                safe_close(f->fd);
        free(f->path);

        ordered_hashmap_free_free(f->chain_cache);

#if HAVE_COMPRESSION
        free(f->compress_buffer);
#endif

#if HAVE_GCRYPT
        if (f->fss_file)
                munmap(f->fss_file, PAGE_ALIGN(f->fss_file_size));
        else
                free(f->fsprg_state);

        free(f->fsprg_seed);

        if (f->hmac)
                gcry_md_close(f->hmac);
#endif

        return mfree(f);
}

static bool keyed_hash_requested(void) {
        int r;

        r = getenv_bool("SYSTEMD_JOURNAL_KEYED_HASH");
        if (r >= 0)
                return r;
        if (r != -ENXIO)
                log_debug_errno(r, "Failed to parse $SYSTEMD_JOURNAL_KEYED_HASH environment variable, ignoring: %m");

        return true;
}

static bool compact_mode_requested(void) {
        int r;

        r = getenv_bool("SYSTEMD_JOURNAL_COMPACT");
        if (r >= 0)
                return r;
        if (r != -ENXIO)
                log_debug_errno(r, "Failed to parse $SYSTEMD_JOURNAL_COMPACT environment variable, ignoring: %m");

        return true;
}

static int journal_file_init_header(
                JournalFile *f,
                JournalFileFlags file_flags,
                JournalFile *template) {

        bool seal = false;
        ssize_t k;
        int r;

        assert(f);

#if HAVE_GCRYPT
        /* Try to load the FSPRG state, and if we can't, then just don't do sealing */
        seal = FLAGS_SET(file_flags, JOURNAL_SEAL) && journal_file_fss_load(f) >= 0;
#endif

        Header h = {
                .header_size = htole64(ALIGN64(sizeof(h))),
                .incompatible_flags = htole32(
                                FLAGS_SET(file_flags, JOURNAL_COMPRESS) * COMPRESSION_TO_HEADER_INCOMPATIBLE_FLAG(DEFAULT_COMPRESSION) |
                                keyed_hash_requested() * HEADER_INCOMPATIBLE_KEYED_HASH |
                                compact_mode_requested() * HEADER_INCOMPATIBLE_COMPACT),
                .compatible_flags = htole32(seal * HEADER_COMPATIBLE_SEALED),
        };

        assert_cc(sizeof(h.signature) == sizeof(HEADER_SIGNATURE));
        memcpy(h.signature, HEADER_SIGNATURE, sizeof(HEADER_SIGNATURE));

        r = sd_id128_randomize(&h.file_id);
        if (r < 0)
                return r;

        if (template) {
                h.seqnum_id = template->header->seqnum_id;
                h.tail_entry_seqnum = template->header->tail_entry_seqnum;
        } else
                h.seqnum_id = h.file_id;

        k = pwrite(f->fd, &h, sizeof(h), 0);
        if (k < 0)
                return -errno;
        if (k != sizeof(h))
                return -EIO;

        return 0;
}

static int journal_file_refresh_header(JournalFile *f) {
        int r;

        assert(f);
        assert(f->header);

        r = sd_id128_get_machine(&f->header->machine_id);
        if (r < 0) {
                if (!ERRNO_IS_MACHINE_ID_UNSET(r))
                        return r;

                /* don't have a machine-id, let's continue without */
                f->header->machine_id = SD_ID128_NULL;
        }

        r = sd_id128_get_boot(&f->header->boot_id);
        if (r < 0)
                return r;

        r = journal_file_set_online(f);

        /* Sync the online state to disk; likely just created a new file, also sync the directory this file
         * is located in. */
        (void) fsync_full(f->fd);

        return r;
}

static bool warn_wrong_flags(const JournalFile *f, bool compatible) {
        const uint32_t any = compatible ? HEADER_COMPATIBLE_ANY : HEADER_INCOMPATIBLE_ANY,
                supported = compatible ? HEADER_COMPATIBLE_SUPPORTED : HEADER_INCOMPATIBLE_SUPPORTED;
        const char *type = compatible ? "compatible" : "incompatible";
        uint32_t flags;

        assert(f);
        assert(f->header);

        flags = le32toh(compatible ? f->header->compatible_flags : f->header->incompatible_flags);

        if (flags & ~supported) {
                if (flags & ~any)
                        log_debug("Journal file %s has unknown %s flags 0x%"PRIx32,
                                  f->path, type, flags & ~any);
                flags = (flags & any) & ~supported;
                if (flags) {
                        const char* strv[6];
                        size_t n = 0;
                        _cleanup_free_ char *t = NULL;

                        if (compatible) {
                                if (flags & HEADER_COMPATIBLE_SEALED)
                                        strv[n++] = "sealed";
                        } else {
                                if (flags & HEADER_INCOMPATIBLE_COMPRESSED_XZ)
                                        strv[n++] = "xz-compressed";
                                if (flags & HEADER_INCOMPATIBLE_COMPRESSED_LZ4)
                                        strv[n++] = "lz4-compressed";
                                if (flags & HEADER_INCOMPATIBLE_COMPRESSED_ZSTD)
                                        strv[n++] = "zstd-compressed";
                                if (flags & HEADER_INCOMPATIBLE_KEYED_HASH)
                                        strv[n++] = "keyed-hash";
                                if (flags & HEADER_INCOMPATIBLE_COMPACT)
                                        strv[n++] = "compact";
                        }
                        strv[n] = NULL;
                        assert(n < ELEMENTSOF(strv));

                        t = strv_join((char**) strv, ", ");
                        log_debug("Journal file %s uses %s %s %s disabled at compilation time.",
                                  f->path, type, n > 1 ? "flags" : "flag", strnull(t));
                }
                return true;
        }

        return false;
}

static int journal_file_verify_header(JournalFile *f) {
        uint64_t arena_size, header_size;

        assert(f);
        assert(f->header);

        if (memcmp(f->header->signature, HEADER_SIGNATURE, 8))
                return -EBADMSG;

        /* In both read and write mode we refuse to open files with incompatible
         * flags we don't know. */
        if (warn_wrong_flags(f, false))
                return -EPROTONOSUPPORT;

        /* When open for writing we refuse to open files with compatible flags, too. */
        if (journal_file_writable(f) && warn_wrong_flags(f, true))
                return -EPROTONOSUPPORT;

        if (f->header->state >= _STATE_MAX)
                return -EBADMSG;

        header_size = le64toh(READ_NOW(f->header->header_size));

        /* The first addition was n_data, so check that we are at least this large */
        if (header_size < HEADER_SIZE_MIN)
                return -EBADMSG;

        /* When open for writing we refuse to open files with a mismatch of the header size, i.e. writing to
         * files implementing older or new header structures. */
        if (journal_file_writable(f) && header_size != sizeof(Header))
                return -EPROTONOSUPPORT;

        if (JOURNAL_HEADER_SEALED(f->header) && !JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays))
                return -EBADMSG;

        arena_size = le64toh(READ_NOW(f->header->arena_size));

        if (UINT64_MAX - header_size < arena_size || header_size + arena_size > (uint64_t) f->last_stat.st_size)
                return -ENODATA;

        if (le64toh(f->header->tail_object_offset) > header_size + arena_size)
                return -ENODATA;

        if (!VALID64(le64toh(f->header->data_hash_table_offset)) ||
            !VALID64(le64toh(f->header->field_hash_table_offset)) ||
            !VALID64(le64toh(f->header->tail_object_offset)) ||
            !VALID64(le64toh(f->header->entry_array_offset)))
                return -ENODATA;

        if (journal_file_writable(f)) {
                sd_id128_t machine_id;
                uint8_t state;
                int r;

                r = sd_id128_get_machine(&machine_id);
                if (r < 0)
                        return r;

                if (!sd_id128_equal(machine_id, f->header->machine_id))
                        return log_debug_errno(SYNTHETIC_ERRNO(EHOSTDOWN),
                                               "Trying to open journal file from different host for writing, refusing.");

                state = f->header->state;

                if (state == STATE_ARCHIVED)
                        return -ESHUTDOWN; /* Already archived */
                if (state == STATE_ONLINE)
                        return log_debug_errno(SYNTHETIC_ERRNO(EBUSY),
                                               "Journal file %s is already online. Assuming unclean closing.",
                                               f->path);
                if (state != STATE_OFFLINE)
                        return log_debug_errno(SYNTHETIC_ERRNO(EBUSY),
                                               "Journal file %s has unknown state %i.",
                                               f->path, state);

                if (f->header->field_hash_table_size == 0 || f->header->data_hash_table_size == 0)
                        return -EBADMSG;

                /* Don't permit appending to files from the future. Because otherwise the realtime timestamps wouldn't
                 * be strictly ordered in the entries in the file anymore, and we can't have that since it breaks
                 * bisection. */
                if (le64toh(f->header->tail_entry_realtime) > now(CLOCK_REALTIME))
                        return log_debug_errno(SYNTHETIC_ERRNO(ETXTBSY),
                                               "Journal file %s is from the future, refusing to append new data to it that'd be older.",
                                               f->path);
        }

        return 0;
}

int journal_file_fstat(JournalFile *f) {
        int r;

        assert(f);
        assert(f->fd >= 0);

        if (fstat(f->fd, &f->last_stat) < 0)
                return -errno;

        f->last_stat_usec = now(CLOCK_MONOTONIC);

        /* Refuse dealing with files that aren't regular */
        r = stat_verify_regular(&f->last_stat);
        if (r < 0)
                return r;

        /* Refuse appending to files that are already deleted */
        if (f->last_stat.st_nlink <= 0)
                return -EIDRM;

        return 0;
}

static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size) {
        uint64_t old_size, new_size, old_header_size, old_arena_size;
        int r;

        assert(f);
        assert(f->header);

        /* We assume that this file is not sparse, and we know that for sure, since we always call
         * posix_fallocate() ourselves */

        if (size > PAGE_ALIGN_DOWN(UINT64_MAX) - offset)
                return -EINVAL;

        if (mmap_cache_fd_got_sigbus(f->cache_fd))
                return -EIO;

        old_header_size = le64toh(READ_NOW(f->header->header_size));
        old_arena_size = le64toh(READ_NOW(f->header->arena_size));
        if (old_arena_size > PAGE_ALIGN_DOWN(UINT64_MAX) - old_header_size)
                return -EBADMSG;

        old_size = old_header_size + old_arena_size;

        new_size = MAX(PAGE_ALIGN(offset + size), old_header_size);

        if (new_size <= old_size) {

                /* We already pre-allocated enough space, but before
                 * we write to it, let's check with fstat() if the
                 * file got deleted, in order make sure we don't throw
                 * away the data immediately. Don't check fstat() for
                 * all writes though, but only once ever 10s. */

                if (f->last_stat_usec + LAST_STAT_REFRESH_USEC > now(CLOCK_MONOTONIC))
                        return 0;

                return journal_file_fstat(f);
        }

        /* Allocate more space. */

        if (f->metrics.max_size > 0 && new_size > f->metrics.max_size)
                return -E2BIG;

        /* Refuse to go over 4G in compact mode so offsets can be stored in 32-bit. */
        if (JOURNAL_HEADER_COMPACT(f->header) && new_size > UINT32_MAX)
                return -E2BIG;

        if (new_size > f->metrics.min_size && f->metrics.keep_free > 0) {
                struct statvfs svfs;

                if (fstatvfs(f->fd, &svfs) >= 0) {
                        uint64_t available;

                        available = LESS_BY((uint64_t) svfs.f_bfree * (uint64_t) svfs.f_bsize, f->metrics.keep_free);

                        if (new_size - old_size > available)
                                return -E2BIG;
                }
        }

        /* Increase by larger blocks at once */
        new_size = DIV_ROUND_UP(new_size, FILE_SIZE_INCREASE) * FILE_SIZE_INCREASE;
        if (f->metrics.max_size > 0 && new_size > f->metrics.max_size)
                new_size = f->metrics.max_size;

        /* Note that the glibc fallocate() fallback is very
           inefficient, hence we try to minimize the allocation area
           as we can. */
        r = posix_fallocate_loop(f->fd, old_size, new_size - old_size);
        if (r < 0)
                return r;

        f->header->arena_size = htole64(new_size - old_header_size);

        return journal_file_fstat(f);
}

static unsigned type_to_context(ObjectType type) {
        /* One context for each type, plus one catch-all for the rest */
        assert_cc(_OBJECT_TYPE_MAX <= MMAP_CACHE_MAX_CONTEXTS);
        assert_cc(CONTEXT_HEADER < MMAP_CACHE_MAX_CONTEXTS);
        return type > OBJECT_UNUSED && type < _OBJECT_TYPE_MAX ? type : 0;
}

static int journal_file_move_to(
                JournalFile *f,
                ObjectType type,
                bool keep_always,
                uint64_t offset,
                uint64_t size,
                void **ret) {

        int r;

        assert(f);
        assert(ret);

        /* This function may clear, overwrite, or alter previously cached entries. After this function has
         * been called, all objects except for one obtained by this function are invalidated and must be
         * re-read before use. */

        if (size <= 0)
                return -EINVAL;

        if (size > UINT64_MAX - offset)
                return -EBADMSG;

        /* Avoid SIGBUS on invalid accesses */
        if (offset + size > (uint64_t) f->last_stat.st_size) {
                /* Hmm, out of range? Let's refresh the fstat() data
                 * first, before we trust that check. */

                r = journal_file_fstat(f);
                if (r < 0)
                        return r;

                if (offset + size > (uint64_t) f->last_stat.st_size)
                        return -EADDRNOTAVAIL;
        }

        return mmap_cache_fd_get(f->cache_fd, type_to_context(type), keep_always, offset, size, &f->last_stat, ret);
}

static uint64_t minimum_header_size(JournalFile *f, Object *o) {

        static const uint64_t table[] = {
                [OBJECT_DATA]             = sizeof(DataObject),
                [OBJECT_FIELD]            = sizeof(FieldObject),
                [OBJECT_ENTRY]            = sizeof(EntryObject),
                [OBJECT_DATA_HASH_TABLE]  = sizeof(HashTableObject),
                [OBJECT_FIELD_HASH_TABLE] = sizeof(HashTableObject),
                [OBJECT_ENTRY_ARRAY]      = sizeof(EntryArrayObject),
                [OBJECT_TAG]              = sizeof(TagObject),
        };

        assert(f);
        assert(o);

        if (o->object.type == OBJECT_DATA)
                return journal_file_data_payload_offset(f);

        if (o->object.type >= ELEMENTSOF(table) || table[o->object.type] <= 0)
                return sizeof(ObjectHeader);

        return table[o->object.type];
}

static int check_object_header(JournalFile *f, Object *o, ObjectType type, uint64_t offset) {
        uint64_t s;

        assert(f);
        assert(o);

        s = le64toh(READ_NOW(o->object.size));
        if (s == 0)
                return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                       "Attempt to move to uninitialized object: %" PRIu64,
                                       offset);

        if (s < sizeof(ObjectHeader))
                return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                       "Attempt to move to overly short object: %" PRIu64,
                                       offset);

        if (o->object.type <= OBJECT_UNUSED)
                return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                       "Attempt to move to object with invalid type: %" PRIu64,
                                       offset);

        if (type > OBJECT_UNUSED && o->object.type != type)
                return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                       "Attempt to move to object of unexpected type: %" PRIu64,
                                       offset);

        if (s < minimum_header_size(f, o))
                return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                       "Attempt to move to truncated object: %" PRIu64,
                                       offset);

        return 0;
}

/* Lightweight object checks. We want this to be fast, so that we won't
 * slowdown every journal_file_move_to_object() call too much. */
static int check_object(JournalFile *f, Object *o, uint64_t offset) {
        assert(f);
        assert(o);

        switch (o->object.type) {

        case OBJECT_DATA:
                if ((le64toh(o->data.entry_offset) == 0) ^ (le64toh(o->data.n_entries) == 0))
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                               "Bad n_entries: %" PRIu64 ": %" PRIu64,
                                               le64toh(o->data.n_entries),
                                               offset);

                if (le64toh(o->object.size) <= journal_file_data_payload_offset(f))
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                               "Bad object size (<= %zu): %" PRIu64 ": %" PRIu64,
                                               journal_file_data_payload_offset(f),
                                               le64toh(o->object.size),
                                               offset);

                if (!VALID64(le64toh(o->data.next_hash_offset)) ||
                    !VALID64(le64toh(o->data.next_field_offset)) ||
                    !VALID64(le64toh(o->data.entry_offset)) ||
                    !VALID64(le64toh(o->data.entry_array_offset)))
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                               "Invalid offset, next_hash_offset=" OFSfmt ", next_field_offset=" OFSfmt ", entry_offset=" OFSfmt ", entry_array_offset=" OFSfmt ": %" PRIu64,
                                               le64toh(o->data.next_hash_offset),
                                               le64toh(o->data.next_field_offset),
                                               le64toh(o->data.entry_offset),
                                               le64toh(o->data.entry_array_offset),
                                               offset);

                break;

        case OBJECT_FIELD:
                if (le64toh(o->object.size) <= offsetof(Object, field.payload))
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                               "Bad field size (<= %zu): %" PRIu64 ": %" PRIu64,
                                               offsetof(Object, field.payload),
                                               le64toh(o->object.size),
                                               offset);

                if (!VALID64(le64toh(o->field.next_hash_offset)) ||
                    !VALID64(le64toh(o->field.head_data_offset)))
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                               "Invalid offset, next_hash_offset=" OFSfmt ", head_data_offset=" OFSfmt ": %" PRIu64,
                                               le64toh(o->field.next_hash_offset),
                                               le64toh(o->field.head_data_offset),
                                               offset);
                break;

        case OBJECT_ENTRY: {
                uint64_t sz;

                sz = le64toh(READ_NOW(o->object.size));
                if (sz < offsetof(Object, entry.items) ||
                    (sz - offsetof(Object, entry.items)) % journal_file_entry_item_size(f) != 0)
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                               "Bad entry size (<= %zu): %" PRIu64 ": %" PRIu64,
                                               offsetof(Object, entry.items),
                                               sz,
                                               offset);

                if ((sz - offsetof(Object, entry.items)) / journal_file_entry_item_size(f) <= 0)
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                               "Invalid number items in entry: %" PRIu64 ": %" PRIu64,
                                               (sz - offsetof(Object, entry.items)) / journal_file_entry_item_size(f),
                                               offset);

                if (le64toh(o->entry.seqnum) <= 0)
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                               "Invalid entry seqnum: %" PRIx64 ": %" PRIu64,
                                               le64toh(o->entry.seqnum),
                                               offset);

                if (!VALID_REALTIME(le64toh(o->entry.realtime)))
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                               "Invalid entry realtime timestamp: %" PRIu64 ": %" PRIu64,
                                               le64toh(o->entry.realtime),
                                               offset);

                if (!VALID_MONOTONIC(le64toh(o->entry.monotonic)))
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                               "Invalid entry monotonic timestamp: %" PRIu64 ": %" PRIu64,
                                               le64toh(o->entry.monotonic),
                                               offset);

                break;
        }

        case OBJECT_DATA_HASH_TABLE:
        case OBJECT_FIELD_HASH_TABLE: {
                uint64_t sz;

                sz = le64toh(READ_NOW(o->object.size));
                if (sz < offsetof(Object, hash_table.items) ||
                    (sz - offsetof(Object, hash_table.items)) % sizeof(HashItem) != 0 ||
                    (sz - offsetof(Object, hash_table.items)) / sizeof(HashItem) <= 0)
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                               "Invalid %s hash table size: %" PRIu64 ": %" PRIu64,
                                               o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field",
                                               sz,
                                               offset);

                break;
        }

        case OBJECT_ENTRY_ARRAY: {
                uint64_t sz;

                sz = le64toh(READ_NOW(o->object.size));
                if (sz < offsetof(Object, entry_array.items) ||
                    (sz - offsetof(Object, entry_array.items)) % journal_file_entry_array_item_size(f) != 0 ||
                    (sz - offsetof(Object, entry_array.items)) / journal_file_entry_array_item_size(f) <= 0)
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                               "Invalid object entry array size: %" PRIu64 ": %" PRIu64,
                                               sz,
                                               offset);

                if (!VALID64(le64toh(o->entry_array.next_entry_array_offset)))
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                               "Invalid object entry array next_entry_array_offset: " OFSfmt ": %" PRIu64,
                                               le64toh(o->entry_array.next_entry_array_offset),
                                               offset);

                break;
        }

        case OBJECT_TAG:
                if (le64toh(o->object.size) != sizeof(TagObject))
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                               "Invalid object tag size: %" PRIu64 ": %" PRIu64,
                                               le64toh(o->object.size),
                                               offset);

                if (!VALID_EPOCH(le64toh(o->tag.epoch)))
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                               "Invalid object tag epoch: %" PRIu64 ": %" PRIu64,
                                               le64toh(o->tag.epoch), offset);

                break;
        }

        return 0;
}

int journal_file_move_to_object(JournalFile *f, ObjectType type, uint64_t offset, Object **ret) {
        int r;
        Object *o;

        assert(f);

        /* Even if this function fails, it may clear, overwrite, or alter previously cached entries. After
         * this function has been called, all objects except for one obtained by this function are
         * invalidated and must be re-read before use.. */

        /* Objects may only be located at multiple of 64 bit */
        if (!VALID64(offset))
                return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                       "Attempt to move to object at non-64bit boundary: %" PRIu64,
                                       offset);

        /* Object may not be located in the file header */
        if (offset < le64toh(f->header->header_size))
                return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                       "Attempt to move to object located in file header: %" PRIu64,
                                       offset);

        r = journal_file_move_to(f, type, false, offset, sizeof(ObjectHeader), (void**) &o);
        if (r < 0)
                return r;

        r = check_object_header(f, o, type, offset);
        if (r < 0)
                return r;

        r = journal_file_move_to(f, type, false, offset, le64toh(READ_NOW(o->object.size)), (void**) &o);
        if (r < 0)
                return r;

        r = check_object_header(f, o, type, offset);
        if (r < 0)
                return r;

        r = check_object(f, o, offset);
        if (r < 0)
                return r;

        if (ret)
                *ret = o;

        return 0;
}

int journal_file_read_object_header(JournalFile *f, ObjectType type, uint64_t offset, Object *ret) {
        ssize_t n;
        Object o;
        int r;

        assert(f);

        /* Objects may only be located at multiple of 64 bit */
        if (!VALID64(offset))
                return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                       "Attempt to read object at non-64bit boundary: %" PRIu64,
                                       offset);

        /* Object may not be located in the file header */
        if (offset < le64toh(f->header->header_size))
                return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                       "Attempt to read object located in file header: %" PRIu64,
                                       offset);

        /* This will likely read too much data but it avoids having to call pread() twice. */
        n = pread(f->fd, &o, sizeof(o), offset);
        if (n < 0)
                return log_debug_errno(errno, "Failed to read journal file at offset: %" PRIu64,
                                       offset);

        if ((size_t) n < sizeof(o.object))
                return log_debug_errno(SYNTHETIC_ERRNO(EIO),
                                       "Failed to read short object at offset: %" PRIu64,
                                       offset);

        r = check_object_header(f, &o, type, offset);
        if (r < 0)
                return r;

        if ((size_t) n < minimum_header_size(f, &o))
                return log_debug_errno(SYNTHETIC_ERRNO(EIO),
                                       "Short read while reading object: %" PRIu64,
                                       offset);

        r = check_object(f, &o, offset);
        if (r < 0)
                return r;

        if (ret)
                *ret = o;

        return 0;
}

static uint64_t inc_seqnum(uint64_t seqnum) {
        if (seqnum < UINT64_MAX-1)
                return seqnum + 1;

        return 1; /* skip over UINT64_MAX and 0 when we run out of seqnums and start again */
}

static uint64_t journal_file_entry_seqnum(
                JournalFile *f,
                uint64_t *seqnum) {

        uint64_t next_seqnum;

        assert(f);
        assert(f->header);

        /* Picks a new sequence number for the entry we are about to add and returns it. */

        next_seqnum = inc_seqnum(le64toh(f->header->tail_entry_seqnum));

        /* If an external seqnum counter was passed, we update both the local and the external one, and set
         * it to the maximum of both */
        if (seqnum)
                *seqnum = next_seqnum = MAX(inc_seqnum(*seqnum), next_seqnum);

        f->header->tail_entry_seqnum = htole64(next_seqnum);

        if (f->header->head_entry_seqnum == 0)
                f->header->head_entry_seqnum = htole64(next_seqnum);

        return next_seqnum;
}

int journal_file_append_object(
                JournalFile *f,
                ObjectType type,
                uint64_t size,
                Object **ret_object,
                uint64_t *ret_offset) {

        int r;
        uint64_t p;
        Object *o;

        assert(f);
        assert(f->header);
        assert(type > OBJECT_UNUSED && type < _OBJECT_TYPE_MAX);
        assert(size >= sizeof(ObjectHeader));

        r = journal_file_set_online(f);
        if (r < 0)
                return r;

        r = journal_file_tail_end_by_mmap(f, &p);
        if (r < 0)
                return r;

        r = journal_file_allocate(f, p, size);
        if (r < 0)
                return r;

        r = journal_file_move_to(f, type, false, p, size, (void**) &o);
        if (r < 0)
                return r;

        o->object = (ObjectHeader) {
                .type = type,
                .size = htole64(size),
        };

        f->header->tail_object_offset = htole64(p);
        f->header->n_objects = htole64(le64toh(f->header->n_objects) + 1);

        if (ret_object)
                *ret_object = o;

        if (ret_offset)
                *ret_offset = p;

        return 0;
}

static int journal_file_setup_data_hash_table(JournalFile *f) {
        uint64_t s, p;
        Object *o;
        int r;

        assert(f);
        assert(f->header);

        /* We estimate that we need 1 hash table entry per 768 bytes
           of journal file and we want to make sure we never get
           beyond 75% fill level. Calculate the hash table size for
           the maximum file size based on these metrics. */

        s = (f->metrics.max_size * 4 / 768 / 3) * sizeof(HashItem);
        if (s < DEFAULT_DATA_HASH_TABLE_SIZE)
                s = DEFAULT_DATA_HASH_TABLE_SIZE;

        log_debug("Reserving %"PRIu64" entries in data hash table.", s / sizeof(HashItem));

        r = journal_file_append_object(f,
                                       OBJECT_DATA_HASH_TABLE,
                                       offsetof(Object, hash_table.items) + s,
                                       &o, &p);
        if (r < 0)
                return r;

        memzero(o->hash_table.items, s);

        f->header->data_hash_table_offset = htole64(p + offsetof(Object, hash_table.items));
        f->header->data_hash_table_size = htole64(s);

        return 0;
}

static int journal_file_setup_field_hash_table(JournalFile *f) {
        uint64_t s, p;
        Object *o;
        int r;

        assert(f);
        assert(f->header);

        /* We use a fixed size hash table for the fields as this
         * number should grow very slowly only */

        s = DEFAULT_FIELD_HASH_TABLE_SIZE;
        log_debug("Reserving %"PRIu64" entries in field hash table.", s / sizeof(HashItem));

        r = journal_file_append_object(f,
                                       OBJECT_FIELD_HASH_TABLE,
                                       offsetof(Object, hash_table.items) + s,
                                       &o, &p);
        if (r < 0)
                return r;

        memzero(o->hash_table.items, s);

        f->header->field_hash_table_offset = htole64(p + offsetof(Object, hash_table.items));
        f->header->field_hash_table_size = htole64(s);

        return 0;
}

int journal_file_map_data_hash_table(JournalFile *f) {
        uint64_t s, p;
        void *t;
        int r;

        assert(f);
        assert(f->header);

        if (f->data_hash_table)
                return 0;

        p = le64toh(f->header->data_hash_table_offset);
        s = le64toh(f->header->data_hash_table_size);

        r = journal_file_move_to(f,
                                 OBJECT_DATA_HASH_TABLE,
                                 true,
                                 p, s,
                                 &t);
        if (r < 0)
                return r;

        f->data_hash_table = t;
        return 0;
}

int journal_file_map_field_hash_table(JournalFile *f) {
        uint64_t s, p;
        void *t;
        int r;

        assert(f);
        assert(f->header);

        if (f->field_hash_table)
                return 0;

        p = le64toh(f->header->field_hash_table_offset);
        s = le64toh(f->header->field_hash_table_size);

        r = journal_file_move_to(f,
                                 OBJECT_FIELD_HASH_TABLE,
                                 true,
                                 p, s,
                                 &t);
        if (r < 0)
                return r;

        f->field_hash_table = t;
        return 0;
}

static int journal_file_link_field(
                JournalFile *f,
                Object *o,
                uint64_t offset,
                uint64_t hash) {

        uint64_t p, h, m;
        int r;

        assert(f);
        assert(f->header);
        assert(f->field_hash_table);
        assert(o);
        assert(offset > 0);

        if (o->object.type != OBJECT_FIELD)
                return -EINVAL;

        m = le64toh(READ_NOW(f->header->field_hash_table_size)) / sizeof(HashItem);
        if (m <= 0)
                return -EBADMSG;

        /* This might alter the window we are looking at */
        o->field.next_hash_offset = o->field.head_data_offset = 0;

        h = hash % m;
        p = le64toh(f->field_hash_table[h].tail_hash_offset);
        if (p == 0)
                f->field_hash_table[h].head_hash_offset = htole64(offset);
        else {
                r = journal_file_move_to_object(f, OBJECT_FIELD, p, &o);
                if (r < 0)
                        return r;

                o->field.next_hash_offset = htole64(offset);
        }

        f->field_hash_table[h].tail_hash_offset = htole64(offset);

        if (JOURNAL_HEADER_CONTAINS(f->header, n_fields))
                f->header->n_fields = htole64(le64toh(f->header->n_fields) + 1);

        return 0;
}

static int journal_file_link_data(
                JournalFile *f,
                Object *o,
                uint64_t offset,
                uint64_t hash) {

        uint64_t p, h, m;
        int r;

        assert(f);
        assert(f->header);
        assert(f->data_hash_table);
        assert(o);
        assert(offset > 0);

        if (o->object.type != OBJECT_DATA)
                return -EINVAL;

        m = le64toh(READ_NOW(f->header->data_hash_table_size)) / sizeof(HashItem);
        if (m <= 0)
                return -EBADMSG;

        /* This might alter the window we are looking at */
        o->data.next_hash_offset = o->data.next_field_offset = 0;
        o->data.entry_offset = o->data.entry_array_offset = 0;
        o->data.n_entries = 0;

        h = hash % m;
        p = le64toh(f->data_hash_table[h].tail_hash_offset);
        if (p == 0)
                /* Only entry in the hash table is easy */
                f->data_hash_table[h].head_hash_offset = htole64(offset);
        else {
                /* Move back to the previous data object, to patch in
                 * pointer */

                r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
                if (r < 0)
                        return r;

                o->data.next_hash_offset = htole64(offset);
        }

        f->data_hash_table[h].tail_hash_offset = htole64(offset);

        if (JOURNAL_HEADER_CONTAINS(f->header, n_data))
                f->header->n_data = htole64(le64toh(f->header->n_data) + 1);

        return 0;
}

static int get_next_hash_offset(
                JournalFile *f,
                uint64_t *p,
                le64_t *next_hash_offset,
                uint64_t *depth,
                le64_t *header_max_depth) {

        uint64_t nextp;

        assert(f);
        assert(p);
        assert(next_hash_offset);
        assert(depth);

        nextp = le64toh(READ_NOW(*next_hash_offset));
        if (nextp > 0) {
                if (nextp <= *p) /* Refuse going in loops */
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                               "Detected hash item loop in %s, refusing.", f->path);

                (*depth)++;

                /* If the depth of this hash chain is larger than all others we have seen so far, record it */
                if (header_max_depth && journal_file_writable(f))
                        *header_max_depth = htole64(MAX(*depth, le64toh(*header_max_depth)));
        }

        *p = nextp;
        return 0;
}

int journal_file_find_field_object_with_hash(
                JournalFile *f,
                const void *field,
                uint64_t size,
                uint64_t hash,
                Object **ret_object,
                uint64_t *ret_offset) {

        uint64_t p, osize, h, m, depth = 0;
        int r;

        assert(f);
        assert(f->header);
        assert(field);
        assert(size > 0);

        /* If the field hash table is empty, we can't find anything */
        if (le64toh(f->header->field_hash_table_size) <= 0)
                return 0;

        /* Map the field hash table, if it isn't mapped yet. */
        r = journal_file_map_field_hash_table(f);
        if (r < 0)
                return r;

        osize = offsetof(Object, field.payload) + size;

        m = le64toh(READ_NOW(f->header->field_hash_table_size)) / sizeof(HashItem);
        if (m <= 0)
                return -EBADMSG;

        h = hash % m;
        p = le64toh(f->field_hash_table[h].head_hash_offset);
        while (p > 0) {
                Object *o;

                r = journal_file_move_to_object(f, OBJECT_FIELD, p, &o);
                if (r < 0)
                        return r;

                if (le64toh(o->field.hash) == hash &&
                    le64toh(o->object.size) == osize &&
                    memcmp(o->field.payload, field, size) == 0) {

                        if (ret_object)
                                *ret_object = o;
                        if (ret_offset)
                                *ret_offset = p;

                        return 1;
                }

                r = get_next_hash_offset(
                                f,
                                &p,
                                &o->field.next_hash_offset,
                                &depth,
                                JOURNAL_HEADER_CONTAINS(f->header, field_hash_chain_depth) ? &f->header->field_hash_chain_depth : NULL);
                if (r < 0)
                        return r;
        }

        return 0;
}

uint64_t journal_file_hash_data(
                JournalFile *f,
                const void *data,
                size_t sz) {

        assert(f);
        assert(f->header);
        assert(data || sz == 0);

        /* We try to unify our codebase on siphash, hence new-styled journal files utilizing the keyed hash
         * function use siphash. Old journal files use the Jenkins hash. */

        if (JOURNAL_HEADER_KEYED_HASH(f->header))
                return siphash24(data, sz, f->header->file_id.bytes);

        return jenkins_hash64(data, sz);
}

int journal_file_find_field_object(
                JournalFile *f,
                const void *field,
                uint64_t size,
                Object **ret_object,
                uint64_t *ret_offset) {

        assert(f);
        assert(field);
        assert(size > 0);

        return journal_file_find_field_object_with_hash(
                        f,
                        field, size,
                        journal_file_hash_data(f, field, size),
                        ret_object, ret_offset);
}

int journal_file_find_data_object_with_hash(
                JournalFile *f,
                const void *data,
                uint64_t size,
                uint64_t hash,
                Object **ret_object,
                uint64_t *ret_offset) {

        uint64_t p, h, m, depth = 0;
        int r;

        assert(f);
        assert(f->header);
        assert(data || size == 0);

        /* If there's no data hash table, then there's no entry. */
        if (le64toh(f->header->data_hash_table_size) <= 0)
                return 0;

        /* Map the data hash table, if it isn't mapped yet. */
        r = journal_file_map_data_hash_table(f);
        if (r < 0)
                return r;

        m = le64toh(READ_NOW(f->header->data_hash_table_size)) / sizeof(HashItem);
        if (m <= 0)
                return -EBADMSG;

        h = hash % m;
        p = le64toh(f->data_hash_table[h].head_hash_offset);

        while (p > 0) {
                Object *o;
                void *d;
                size_t rsize;

                r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
                if (r < 0)
                        return r;

                if (le64toh(o->data.hash) != hash)
                        goto next;

                r = journal_file_data_payload(f, o, p, NULL, 0, 0, &d, &rsize);
                if (r < 0)
                        return r;
                assert(r > 0); /* journal_file_data_payload() always returns > 0 if no field is provided. */

                if (memcmp_nn(data, size, d, rsize) == 0) {
                         if (ret_object)
                                *ret_object = o;

                        if (ret_offset)
                                *ret_offset = p;

                        return 1;
                }

        next:
                r = get_next_hash_offset(
                                f,
                                &p,
                                &o->data.next_hash_offset,
                                &depth,
                                JOURNAL_HEADER_CONTAINS(f->header, data_hash_chain_depth) ? &f->header->data_hash_chain_depth : NULL);
                if (r < 0)
                        return r;
        }

        return 0;
}

int journal_file_find_data_object(
                JournalFile *f,
                const void *data,
                uint64_t size,
                Object **ret_object,
                uint64_t *ret_offset) {

        assert(f);
        assert(data || size == 0);

        return journal_file_find_data_object_with_hash(
                        f,
                        data, size,
                        journal_file_hash_data(f, data, size),
                        ret_object, ret_offset);
}

bool journal_field_valid(const char *p, size_t l, bool allow_protected) {
        /* We kinda enforce POSIX syntax recommendations for
           environment variables here, but make a couple of additional
           requirements.

           http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html */

        assert(p);

        if (l == SIZE_MAX)
                l = strlen(p);

        /* No empty field names */
        if (l <= 0)
                return false;

        /* Don't allow names longer than 64 chars */
        if (l > 64)
                return false;

        /* Variables starting with an underscore are protected */
        if (!allow_protected && p[0] == '_')
                return false;

        /* Don't allow digits as first character */
        if (ascii_isdigit(p[0]))
                return false;

        /* Only allow A-Z0-9 and '_' */
        for (const char *a = p; a < p + l; a++)
                if ((*a < 'A' || *a > 'Z') &&
                    !ascii_isdigit(*a) &&
                    *a != '_')
                        return false;

        return true;
}

static int journal_file_append_field(
                JournalFile *f,
                const void *field,
                uint64_t size,
                Object **ret_object,
                uint64_t *ret_offset) {

        uint64_t hash, p;
        uint64_t osize;
        Object *o;
        int r;

        assert(f);
        assert(field);
        assert(size > 0);

        if (!journal_field_valid(field, size, true))
                return -EBADMSG;

        hash = journal_file_hash_data(f, field, size);

        r = journal_file_find_field_object_with_hash(f, field, size, hash, ret_object, ret_offset);
        if (r < 0)
                return r;
        if (r > 0)
                return 0;

        osize = offsetof(Object, field.payload) + size;
        r = journal_file_append_object(f, OBJECT_FIELD, osize, &o, &p);
        if (r < 0)
                return r;

        o->field.hash = htole64(hash);
        memcpy(o->field.payload, field, size);

        r = journal_file_link_field(f, o, p, hash);
        if (r < 0)
                return r;

        /* The linking might have altered the window, so let's only pass the offset to hmac which will
         * move to the object again if needed. */

#if HAVE_GCRYPT
        r = journal_file_hmac_put_object(f, OBJECT_FIELD, NULL, p);
        if (r < 0)
                return r;
#endif

        if (ret_object) {
                r = journal_file_move_to_object(f, OBJECT_FIELD, p, ret_object);
                if (r < 0)
                        return r;
        }

        if (ret_offset)
                *ret_offset = p;

        return 0;
}

static Compression maybe_compress_payload(JournalFile *f, uint8_t *dst, const uint8_t *src, uint64_t size, size_t *rsize) {
        Compression compression = COMPRESSION_NONE;

        assert(f);
        assert(f->header);

#if HAVE_COMPRESSION
        if (JOURNAL_FILE_COMPRESS(f) && size >= f->compress_threshold_bytes) {
                compression = compress_blob(src, size, dst, size - 1, rsize);
                if (compression > 0)
                        log_debug("Compressed data object %"PRIu64" -> %zu using %s",
                                  size, *rsize, compression_to_string(compression));
                else
                        /* Compression didn't work, we don't really care why, let's continue without compression */
                        compression = COMPRESSION_NONE;
        }
#endif

        return compression;
}

static int journal_file_append_data(
                JournalFile *f,
                const void *data,
                uint64_t size,
                Object **ret_object,
                uint64_t *ret_offset) {

        uint64_t hash, p, osize;
        Object *o, *fo;
        size_t rsize = 0;
        Compression c;
        const void *eq;
        int r;

        assert(f);

        if (!data || size == 0)
                return -EINVAL;

        hash = journal_file_hash_data(f, data, size);

        r = journal_file_find_data_object_with_hash(f, data, size, hash, ret_object, ret_offset);
        if (r < 0)
                return r;
        if (r > 0)
                return 0;

        eq = memchr(data, '=', size);
        if (!eq)
                return -EINVAL;

        osize = journal_file_data_payload_offset(f) + size;
        r = journal_file_append_object(f, OBJECT_DATA, osize, &o, &p);
        if (r < 0)
                return r;

        o->data.hash = htole64(hash);

        c = maybe_compress_payload(f, journal_file_data_payload_field(f, o), data, size, &rsize);

        if (c != COMPRESSION_NONE) {
                o->object.size = htole64(journal_file_data_payload_offset(f) + rsize);
                o->object.flags |= COMPRESSION_TO_OBJECT_FLAG(c);
        } else
                memcpy_safe(journal_file_data_payload_field(f, o), data, size);

        r = journal_file_link_data(f, o, p, hash);
        if (r < 0)
                return r;

        /* The linking might have altered the window, so let's refresh our pointer. */
        r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
        if (r < 0)
                return r;

#if HAVE_GCRYPT
        r = journal_file_hmac_put_object(f, OBJECT_DATA, o, p);
        if (r < 0)
                return r;
#endif

        /* Create field object ... */
        r = journal_file_append_field(f, data, (uint8_t*) eq - (uint8_t*) data, &fo, NULL);
        if (r < 0)
                return r;

        /* ... and link it in. */
        o->data.next_field_offset = fo->field.head_data_offset;
        fo->field.head_data_offset = le64toh(p);

        if (ret_object)
                *ret_object = o;

        if (ret_offset)
                *ret_offset = p;

        return 0;
}

static int maybe_decompress_payload(
                JournalFile *f,
                uint8_t *payload,
                uint64_t size,
                Compression compression,
                const char *field,
                size_t field_length,
                size_t data_threshold,
                void **ret_data,
                size_t *ret_size) {

        assert(f);

        /* We can't read objects larger than 4G on a 32bit machine */
        if ((uint64_t) (size_t) size != size)
                return -E2BIG;

        if (compression != COMPRESSION_NONE) {
#if HAVE_COMPRESSION
                size_t rsize;
                int r;

                if (field) {
                        r = decompress_startswith(compression, payload, size, &f->compress_buffer, field,
                                                  field_length, '=');
                        if (r < 0)
                                return log_debug_errno(r,
                                                       "Cannot decompress %s object of length %" PRIu64 ": %m",
                                                       compression_to_string(compression),
                                                       size);
                        if (r == 0) {
                                if (ret_data)
                                        *ret_data = NULL;
                                if (ret_size)
                                        *ret_size = 0;
                                return 0;
                        }
                }

                r = decompress_blob(compression, payload, size, &f->compress_buffer, &rsize, 0);
                if (r < 0)
                        return r;

                if (ret_data)
                        *ret_data = f->compress_buffer;
                if (ret_size)
                        *ret_size = rsize;
#else
                return -EPROTONOSUPPORT;
#endif
        } else {
                if (field && (size < field_length + 1 || memcmp(payload, field, field_length) != 0 || payload[field_length] != '=')) {
                        if (ret_data)
                                *ret_data = NULL;
                        if (ret_size)
                                *ret_size = 0;
                        return 0;
                }

                if (ret_data)
                        *ret_data = payload;
                if (ret_size)
                        *ret_size = (size_t) size;
        }

        return 1;
}

int journal_file_data_payload(
                JournalFile *f,
                Object *o,
                uint64_t offset,
                const char *field,
                size_t field_length,
                size_t data_threshold,
                void **ret_data,
                size_t *ret_size) {

        uint64_t size;
        Compression c;
        int r;

        assert(f);
        assert(!field == (field_length == 0)); /* These must be specified together. */

        if (!o) {
                r = journal_file_move_to_object(f, OBJECT_DATA, offset, &o);
                if (r < 0)
                        return r;
        }

        size = le64toh(READ_NOW(o->object.size));
        if (size < journal_file_data_payload_offset(f))
                return -EBADMSG;

        size -= journal_file_data_payload_offset(f);

        c = COMPRESSION_FROM_OBJECT(o);
        if (c < 0)
                return -EPROTONOSUPPORT;

        return maybe_decompress_payload(f, journal_file_data_payload_field(f, o), size, c, field,
                                        field_length, data_threshold, ret_data, ret_size);
}

uint64_t journal_file_entry_n_items(JournalFile *f, Object *o) {
        uint64_t sz;

        assert(f);
        assert(o);

        if (o->object.type != OBJECT_ENTRY)
                return 0;

        sz = le64toh(READ_NOW(o->object.size));
        if (sz < offsetof(Object, entry.items))
                return 0;

        return (sz - offsetof(Object, entry.items)) / journal_file_entry_item_size(f);
}

uint64_t journal_file_entry_array_n_items(JournalFile *f, Object *o) {
        uint64_t sz;

        assert(f);
        assert(o);

        if (o->object.type != OBJECT_ENTRY_ARRAY)
                return 0;

        sz = le64toh(READ_NOW(o->object.size));
        if (sz < offsetof(Object, entry_array.items))
                return 0;

        return (sz - offsetof(Object, entry_array.items)) / journal_file_entry_array_item_size(f);
}

uint64_t journal_file_hash_table_n_items(Object *o) {
        uint64_t sz;

        assert(o);

        if (!IN_SET(o->object.type, OBJECT_DATA_HASH_TABLE, OBJECT_FIELD_HASH_TABLE))
                return 0;

        sz = le64toh(READ_NOW(o->object.size));
        if (sz < offsetof(Object, hash_table.items))
                return 0;

        return (sz - offsetof(Object, hash_table.items)) / sizeof(HashItem);
}

static void write_entry_array_item(JournalFile *f, Object *o, uint64_t i, uint64_t p) {
        assert(f);
        assert(o);

        if (JOURNAL_HEADER_COMPACT(f->header)) {
                assert(p <= UINT32_MAX);
                o->entry_array.items.compact[i] = htole32(p);
        } else
                o->entry_array.items.regular[i] = htole64(p);
}

static int link_entry_into_array(
                JournalFile *f,
                le64_t *first,
                le64_t *idx,
                le32_t *tail,
                le32_t *tidx,
                uint64_t p) {

        uint64_t n = 0, ap = 0, q, i, a, hidx;
        Object *o;
        int r;

        assert(f);
        assert(f->header);
        assert(first);
        assert(idx);
        assert(p > 0);

        a = tail ? le32toh(*tail) : le64toh(*first);
        hidx = le64toh(READ_NOW(*idx));
        i = tidx ? le32toh(READ_NOW(*tidx)) : hidx;

        while (a > 0) {
                r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
                if (r < 0)
                        return r;

                n = journal_file_entry_array_n_items(f, o);
                if (i < n) {
                        write_entry_array_item(f, o, i, p);
                        *idx = htole64(hidx + 1);
                        if (tidx)
                                *tidx = htole32(le32toh(*tidx) + 1);
                        return 0;
                }

                i -= n;
                ap = a;
                a = le64toh(o->entry_array.next_entry_array_offset);
        }

        if (hidx > n)
                n = (hidx+1) * 2;
        else
                n = n * 2;

        if (n < 4)
                n = 4;

        r = journal_file_append_object(f, OBJECT_ENTRY_ARRAY,
                                       offsetof(Object, entry_array.items) + n * journal_file_entry_array_item_size(f),
                                       &o, &q);
        if (r < 0)
                return r;

#if HAVE_GCRYPT
        r = journal_file_hmac_put_object(f, OBJECT_ENTRY_ARRAY, o, q);
        if (r < 0)
                return r;
#endif

        write_entry_array_item(f, o, i, p);

        if (ap == 0)
                *first = htole64(q);
        else {
                r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, ap, &o);
                if (r < 0)
                        return r;

                o->entry_array.next_entry_array_offset = htole64(q);
        }

        if (tail)
                *tail = htole32(q);

        if (JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays))
                f->header->n_entry_arrays = htole64(le64toh(f->header->n_entry_arrays) + 1);

        *idx = htole64(hidx + 1);
        if (tidx)
                *tidx = htole32(1);

        return 0;
}

static int link_entry_into_array_plus_one(
                JournalFile *f,
                le64_t *extra,
                le64_t *first,
                le64_t *idx,
                le32_t *tail,
                le32_t *tidx,
                uint64_t p) {

        uint64_t hidx;
        int r;

        assert(f);
        assert(extra);
        assert(first);
        assert(idx);
        assert(p > 0);

        hidx = le64toh(READ_NOW(*idx));
        if (hidx == UINT64_MAX)
                return -EBADMSG;
        if (hidx == 0)
                *extra = htole64(p);
        else {
                le64_t i;

                i = htole64(hidx - 1);
                r = link_entry_into_array(f, first, &i, tail, tidx, p);
                if (r < 0)
                        return r;
        }

        *idx = htole64(hidx + 1);
        return 0;
}

static int journal_file_link_entry_item(JournalFile *f, uint64_t offset, uint64_t p) {
        Object *o;
        int r;

        assert(f);
        assert(offset > 0);

        r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
        if (r < 0)
                return r;

        return link_entry_into_array_plus_one(f,
                                              &o->data.entry_offset,
                                              &o->data.entry_array_offset,
                                              &o->data.n_entries,
                                              JOURNAL_HEADER_COMPACT(f->header) ? &o->data.compact.tail_entry_array_offset : NULL,
                                              JOURNAL_HEADER_COMPACT(f->header) ? &o->data.compact.tail_entry_array_n_entries : NULL,
                                              offset);
}

static int journal_file_link_entry(
                JournalFile *f,
                Object *o,
                uint64_t offset,
                const EntryItem items[],
                size_t n_items) {

        int r;

        assert(f);
        assert(f->header);
        assert(o);
        assert(offset > 0);

        if (o->object.type != OBJECT_ENTRY)
                return -EINVAL;

        __atomic_thread_fence(__ATOMIC_SEQ_CST);

        /* Link up the entry itself */
        r = link_entry_into_array(f,
                                  &f->header->entry_array_offset,
                                  &f->header->n_entries,
                                  JOURNAL_HEADER_CONTAINS(f->header, tail_entry_array_offset) ? &f->header->tail_entry_array_offset : NULL,
                                  JOURNAL_HEADER_CONTAINS(f->header, tail_entry_array_n_entries) ? &f->header->tail_entry_array_n_entries : NULL,
                                  offset);
        if (r < 0)
                return r;

        /* log_debug("=> %s seqnr=%"PRIu64" n_entries=%"PRIu64, f->path, o->entry.seqnum, f->header->n_entries); */

        if (f->header->head_entry_realtime == 0)
                f->header->head_entry_realtime = o->entry.realtime;

        f->header->tail_entry_realtime = o->entry.realtime;
        f->header->tail_entry_monotonic = o->entry.monotonic;

        /* Link up the items */
        for (uint64_t i = 0; i < n_items; i++) {
                int k;

                /* If we fail to link an entry item because we can't allocate a new entry array, don't fail
                 * immediately but try to link the other entry items since it might still be possible to link
                 * those if they don't require a new entry array to be allocated. */

                k = journal_file_link_entry_item(f, offset, items[i].object_offset);
                if (k == -E2BIG)
                        r = k;
                else if (k < 0)
                        return k;
        }

        return r;
}

static void write_entry_item(JournalFile *f, Object *o, uint64_t i, const EntryItem *item) {
        assert(f);
        assert(o);
        assert(item);

        if (JOURNAL_HEADER_COMPACT(f->header)) {
                assert(item->object_offset <= UINT32_MAX);
                o->entry.items.compact[i].object_offset = htole32(item->object_offset);
        } else {
                o->entry.items.regular[i].object_offset = htole64(item->object_offset);
                o->entry.items.regular[i].hash = htole64(item->hash);
        }
}

static int journal_file_append_entry_internal(
                JournalFile *f,
                const dual_timestamp *ts,
                const sd_id128_t *boot_id,
                uint64_t xor_hash,
                const EntryItem items[],
                size_t n_items,
                uint64_t *seqnum,
                Object **ret_object,
                uint64_t *ret_offset) {

        uint64_t np;
        uint64_t osize;
        Object *o;
        int r;

        assert(f);
        assert(f->header);
        assert(ts);
        assert(items || n_items == 0);

        if (f->strict_order) {
                /* If requested be stricter with ordering in this journal file, to make searching via
                 * bisection fully deterministic. This is an optional feature, so that if desired journal
                 * files can be written where the ordering is not strictly enforced (in which case bisection
                 * will yield *a* result, but not the *only* result, when searching for points in
                 * time). Strict ordering mode is enabled when journald originally writes the files, but
                 * might not necessarily be if other tools (the remoting tools for example) write journal
                 * files from combined sources.
                 *
                 * Typically, if any of the errors generated here are seen journald will just rotate the
                 * journal files and start anew. */

                if (ts->realtime < le64toh(f->header->tail_entry_realtime))
                        return log_debug_errno(SYNTHETIC_ERRNO(EREMCHG),
                                               "Realtime timestamp %" PRIu64 " smaller than previous realtime "
                                               "timestamp %" PRIu64 ", refusing entry.",
                                               ts->realtime, le64toh(f->header->tail_entry_realtime));

                if (!sd_id128_is_null(f->header->boot_id) && boot_id) {

                        if (!sd_id128_equal(f->header->boot_id, *boot_id))
                                return log_debug_errno(SYNTHETIC_ERRNO(EREMOTE),
                                                       "Boot ID to write is different from previous boot id, refusing entry.");

                        if (ts->monotonic < le64toh(f->header->tail_entry_monotonic))
                                return log_debug_errno(SYNTHETIC_ERRNO(ENOTNAM),
                                                       "Monotonic timestamp %" PRIu64 " smaller than previous monotonic "
                                                       "timestamp %" PRIu64 ", refusing entry.",
                                                       ts->monotonic, le64toh(f->header->tail_entry_monotonic));
                }
        }

        osize = offsetof(Object, entry.items) + (n_items * journal_file_entry_item_size(f));

        r = journal_file_append_object(f, OBJECT_ENTRY, osize, &o, &np);
        if (r < 0)
                return r;

        o->entry.seqnum = htole64(journal_file_entry_seqnum(f, seqnum));
        o->entry.realtime = htole64(ts->realtime);
        o->entry.monotonic = htole64(ts->monotonic);
        o->entry.xor_hash = htole64(xor_hash);
        if (boot_id)
                f->header->boot_id = *boot_id;
        o->entry.boot_id = f->header->boot_id;

        for (size_t i = 0; i < n_items; i++)
                write_entry_item(f, o, i, &items[i]);

#if HAVE_GCRYPT
        r = journal_file_hmac_put_object(f, OBJECT_ENTRY, o, np);
        if (r < 0)
                return r;
#endif

        r = journal_file_link_entry(f, o, np, items, n_items);
        if (r < 0)
                return r;

        if (ret_object)
                *ret_object = o;

        if (ret_offset)
                *ret_offset = np;

        return r;
}

void journal_file_post_change(JournalFile *f) {
        assert(f);

        if (f->fd < 0)
                return;

        /* inotify() does not receive IN_MODIFY events from file
         * accesses done via mmap(). After each access we hence
         * trigger IN_MODIFY by truncating the journal file to its
         * current size which triggers IN_MODIFY. */

        __atomic_thread_fence(__ATOMIC_SEQ_CST);

        if (ftruncate(f->fd, f->last_stat.st_size) < 0)
                log_debug_errno(errno, "Failed to truncate file to its own size: %m");
}

static int post_change_thunk(sd_event_source *timer, uint64_t usec, void *userdata) {
        assert(userdata);

        journal_file_post_change(userdata);

        return 1;
}

static void schedule_post_change(JournalFile *f) {
        sd_event *e;
        int r;

        assert(f);
        assert(f->post_change_timer);

        assert_se(e = sd_event_source_get_event(f->post_change_timer));

        /* If we are already going down, post the change immediately. */
        if (IN_SET(sd_event_get_state(e), SD_EVENT_EXITING, SD_EVENT_FINISHED))
                goto fail;

        r = sd_event_source_get_enabled(f->post_change_timer, NULL);
        if (r < 0) {
                log_debug_errno(r, "Failed to get ftruncate timer state: %m");
                goto fail;
        }
        if (r > 0)
                return;

        r = sd_event_source_set_time_relative(f->post_change_timer, f->post_change_timer_period);
        if (r < 0) {
                log_debug_errno(r, "Failed to set time for scheduling ftruncate: %m");
                goto fail;
        }

        r = sd_event_source_set_enabled(f->post_change_timer, SD_EVENT_ONESHOT);
        if (r < 0) {
                log_debug_errno(r, "Failed to enable scheduled ftruncate: %m");
                goto fail;
        }

        return;

fail:
        /* On failure, let's simply post the change immediately. */
        journal_file_post_change(f);
}

/* Enable coalesced change posting in a timer on the provided sd_event instance */
int journal_file_enable_post_change_timer(JournalFile *f, sd_event *e, usec_t t) {
        _cleanup_(sd_event_source_unrefp) sd_event_source *timer = NULL;
        int r;

        assert(f);
        assert_return(!f->post_change_timer, -EINVAL);
        assert(e);
        assert(t);

        r = sd_event_add_time(e, &timer, CLOCK_MONOTONIC, 0, 0, post_change_thunk, f);
        if (r < 0)
                return r;

        r = sd_event_source_set_enabled(timer, SD_EVENT_OFF);
        if (r < 0)
                return r;

        f->post_change_timer = TAKE_PTR(timer);
        f->post_change_timer_period = t;

        return r;
}

static int entry_item_cmp(const EntryItem *a, const EntryItem *b) {
        return CMP(ASSERT_PTR(a)->object_offset, ASSERT_PTR(b)->object_offset);
}

static size_t remove_duplicate_entry_items(EntryItem items[], size_t n) {
        size_t j = 1;

        assert(items || n == 0);

        if (n <= 1)
                return n;

        for (size_t i = 1; i < n; i++)
                if (items[i].object_offset != items[j - 1].object_offset)
                        items[j++] = items[i];

        return j;
}

int journal_file_append_entry(
                JournalFile *f,
                const dual_timestamp *ts,
                const sd_id128_t *boot_id,
                const struct iovec iovec[],
                size_t n_iovec,
                uint64_t *seqnum,
                Object **ret_object,
                uint64_t *ret_offset) {

        _cleanup_free_ EntryItem *items_alloc = NULL;
        EntryItem *items;
        uint64_t xor_hash = 0;
        struct dual_timestamp _ts;
        sd_id128_t _boot_id;
        int r;

        assert(f);
        assert(f->header);
        assert(iovec);
        assert(n_iovec > 0);

        if (ts) {
                if (!VALID_REALTIME(ts->realtime))
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                               "Invalid realtime timestamp %" PRIu64 ", refusing entry.",
                                               ts->realtime);
                if (!VALID_MONOTONIC(ts->monotonic))
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                               "Invalid monotomic timestamp %" PRIu64 ", refusing entry.",
                                               ts->monotonic);
        } else {
                dual_timestamp_get(&_ts);
                ts = &_ts;
        }

        if (!boot_id) {
                r = sd_id128_get_boot(&_boot_id);
                if (r < 0)
                        return r;

                boot_id = &_boot_id;
        }

#if HAVE_GCRYPT
        r = journal_file_maybe_append_tag(f, ts->realtime);
        if (r < 0)
                return r;
#endif

        if (n_iovec < ALLOCA_MAX / sizeof(EntryItem) / 2)
                items = newa(EntryItem, n_iovec);
        else {
                items_alloc = new(EntryItem, n_iovec);
                if (!items_alloc)
                        return -ENOMEM;

                items = items_alloc;
        }

        for (size_t i = 0; i < n_iovec; i++) {
                uint64_t p;
                Object *o;

                r = journal_file_append_data(f, iovec[i].iov_base, iovec[i].iov_len, &o, &p);
                if (r < 0)
                        return r;

                /* When calculating the XOR hash field, we need to take special care if the "keyed-hash"
                 * journal file flag is on. We use the XOR hash field to quickly determine the identity of a
                 * specific record, and give records with otherwise identical position (i.e. match in seqno,
                 * timestamp, …) a stable ordering. But for that we can't have it that the hash of the
                 * objects in each file is different since they are keyed. Hence let's calculate the Jenkins
                 * hash here for that. This also has the benefit that cursors for old and new journal files
                 * are completely identical (they include the XOR hash after all). For classic Jenkins-hash
                 * files things are easier, we can just take the value from the stored record directly. */

                if (JOURNAL_HEADER_KEYED_HASH(f->header))
                        xor_hash ^= jenkins_hash64(iovec[i].iov_base, iovec[i].iov_len);
                else
                        xor_hash ^= le64toh(o->data.hash);

                items[i] = (EntryItem) {
                        .object_offset = p,
                        .hash = le64toh(o->data.hash),
                };
        }

        /* Order by the position on disk, in order to improve seek
         * times for rotating media. */
        typesafe_qsort(items, n_iovec, entry_item_cmp);
        n_iovec = remove_duplicate_entry_items(items, n_iovec);

        r = journal_file_append_entry_internal(f, ts, boot_id, xor_hash, items, n_iovec, seqnum, ret_object, ret_offset);

        /* If the memory mapping triggered a SIGBUS then we return an
         * IO error and ignore the error code passed down to us, since
         * it is very likely just an effect of a nullified replacement
         * mapping page */

        if (mmap_cache_fd_got_sigbus(f->cache_fd))
                r = -EIO;

        if (f->post_change_timer)
                schedule_post_change(f);
        else
                journal_file_post_change(f);

        return r;
}

typedef struct ChainCacheItem {
        uint64_t first; /* the array at the beginning of the chain */
        uint64_t array; /* the cached array */
        uint64_t begin; /* the first item in the cached array */
        uint64_t total; /* the total number of items in all arrays before this one in the chain */
        uint64_t last_index; /* the last index we looked at, to optimize locality when bisecting */
} ChainCacheItem;

static void chain_cache_put(
                OrderedHashmap *h,
                ChainCacheItem *ci,
                uint64_t first,
                uint64_t array,
                uint64_t begin,
                uint64_t total,
                uint64_t last_index) {

        assert(h);

        if (!ci) {
                /* If the chain item to cache for this chain is the
                 * first one it's not worth caching anything */
                if (array == first)
                        return;

                if (ordered_hashmap_size(h) >= CHAIN_CACHE_MAX) {
                        ci = ordered_hashmap_steal_first(h);
                        assert(ci);
                } else {
                        ci = new(ChainCacheItem, 1);
                        if (!ci)
                                return;
                }

                ci->first = first;

                if (ordered_hashmap_put(h, &ci->first, ci) < 0) {
                        free(ci);
                        return;
                }
        } else
                assert(ci->first == first);

        ci->array = array;
        ci->begin = begin;
        ci->total = total;
        ci->last_index = last_index;
}

static int bump_array_index(uint64_t *i, direction_t direction, uint64_t n) {
        assert(i);

        /* Increase or decrease the specified index, in the right direction. */

        if (direction == DIRECTION_DOWN) {
                if (*i >= n - 1)
                        return 0;

                (*i)++;
        } else {
                if (*i <= 0)
                        return 0;

                (*i)--;
        }

        return 1;
}

static int bump_entry_array(
                JournalFile *f,
                Object *o,
                uint64_t offset,
                uint64_t first,
                direction_t direction,
                uint64_t *ret) {

        uint64_t p, q = 0;
        int r;

        assert(f);
        assert(offset);
        assert(ret);

        if (direction == DIRECTION_DOWN) {
                assert(o);
                *ret = le64toh(o->entry_array.next_entry_array_offset);
                return 0;
        }

        /* Entry array chains are a singly linked list, so to find the previous array in the chain, we have
         * to start iterating from the top. */

        p = first;

        while (p > 0 && p != offset) {
                r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, p, &o);
                if (r < 0)
                        return r;

                q = p;
                p = le64toh(o->entry_array.next_entry_array_offset);
        }

        /* If we can't find the previous entry array in the entry array chain, we're likely dealing with a
         * corrupted journal file. */
        if (p == 0)
                return -EBADMSG;

        *ret = q;

        return 0;
}

static int generic_array_get(
                JournalFile *f,
                uint64_t first,
                uint64_t i,
                direction_t direction,
                Object **ret_object,
                uint64_t *ret_offset) {

        uint64_t p = 0, a, t = 0, k;
        ChainCacheItem *ci;
        Object *o;
        int r;

        assert(f);

        /* FIXME: fix return value assignment on success. */

        a = first;

        /* Try the chain cache first */
        ci = ordered_hashmap_get(f->chain_cache, &first);
        if (ci && i > ci->total) {
                a = ci->array;
                i -= ci->total;
                t = ci->total;
        }

        while (a > 0) {
                r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
                if (IN_SET(r, -EBADMSG, -EADDRNOTAVAIL)) {
                        /* If there's corruption and we're going downwards, let's pretend we reached the
                         * final entry in the entry array chain. */

                        if (direction == DIRECTION_DOWN)
                                return 0;

                        /* If there's corruption and we're going upwards, move back to the previous entry
                         * array and start iterating entries from there. */

                        r = bump_entry_array(f, NULL, a, first, DIRECTION_UP, &a);
                        if (r < 0)
                                return r;

                        i = UINT64_MAX;

                        break;
                }
                if (r < 0)
                        return r;

                k = journal_file_entry_array_n_items(f, o);
                if (i < k)
                        break;

                i -= k;
                t += k;
                a = le64toh(o->entry_array.next_entry_array_offset);
        }

        /* If we've found the right location, now look for the first non-corrupt entry object (in the right
         * direction). */

        while (a > 0) {
                /* In the first iteration of the while loop, we reuse i, k and o from the previous while
                 * loop. */
                if (i == UINT64_MAX) {
                        r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
                        if (r < 0)
                                return r;

                        k = journal_file_entry_array_n_items(f, o);
                        if (k == 0)
                                break;

                        i = direction == DIRECTION_DOWN ? 0 : k - 1;
                }

                do {
                        p = journal_file_entry_array_item(f, o, i);

                        r = journal_file_move_to_object(f, OBJECT_ENTRY, p, ret_object);
                        if (r >= 0) {
                                /* Let's cache this item for the next invocation */
                                chain_cache_put(f->chain_cache, ci, first, a, journal_file_entry_array_item(f, o, 0), t, i);

                                if (ret_offset)
                                        *ret_offset = p;

                                return 1;
                        }
                        if (!IN_SET(r, -EADDRNOTAVAIL, -EBADMSG))
                                return r;

                        /* OK, so this entry is borked. Most likely some entry didn't get synced to
                        * disk properly, let's see if the next one might work for us instead. */
                        log_debug_errno(r, "Entry item %" PRIu64 " is bad, skipping over it.", i);
                } while (bump_array_index(&i, direction, k) > 0);

                r = bump_entry_array(f, o, a, first, direction, &a);
                if (r < 0)
                        return r;

                t += k;
                i = UINT64_MAX;
        }

        return 0;
}

static int generic_array_get_plus_one(
                JournalFile *f,
                uint64_t extra,
                uint64_t first,
                uint64_t i,
                direction_t direction,
                Object **ret_object,
                uint64_t *ret_offset) {

        int r;

        assert(f);

        /* FIXME: fix return value assignment on success. */

        if (i == 0) {
                r = journal_file_move_to_object(f, OBJECT_ENTRY, extra, ret_object);
                if (IN_SET(r, -EADDRNOTAVAIL, -EBADMSG))
                        return generic_array_get(f, first, 0, direction, ret_object, ret_offset);
                if (r < 0)
                        return r;

                if (ret_offset)
                        *ret_offset = extra;

                return 1;
        }

        return generic_array_get(f, first, i - 1, direction, ret_object, ret_offset);
}

enum {
        TEST_FOUND,
        TEST_LEFT,
        TEST_RIGHT
};

static int generic_array_bisect(
                JournalFile *f,
                uint64_t first,
                uint64_t n,
                uint64_t needle,
                int (*test_object)(JournalFile *f, uint64_t p, uint64_t needle),
                direction_t direction,
                Object **ret_object,
                uint64_t *ret_offset,
                uint64_t *ret_idx) {

        /* Given an entry array chain, this function finds the object "closest" to the given needle in the
         * chain, taking into account the provided direction. A function can be provided to determine how
         * an object is matched against the given needle.
         *
         * Given a journal file, the offset of an object and the needle, the test_object() function should
         * return TEST_LEFT if the needle is located earlier in the entry array chain, TEST_RIGHT if the
         * needle is located later in the entry array chain and TEST_FOUND if the object matches the needle.
         * If test_object() returns TEST_FOUND for a specific object, that object's information will be used
         * to populate the return values of this function. If test_object() never returns TEST_FOUND, the
         * return values are populated with the details of one of the objects closest to the needle. If the
         * direction is DIRECTION_UP, the earlier object is used. Otherwise, the later object is used.
         */

        uint64_t a, p, t = 0, i = 0, last_p = 0, last_index = UINT64_MAX;
        bool subtract_one = false;
        Object *array = NULL;
        ChainCacheItem *ci;
        int r;

        assert(f);
        assert(test_object);

        /* Start with the first array in the chain */
        a = first;

        ci = ordered_hashmap_get(f->chain_cache, &first);
        if (ci && n > ci->total && ci->begin != 0) {
                /* Ah, we have iterated this bisection array chain
                 * previously! Let's see if we can skip ahead in the
                 * chain, as far as the last time. But we can't jump
                 * backwards in the chain, so let's check that
                 * first. */

                r = test_object(f, ci->begin, needle);
                if (r < 0)
                        return r;

                if (r == TEST_LEFT) {
                        /* OK, what we are looking for is right of the
                         * begin of this EntryArray, so let's jump
                         * straight to previously cached array in the
                         * chain */

                        a = ci->array;
                        n -= ci->total;
                        t = ci->total;
                        last_index = ci->last_index;
                }
        }

        while (a > 0) {
                uint64_t left, right, k, lp;

                r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &array);
                if (r < 0)
                        return r;

                k = journal_file_entry_array_n_items(f, array);
                right = MIN(k, n);
                if (right <= 0)
                        return 0;

                i = right - 1;
                lp = p = journal_file_entry_array_item(f, array, i);
                if (p <= 0)
                        r = -EBADMSG;
                else
                        r = test_object(f, p, needle);
                if (r == -EBADMSG) {
                        log_debug_errno(r, "Encountered invalid entry while bisecting, cutting algorithm short. (1)");
                        n = i;
                        continue;
                }
                if (r < 0)
                        return r;

                if (r == TEST_FOUND)
                        r = direction == DIRECTION_DOWN ? TEST_RIGHT : TEST_LEFT;

                if (r == TEST_RIGHT) {
                        left = 0;
                        right -= 1;

                        if (last_index != UINT64_MAX) {
                                assert(last_index <= right);

                                /* If we cached the last index we
                                 * looked at, let's try to not to jump
                                 * too wildly around and see if we can
                                 * limit the range to look at early to
                                 * the immediate neighbors of the last
                                 * index we looked at. */

                                if (last_index > 0) {
                                        uint64_t x = last_index - 1;

                                        p = journal_file_entry_array_item(f, array, x);
                                        if (p <= 0)
                                                return -EBADMSG;

                                        r = test_object(f, p, needle);
                                        if (r < 0)
                                                return r;

                                        if (r == TEST_FOUND)
                                                r = direction == DIRECTION_DOWN ? TEST_RIGHT : TEST_LEFT;

                                        if (r == TEST_RIGHT)
                                                right = x;
                                        else
                                                left = x + 1;
                                }

                                if (last_index < right) {
                                        uint64_t y = last_index + 1;

                                        p = journal_file_entry_array_item(f, array, y);
                                        if (p <= 0)
                                                return -EBADMSG;

                                        r = test_object(f, p, needle);
                                        if (r < 0)
                                                return r;

                                        if (r == TEST_FOUND)
                                                r = direction == DIRECTION_DOWN ? TEST_RIGHT : TEST_LEFT;

                                        if (r == TEST_RIGHT)
                                                right = y;
                                        else
                                                left = y + 1;
                                }
                        }

                        for (;;) {
                                if (left == right) {
                                        if (direction == DIRECTION_UP)
                                                subtract_one = true;

                                        i = left;
                                        goto found;
                                }

                                assert(left < right);
                                i = (left + right) / 2;

                                p = journal_file_entry_array_item(f, array, i);
                                if (p <= 0)
                                        r = -EBADMSG;
                                else
                                        r = test_object(f, p, needle);
                                if (r == -EBADMSG) {
                                        log_debug_errno(r, "Encountered invalid entry while bisecting, cutting algorithm short. (2)");
                                        right = n = i;
                                        continue;
                                }
                                if (r < 0)
                                        return r;

                                if (r == TEST_FOUND)
                                        r = direction == DIRECTION_DOWN ? TEST_RIGHT : TEST_LEFT;

                                if (r == TEST_RIGHT)
                                        right = i;
                                else
                                        left = i + 1;
                        }
                }

                if (k >= n) {
                        if (direction == DIRECTION_UP) {
                                i = n;
                                subtract_one = true;
                                goto found;
                        }

                        return 0;
                }

                last_p = lp;

                n -= k;
                t += k;
                last_index = UINT64_MAX;
                a = le64toh(array->entry_array.next_entry_array_offset);
        }

        return 0;

found:
        if (subtract_one && t == 0 && i == 0)
                return 0;

        /* Let's cache this item for the next invocation */
        chain_cache_put(f->chain_cache, ci, first, a, journal_file_entry_array_item(f, array, 0), t, subtract_one ? (i > 0 ? i-1 : UINT64_MAX) : i);

        if (subtract_one && i == 0)
                p = last_p;
        else if (subtract_one)
                p = journal_file_entry_array_item(f, array, i - 1);
        else
                p = journal_file_entry_array_item(f, array, i);

        if (ret_object) {
                r = journal_file_move_to_object(f, OBJECT_ENTRY, p, ret_object);
                if (r < 0)
                        return r;
        }

        if (ret_offset)
                *ret_offset = p;

        if (ret_idx)
                *ret_idx = t + i + (subtract_one ? -1 : 0);

        return 1;
}

static int generic_array_bisect_plus_one(
                JournalFile *f,
                uint64_t extra,
                uint64_t first,
                uint64_t n,
                uint64_t needle,
                int (*test_object)(JournalFile *f, uint64_t p, uint64_t needle),
                direction_t direction,
                Object **ret_object,
                uint64_t *ret_offset,
                uint64_t *ret_idx) {

        int r;
        bool step_back = false;

        assert(f);
        assert(test_object);

        if (n <= 0)
                return 0;

        /* This bisects the array in object 'first', but first checks
         * an extra  */
        r = test_object(f, extra, needle);
        if (r < 0)
                return r;

        if (r == TEST_FOUND)
                r = direction == DIRECTION_DOWN ? TEST_RIGHT : TEST_LEFT;

        /* if we are looking with DIRECTION_UP then we need to first
           see if in the actual array there is a matching entry, and
           return the last one of that. But if there isn't any we need
           to return this one. Hence remember this, and return it
           below. */
        if (r == TEST_LEFT)
                step_back = direction == DIRECTION_UP;

        if (r == TEST_RIGHT) {
                if (direction == DIRECTION_DOWN)
                        goto found;
                else
                        return 0;
        }

        r = generic_array_bisect(f, first, n-1, needle, test_object, direction, ret_object, ret_offset, ret_idx);

        if (r == 0 && step_back)
                goto found;

        if (r > 0 && ret_idx)
                (*ret_idx)++;

        return r;

found:
        if (ret_object) {
                r = journal_file_move_to_object(f, OBJECT_ENTRY, extra, ret_object);
                if (r < 0)
                        return r;
        }

        if (ret_offset)
                *ret_offset = extra;

        if (ret_idx)
                *ret_idx = 0;

        return 1;
}

_pure_ static int test_object_offset(JournalFile *f, uint64_t p, uint64_t needle) {
        assert(f);
        assert(p > 0);

        if (p == needle)
                return TEST_FOUND;
        else if (p < needle)
                return TEST_LEFT;
        else
                return TEST_RIGHT;
}

int journal_file_move_to_entry_by_offset(
                JournalFile *f,
                uint64_t p,
                direction_t direction,
                Object **ret_object,
                uint64_t *ret_offset) {

        assert(f);
        assert(f->header);

        return generic_array_bisect(
                        f,
                        le64toh(f->header->entry_array_offset),
                        le64toh(f->header->n_entries),
                        p,
                        test_object_offset,
                        direction,
                        ret_object, ret_offset, NULL);
}

static int test_object_seqnum(JournalFile *f, uint64_t p, uint64_t needle) {
        uint64_t sq;
        Object *o;
        int r;

        assert(f);
        assert(p > 0);

        r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o);
        if (r < 0)
                return r;

        sq = le64toh(READ_NOW(o->entry.seqnum));
        if (sq == needle)
                return TEST_FOUND;
        else if (sq < needle)
                return TEST_LEFT;
        else
                return TEST_RIGHT;
}

int journal_file_move_to_entry_by_seqnum(
                JournalFile *f,
                uint64_t seqnum,
                direction_t direction,
                Object **ret_object,
                uint64_t *ret_offset) {

        assert(f);
        assert(f->header);

        return generic_array_bisect(
                        f,
                        le64toh(f->header->entry_array_offset),
                        le64toh(f->header->n_entries),
                        seqnum,
                        test_object_seqnum,
                        direction,
                        ret_object, ret_offset, NULL);
}

static int test_object_realtime(JournalFile *f, uint64_t p, uint64_t needle) {
        Object *o;
        uint64_t rt;
        int r;

        assert(f);
        assert(p > 0);

        r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o);
        if (r < 0)
                return r;

        rt = le64toh(READ_NOW(o->entry.realtime));
        if (rt == needle)
                return TEST_FOUND;
        else if (rt < needle)
                return TEST_LEFT;
        else
                return TEST_RIGHT;
}

int journal_file_move_to_entry_by_realtime(
                JournalFile *f,
                uint64_t realtime,
                direction_t direction,
                Object **ret_object,
                uint64_t *ret_offset) {

        assert(f);
        assert(f->header);

        return generic_array_bisect(
                        f,
                        le64toh(f->header->entry_array_offset),
                        le64toh(f->header->n_entries),
                        realtime,
                        test_object_realtime,
                        direction,
                        ret_object, ret_offset, NULL);
}

static int test_object_monotonic(JournalFile *f, uint64_t p, uint64_t needle) {
        Object *o;
        uint64_t m;
        int r;

        assert(f);
        assert(p > 0);

        r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o);
        if (r < 0)
                return r;

        m = le64toh(READ_NOW(o->entry.monotonic));
        if (m == needle)
                return TEST_FOUND;
        else if (m < needle)
                return TEST_LEFT;
        else
                return TEST_RIGHT;
}

static int find_data_object_by_boot_id(
                JournalFile *f,
                sd_id128_t boot_id,
                Object **ret_object,
                uint64_t *ret_offset) {

        char t[STRLEN("_BOOT_ID=") + 32 + 1] = "_BOOT_ID=";

        assert(f);

        sd_id128_to_string(boot_id, t + 9);
        return journal_file_find_data_object(f, t, sizeof(t) - 1, ret_object, ret_offset);
}

int journal_file_move_to_entry_by_monotonic(
                JournalFile *f,
                sd_id128_t boot_id,
                uint64_t monotonic,
                direction_t direction,
                Object **ret_object,
                uint64_t *ret_offset) {

        Object *o;
        int r;

        assert(f);

        r = find_data_object_by_boot_id(f, boot_id, &o, NULL);
        if (r < 0)
                return r;
        if (r == 0)
                return -ENOENT;

        return generic_array_bisect_plus_one(
                        f,
                        le64toh(o->data.entry_offset),
                        le64toh(o->data.entry_array_offset),
                        le64toh(o->data.n_entries),
                        monotonic,
                        test_object_monotonic,
                        direction,
                        ret_object, ret_offset, NULL);
}

void journal_file_reset_location(JournalFile *f) {
        assert(f);

        f->location_type = LOCATION_HEAD;
        f->current_offset = 0;
        f->current_seqnum = 0;
        f->current_realtime = 0;
        f->current_monotonic = 0;
        zero(f->current_boot_id);
        f->current_xor_hash = 0;
}

void journal_file_save_location(JournalFile *f, Object *o, uint64_t offset) {
        assert(f);
        assert(o);

        f->location_type = LOCATION_SEEK;
        f->current_offset = offset;
        f->current_seqnum = le64toh(o->entry.seqnum);
        f->current_realtime = le64toh(o->entry.realtime);
        f->current_monotonic = le64toh(o->entry.monotonic);
        f->current_boot_id = o->entry.boot_id;
        f->current_xor_hash = le64toh(o->entry.xor_hash);
}

int journal_file_compare_locations(JournalFile *af, JournalFile *bf) {
        int r;

        assert(af);
        assert(af->header);
        assert(bf);
        assert(bf->header);
        assert(af->location_type == LOCATION_SEEK);
        assert(bf->location_type == LOCATION_SEEK);

        /* If contents, timestamps and seqnum match, these entries are
         * identical. */
        if (sd_id128_equal(af->current_boot_id, bf->current_boot_id) &&
            af->current_monotonic == bf->current_monotonic &&
            af->current_realtime == bf->current_realtime &&
            af->current_xor_hash == bf->current_xor_hash &&
            sd_id128_equal(af->header->seqnum_id, bf->header->seqnum_id) &&
            af->current_seqnum == bf->current_seqnum)
                return 0;

        if (sd_id128_equal(af->header->seqnum_id, bf->header->seqnum_id)) {

                /* If this is from the same seqnum source, compare
                 * seqnums */
                r = CMP(af->current_seqnum, bf->current_seqnum);
                if (r != 0)
                        return r;

                /* Wow! This is weird, different data but the same
                 * seqnums? Something is borked, but let's make the
                 * best of it and compare by time. */
        }

        if (sd_id128_equal(af->current_boot_id, bf->current_boot_id)) {

                /* If the boot id matches, compare monotonic time */
                r = CMP(af->current_monotonic, bf->current_monotonic);
                if (r != 0)
                        return r;
        }

        /* Otherwise, compare UTC time */
        r = CMP(af->current_realtime, bf->current_realtime);
        if (r != 0)
                return r;

        /* Finally, compare by contents */
        return CMP(af->current_xor_hash, bf->current_xor_hash);
}

static bool check_properly_ordered(uint64_t new_offset, uint64_t old_offset, direction_t direction) {

        /* Consider it an error if any of the two offsets is uninitialized */
        if (old_offset == 0 || new_offset == 0)
                return false;

        /* If we go down, the new offset must be larger than the old one. */
        return direction == DIRECTION_DOWN ?
                new_offset > old_offset  :
                new_offset < old_offset;
}

int journal_file_next_entry(
                JournalFile *f,
                uint64_t p,
                direction_t direction,
                Object **ret_object,
                uint64_t *ret_offset) {

        uint64_t i, n, ofs;
        int r;

        assert(f);
        assert(f->header);

        /* FIXME: fix return value assignment. */

        n = le64toh(READ_NOW(f->header->n_entries));
        if (n <= 0)
                return 0;

        if (p == 0)
                i = direction == DIRECTION_DOWN ? 0 : n - 1;
        else {
                r = generic_array_bisect(f,
                                         le64toh(f->header->entry_array_offset),
                                         le64toh(f->header->n_entries),
                                         p,
                                         test_object_offset,
                                         DIRECTION_DOWN,
                                         NULL, NULL,
                                         &i);
                if (r <= 0)
                        return r;

                r = bump_array_index(&i, direction, n);
                if (r <= 0)
                        return r;
        }

        /* And jump to it */
        r = generic_array_get(f, le64toh(f->header->entry_array_offset), i, direction, ret_object, &ofs);
        if (r <= 0)
                return r;

        /* Ensure our array is properly ordered. */
        if (p > 0 && !check_properly_ordered(ofs, p, direction))
                return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                       "%s: entry array not properly ordered at entry %" PRIu64,
                                       f->path, i);

        if (ret_offset)
                *ret_offset = ofs;

        return 1;
}

int journal_file_next_entry_for_data(
                JournalFile *f,
                Object *d,
                direction_t direction,
                Object **ret_object,
                uint64_t *ret_offset) {

        uint64_t i, n, ofs;
        int r;

        assert(f);
        assert(d);
        assert(d->object.type == OBJECT_DATA);

        /* FIXME: fix return value assignment. */

        n = le64toh(READ_NOW(d->data.n_entries));
        if (n <= 0)
                return n;

        i = direction == DIRECTION_DOWN ? 0 : n - 1;

        r = generic_array_get_plus_one(f,
                                       le64toh(d->data.entry_offset),
                                       le64toh(d->data.entry_array_offset),
                                       i,
                                       direction,
                                       ret_object, &ofs);
        if (r <= 0)
                return r;

        if (ret_offset)
                *ret_offset = ofs;

        return 1;
}

int journal_file_move_to_entry_by_offset_for_data(
                JournalFile *f,
                Object *d,
                uint64_t p,
                direction_t direction,
                Object **ret, uint64_t *ret_offset) {

        assert(f);
        assert(d);
        assert(d->object.type == OBJECT_DATA);

        return generic_array_bisect_plus_one(
                        f,
                        le64toh(d->data.entry_offset),
                        le64toh(d->data.entry_array_offset),
                        le64toh(d->data.n_entries),
                        p,
                        test_object_offset,
                        direction,
                        ret, ret_offset, NULL);
}

int journal_file_move_to_entry_by_monotonic_for_data(
                JournalFile *f,
                Object *d,
                sd_id128_t boot_id,
                uint64_t monotonic,
                direction_t direction,
                Object **ret_object,
                uint64_t *ret_offset) {

        uint64_t b, z, entry_offset, entry_array_offset, n_entries;
        Object *o;
        int r;

        assert(f);
        assert(d);
        assert(d->object.type == OBJECT_DATA);

        /* Save all the required data before the data object gets invalidated. */
        entry_offset = le64toh(READ_NOW(d->data.entry_offset));
        entry_array_offset = le64toh(READ_NOW(d->data.entry_array_offset));
        n_entries = le64toh(READ_NOW(d->data.n_entries));

        /* First, seek by time */
        r = find_data_object_by_boot_id(f, boot_id, &o, &b);
        if (r < 0)
                return r;
        if (r == 0)
                return -ENOENT;

        r = generic_array_bisect_plus_one(f,
                                          le64toh(o->data.entry_offset),
                                          le64toh(o->data.entry_array_offset),
                                          le64toh(o->data.n_entries),
                                          monotonic,
                                          test_object_monotonic,
                                          direction,
                                          NULL, &z, NULL);
        if (r <= 0)
                return r;

        /* And now, continue seeking until we find an entry that
         * exists in both bisection arrays */

        r = journal_file_move_to_object(f, OBJECT_DATA, b, &o);
        if (r < 0)
                return r;

        for (;;) {
                uint64_t p, q;

                r = generic_array_bisect_plus_one(f,
                                                  entry_offset,
                                                  entry_array_offset,
                                                  n_entries,
                                                  z,
                                                  test_object_offset,
                                                  direction,
                                                  NULL, &p, NULL);
                if (r <= 0)
                        return r;

                r = generic_array_bisect_plus_one(f,
                                                  le64toh(o->data.entry_offset),
                                                  le64toh(o->data.entry_array_offset),
                                                  le64toh(o->data.n_entries),
                                                  p,
                                                  test_object_offset,
                                                  direction,
                                                  NULL, &q, NULL);

                if (r <= 0)
                        return r;

                if (p == q) {
                        if (ret_object) {
                                r = journal_file_move_to_object(f, OBJECT_ENTRY, q, ret_object);
                                if (r < 0)
                                        return r;
                        }

                        if (ret_offset)
                                *ret_offset = q;

                        return 1;
                }

                z = q;
        }
}

int journal_file_move_to_entry_by_seqnum_for_data(
                JournalFile *f,
                Object *d,
                uint64_t seqnum,
                direction_t direction,
                Object **ret_object,
                uint64_t *ret_offset) {

        assert(f);
        assert(d);
        assert(d->object.type == OBJECT_DATA);

        return generic_array_bisect_plus_one(
                        f,
                        le64toh(d->data.entry_offset),
                        le64toh(d->data.entry_array_offset),
                        le64toh(d->data.n_entries),
                        seqnum,
                        test_object_seqnum,
                        direction,
                        ret_object, ret_offset, NULL);
}

int journal_file_move_to_entry_by_realtime_for_data(
                JournalFile *f,
                Object *d,
                uint64_t realtime,
                direction_t direction,
                Object **ret, uint64_t *ret_offset) {

        assert(f);
        assert(d);
        assert(d->object.type == OBJECT_DATA);

        return generic_array_bisect_plus_one(
                        f,
                        le64toh(d->data.entry_offset),
                        le64toh(d->data.entry_array_offset),
                        le64toh(d->data.n_entries),
                        realtime,
                        test_object_realtime,
                        direction,
                        ret, ret_offset, NULL);
}

void journal_file_dump(JournalFile *f) {
        Object *o;
        uint64_t p;
        int r;

        assert(f);
        assert(f->header);

        journal_file_print_header(f);

        p = le64toh(READ_NOW(f->header->header_size));
        while (p != 0) {
                const char *s;
                Compression c;

                r = journal_file_move_to_object(f, OBJECT_UNUSED, p, &o);
                if (r < 0)
                        goto fail;

                s = journal_object_type_to_string(o->object.type);

                switch (o->object.type) {

                case OBJECT_ENTRY:
                        assert(s);

                        printf("Type: %s seqnum=%"PRIu64" monotonic=%"PRIu64" realtime=%"PRIu64"\n",
                               s,
                               le64toh(o->entry.seqnum),
                               le64toh(o->entry.monotonic),
                               le64toh(o->entry.realtime));
                        break;

                case OBJECT_TAG:
                        assert(s);

                        printf("Type: %s seqnum=%"PRIu64" epoch=%"PRIu64"\n",
                               s,
                               le64toh(o->tag.seqnum),
                               le64toh(o->tag.epoch));
                        break;

                default:
                        if (s)
                                printf("Type: %s \n", s);
                        else
                                printf("Type: unknown (%i)", o->object.type);

                        break;
                }

                c = COMPRESSION_FROM_OBJECT(o);
                if (c > COMPRESSION_NONE)
                        printf("Flags: %s\n",
                               compression_to_string(c));

                if (p == le64toh(f->header->tail_object_offset))
                        p = 0;
                else
                        p += ALIGN64(le64toh(o->object.size));
        }

        return;
fail:
        log_error("File corrupt");
}

/* Note: the lifetime of the compound literal is the immediately surrounding block. */
#define FORMAT_TIMESTAMP_SAFE(t) (FORMAT_TIMESTAMP(t) ?: " --- ")

void journal_file_print_header(JournalFile *f) {
        struct stat st;

        assert(f);
        assert(f->header);

        printf("File path: %s\n"
               "File ID: %s\n"
               "Machine ID: %s\n"
               "Boot ID: %s\n"
               "Sequential number ID: %s\n"
               "State: %s\n"
               "Compatible flags:%s%s\n"
               "Incompatible flags:%s%s%s%s%s%s\n"
               "Header size: %"PRIu64"\n"
               "Arena size: %"PRIu64"\n"
               "Data hash table size: %"PRIu64"\n"
               "Field hash table size: %"PRIu64"\n"
               "Rotate suggested: %s\n"
               "Head sequential number: %"PRIu64" (%"PRIx64")\n"
               "Tail sequential number: %"PRIu64" (%"PRIx64")\n"
               "Head realtime timestamp: %s (%"PRIx64")\n"
               "Tail realtime timestamp: %s (%"PRIx64")\n"
               "Tail monotonic timestamp: %s (%"PRIx64")\n"
               "Objects: %"PRIu64"\n"
               "Entry objects: %"PRIu64"\n",
               f->path,
               SD_ID128_TO_STRING(f->header->file_id),
               SD_ID128_TO_STRING(f->header->machine_id),
               SD_ID128_TO_STRING(f->header->boot_id),
               SD_ID128_TO_STRING(f->header->seqnum_id),
               f->header->state == STATE_OFFLINE ? "OFFLINE" :
               f->header->state == STATE_ONLINE ? "ONLINE" :
               f->header->state == STATE_ARCHIVED ? "ARCHIVED" : "UNKNOWN",
               JOURNAL_HEADER_SEALED(f->header) ? " SEALED" : "",
               (le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_ANY) ? " ???" : "",
               JOURNAL_HEADER_COMPRESSED_XZ(f->header) ? " COMPRESSED-XZ" : "",
               JOURNAL_HEADER_COMPRESSED_LZ4(f->header) ? " COMPRESSED-LZ4" : "",
               JOURNAL_HEADER_COMPRESSED_ZSTD(f->header) ? " COMPRESSED-ZSTD" : "",
               JOURNAL_HEADER_KEYED_HASH(f->header) ? " KEYED-HASH" : "",
               JOURNAL_HEADER_COMPACT(f->header) ? " COMPACT" : "",
               (le32toh(f->header->incompatible_flags) & ~HEADER_INCOMPATIBLE_ANY) ? " ???" : "",
               le64toh(f->header->header_size),
               le64toh(f->header->arena_size),
               le64toh(f->header->data_hash_table_size) / sizeof(HashItem),
               le64toh(f->header->field_hash_table_size) / sizeof(HashItem),
               yes_no(journal_file_rotate_suggested(f, 0, LOG_DEBUG)),
               le64toh(f->header->head_entry_seqnum), le64toh(f->header->head_entry_seqnum),
               le64toh(f->header->tail_entry_seqnum), le64toh(f->header->tail_entry_seqnum),
               FORMAT_TIMESTAMP_SAFE(le64toh(f->header->head_entry_realtime)), le64toh(f->header->head_entry_realtime),
               FORMAT_TIMESTAMP_SAFE(le64toh(f->header->tail_entry_realtime)), le64toh(f->header->tail_entry_realtime),
               FORMAT_TIMESPAN(le64toh(f->header->tail_entry_monotonic), USEC_PER_MSEC), le64toh(f->header->tail_entry_monotonic),
               le64toh(f->header->n_objects),
               le64toh(f->header->n_entries));

        if (JOURNAL_HEADER_CONTAINS(f->header, n_data))
                printf("Data objects: %"PRIu64"\n"
                       "Data hash table fill: %.1f%%\n",
                       le64toh(f->header->n_data),
                       100.0 * (double) le64toh(f->header->n_data) / ((double) (le64toh(f->header->data_hash_table_size) / sizeof(HashItem))));

        if (JOURNAL_HEADER_CONTAINS(f->header, n_fields))
                printf("Field objects: %"PRIu64"\n"
                       "Field hash table fill: %.1f%%\n",
                       le64toh(f->header->n_fields),
                       100.0 * (double) le64toh(f->header->n_fields) / ((double) (le64toh(f->header->field_hash_table_size) / sizeof(HashItem))));

        if (JOURNAL_HEADER_CONTAINS(f->header, n_tags))
                printf("Tag objects: %"PRIu64"\n",
                       le64toh(f->header->n_tags));
        if (JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays))
                printf("Entry array objects: %"PRIu64"\n",
                       le64toh(f->header->n_entry_arrays));

        if (JOURNAL_HEADER_CONTAINS(f->header, field_hash_chain_depth))
                printf("Deepest field hash chain: %" PRIu64"\n",
                       f->header->field_hash_chain_depth);

        if (JOURNAL_HEADER_CONTAINS(f->header, data_hash_chain_depth))
                printf("Deepest data hash chain: %" PRIu64"\n",
                       f->header->data_hash_chain_depth);

        if (fstat(f->fd, &st) >= 0)
                printf("Disk usage: %s\n", FORMAT_BYTES((uint64_t) st.st_blocks * 512ULL));
}

static int journal_file_warn_btrfs(JournalFile *f) {
        unsigned attrs;
        int r;

        assert(f);

        /* Before we write anything, check if the COW logic is turned
         * off on btrfs. Given our write pattern that is quite
         * unfriendly to COW file systems this should greatly improve
         * performance on COW file systems, such as btrfs, at the
         * expense of data integrity features (which shouldn't be too
         * bad, given that we do our own checksumming). */

        r = fd_is_fs_type(f->fd, BTRFS_SUPER_MAGIC);
        if (r < 0)
                return log_ratelimit_warning_errno(r, JOURNAL_LOG_RATELIMIT, "Failed to determine if journal is on btrfs: %m");
        if (!r)
                return 0;

        r = read_attr_fd(f->fd, &attrs);
        if (r < 0)
                return log_ratelimit_warning_errno(r, JOURNAL_LOG_RATELIMIT, "Failed to read file attributes: %m");

        if (attrs & FS_NOCOW_FL) {
                log_debug("Detected btrfs file system with copy-on-write disabled, all is good.");
                return 0;
        }

        log_ratelimit_notice(JOURNAL_LOG_RATELIMIT,
                             "Creating journal file %s on a btrfs file system, and copy-on-write is enabled. "
                             "This is likely to slow down journal access substantially, please consider turning "
                             "off the copy-on-write file attribute on the journal directory, using chattr +C.",
                             f->path);

        return 1;
}

static void journal_default_metrics(JournalMetrics *m, int fd, bool compact) {
        struct statvfs ss;
        uint64_t fs_size = 0;

        assert(m);
        assert(fd >= 0);

        if (fstatvfs(fd, &ss) >= 0)
                fs_size = ss.f_frsize * ss.f_blocks;
        else
                log_debug_errno(errno, "Failed to determine disk size: %m");

        if (m->max_use == UINT64_MAX) {

                if (fs_size > 0)
                        m->max_use = CLAMP(PAGE_ALIGN(fs_size / 10), /* 10% of file system size */
                                           MAX_USE_LOWER, MAX_USE_UPPER);
                else
                        m->max_use = MAX_USE_LOWER;
        } else {
                m->max_use = PAGE_ALIGN(m->max_use);

                if (m->max_use != 0 && m->max_use < JOURNAL_FILE_SIZE_MIN*2)
                        m->max_use = JOURNAL_FILE_SIZE_MIN*2;
        }

        if (m->min_use == UINT64_MAX) {
                if (fs_size > 0)
                        m->min_use = CLAMP(PAGE_ALIGN(fs_size / 50), /* 2% of file system size */
                                           MIN_USE_LOW, MIN_USE_HIGH);
                else
                        m->min_use = MIN_USE_LOW;
        }

        if (m->min_use > m->max_use)
                m->min_use = m->max_use;

        if (m->max_size == UINT64_MAX)
                m->max_size = MIN(PAGE_ALIGN(m->max_use / 8), /* 8 chunks */
                                  MAX_SIZE_UPPER);
        else
                m->max_size = PAGE_ALIGN(m->max_size);

        if (compact && m->max_size > JOURNAL_COMPACT_SIZE_MAX)
                m->max_size = JOURNAL_COMPACT_SIZE_MAX;

        if (m->max_size != 0) {
                if (m->max_size < JOURNAL_FILE_SIZE_MIN)
                        m->max_size = JOURNAL_FILE_SIZE_MIN;

                if (m->max_use != 0 && m->max_size*2 > m->max_use)
                        m->max_use = m->max_size*2;
        }

        if (m->min_size == UINT64_MAX)
                m->min_size = JOURNAL_FILE_SIZE_MIN;
        else
                m->min_size = CLAMP(PAGE_ALIGN(m->min_size),
                                    JOURNAL_FILE_SIZE_MIN,
                                    m->max_size ?: UINT64_MAX);

        if (m->keep_free == UINT64_MAX) {
                if (fs_size > 0)
                        m->keep_free = MIN(PAGE_ALIGN(fs_size / 20), /* 5% of file system size */
                                           KEEP_FREE_UPPER);
                else
                        m->keep_free = DEFAULT_KEEP_FREE;
        }

        if (m->n_max_files == UINT64_MAX)
                m->n_max_files = DEFAULT_N_MAX_FILES;

        log_debug("Fixed min_use=%s max_use=%s max_size=%s min_size=%s keep_free=%s n_max_files=%" PRIu64,
                  FORMAT_BYTES(m->min_use),
                  FORMAT_BYTES(m->max_use),
                  FORMAT_BYTES(m->max_size),
                  FORMAT_BYTES(m->min_size),
                  FORMAT_BYTES(m->keep_free),
                  m->n_max_files);
}

int journal_file_open(
                int fd,
                const char *fname,
                int open_flags,
                JournalFileFlags file_flags,
                mode_t mode,
                uint64_t compress_threshold_bytes,
                JournalMetrics *metrics,
                MMapCache *mmap_cache,
                JournalFile *template,
                JournalFile **ret) {

        bool newly_created = false;
        JournalFile *f;
        void *h;
        int r;

        assert(fd >= 0 || fname);
        assert(file_flags >= 0);
        assert(file_flags <= _JOURNAL_FILE_FLAGS_MAX);
        assert(mmap_cache);
        assert(ret);

        if (!IN_SET((open_flags & O_ACCMODE), O_RDONLY, O_RDWR))
                return -EINVAL;

        if ((open_flags & O_ACCMODE) == O_RDONLY && FLAGS_SET(open_flags, O_CREAT))
                return -EINVAL;

        if (fname && (open_flags & O_CREAT) && !endswith(fname, ".journal"))
                return -EINVAL;

        f = new(JournalFile, 1);
        if (!f)
                return -ENOMEM;

        *f = (JournalFile) {
                .fd = fd,
                .mode = mode,
                .open_flags = open_flags,
                .compress_threshold_bytes = compress_threshold_bytes == UINT64_MAX ?
                                            DEFAULT_COMPRESS_THRESHOLD :
                                            MAX(MIN_COMPRESS_THRESHOLD, compress_threshold_bytes),
                .strict_order = FLAGS_SET(file_flags, JOURNAL_STRICT_ORDER),
        };

        if (fname) {
                f->path = strdup(fname);
                if (!f->path) {
                        r = -ENOMEM;
                        goto fail;
                }
        } else {
                assert(fd >= 0);

                /* If we don't know the path, fill in something explanatory and vaguely useful */
                if (asprintf(&f->path, "/proc/self/%i", fd) < 0) {
                        r = -ENOMEM;
                        goto fail;
                }
        }

        f->chain_cache = ordered_hashmap_new(&uint64_hash_ops);
        if (!f->chain_cache) {
                r = -ENOMEM;
                goto fail;
        }

        if (f->fd < 0) {
                /* We pass O_NONBLOCK here, so that in case somebody pointed us to some character device node or FIFO
                 * or so, we likely fail quickly than block for long. For regular files O_NONBLOCK has no effect, hence
                 * it doesn't hurt in that case. */

                f->fd = openat_report_new(AT_FDCWD, f->path, f->open_flags|O_CLOEXEC|O_NONBLOCK, f->mode, &newly_created);
                if (f->fd < 0) {
                        r = f->fd;
                        goto fail;
                }

                /* fds we opened here by us should also be closed by us. */
                f->close_fd = true;

                r = fd_nonblock(f->fd, false);
                if (r < 0)
                        goto fail;

                if (!newly_created) {
                        r = journal_file_fstat(f);
                        if (r < 0)
                                goto fail;
                }
        } else {
                r = journal_file_fstat(f);
                if (r < 0)
                        goto fail;

                /* If we just got the fd passed in, we don't really know if we created the file anew */
                newly_created = f->last_stat.st_size == 0 && journal_file_writable(f);
        }

        f->cache_fd = mmap_cache_add_fd(mmap_cache, f->fd, mmap_prot_from_open_flags(open_flags));
        if (!f->cache_fd) {
                r = -ENOMEM;
                goto fail;
        }

        if (newly_created) {
                (void) journal_file_warn_btrfs(f);

                /* Let's attach the creation time to the journal file, so that the vacuuming code knows the age of this
                 * file even if the file might end up corrupted one day... Ideally we'd just use the creation time many
                 * file systems maintain for each file, but the API to query this is very new, hence let's emulate this
                 * via extended attributes. If extended attributes are not supported we'll just skip this, and rely
                 * solely on mtime/atime/ctime of the file. */
                (void) fd_setcrtime(f->fd, 0);

                r = journal_file_init_header(f, file_flags, template);
                if (r < 0)
                        goto fail;

                r = journal_file_fstat(f);
                if (r < 0)
                        goto fail;
        }

        if (f->last_stat.st_size < (off_t) HEADER_SIZE_MIN) {
                r = -ENODATA;
                goto fail;
        }

        r = mmap_cache_fd_get(f->cache_fd, CONTEXT_HEADER, true, 0, PAGE_ALIGN(sizeof(Header)), &f->last_stat, &h);
        if (r == -EINVAL) {
                /* Some file systems (jffs2 or p9fs) don't support mmap() properly (or only read-only
                 * mmap()), and return EINVAL in that case. Let's propagate that as a more recognizable error
                 * code. */
                r = -EAFNOSUPPORT;
                goto fail;
        }
        if (r < 0)
                goto fail;

        f->header = h;

        if (!newly_created) {
                r = journal_file_verify_header(f);
                if (r < 0)
                        goto fail;
        }

#if HAVE_GCRYPT
        if (!newly_created && journal_file_writable(f) && JOURNAL_HEADER_SEALED(f->header)) {
                r = journal_file_fss_load(f);
                if (r < 0)
                        goto fail;
        }
#endif

        if (journal_file_writable(f)) {
                if (metrics) {
                        journal_default_metrics(metrics, f->fd, JOURNAL_HEADER_COMPACT(f->header));
                        f->metrics = *metrics;
                } else if (template)
                        f->metrics = template->metrics;

                r = journal_file_refresh_header(f);
                if (r < 0)
                        goto fail;
        }

#if HAVE_GCRYPT
        r = journal_file_hmac_setup(f);
        if (r < 0)
                goto fail;
#endif

        if (newly_created) {
                r = journal_file_setup_field_hash_table(f);
                if (r < 0)
                        goto fail;

                r = journal_file_setup_data_hash_table(f);
                if (r < 0)
                        goto fail;

#if HAVE_GCRYPT
                r = journal_file_append_first_tag(f);
                if (r < 0)
                        goto fail;
#endif
        }

        if (mmap_cache_fd_got_sigbus(f->cache_fd)) {
                r = -EIO;
                goto fail;
        }

        if (template && template->post_change_timer) {
                r = journal_file_enable_post_change_timer(
                                f,
                                sd_event_source_get_event(template->post_change_timer),
                                template->post_change_timer_period);

                if (r < 0)
                        goto fail;
        }

        /* The file is opened now successfully, thus we take possession of any passed in fd. */
        f->close_fd = true;

        if (DEBUG_LOGGING) {
                static int last_seal = -1, last_compress = -1, last_keyed_hash = -1;
                static uint64_t last_bytes = UINT64_MAX;

                if (last_seal != JOURNAL_HEADER_SEALED(f->header) ||
                    last_keyed_hash != JOURNAL_HEADER_KEYED_HASH(f->header) ||
                    last_compress != JOURNAL_FILE_COMPRESS(f) ||
                    last_bytes != f->compress_threshold_bytes) {

                        log_debug("Journal effective settings seal=%s keyed_hash=%s compress=%s compress_threshold_bytes=%s",
                                  yes_no(JOURNAL_HEADER_SEALED(f->header)), yes_no(JOURNAL_HEADER_KEYED_HASH(f->header)),
                                  yes_no(JOURNAL_FILE_COMPRESS(f)), FORMAT_BYTES(f->compress_threshold_bytes));
                        last_seal = JOURNAL_HEADER_SEALED(f->header);
                        last_keyed_hash = JOURNAL_HEADER_KEYED_HASH(f->header);
                        last_compress = JOURNAL_FILE_COMPRESS(f);
                        last_bytes = f->compress_threshold_bytes;
                }
        }

        *ret = f;
        return 0;

fail:
        if (f->cache_fd && mmap_cache_fd_got_sigbus(f->cache_fd))
                r = -EIO;

        (void) journal_file_close(f);

        if (newly_created && fd < 0)
                (void) unlink(fname);

        return r;
}

int journal_file_parse_uid_from_filename(const char *path, uid_t *ret_uid) {
        _cleanup_free_ char *buf = NULL, *p = NULL;
        const char *a, *b, *at;
        int r;

        /* This helper returns -EREMOTE when the filename doesn't match user online/offline journal
         * pattern. Hence it currently doesn't parse archived or disposed user journals. */

        assert(path);
        assert(ret_uid);

        r = path_extract_filename(path, &p);
        if (r < 0)
                return r;
        if (r == O_DIRECTORY)
                return -EISDIR;

        a = startswith(p, "user-");
        if (!a)
                return -EREMOTE;
        b = endswith(p, ".journal");
        if (!b)
                return -EREMOTE;

        at = strchr(a, '@');
        if (at)
                return -EREMOTE;

        buf = strndup(a, b-a);
        if (!buf)
                return -ENOMEM;

        return parse_uid(buf, ret_uid);
}

int journal_file_archive(JournalFile *f, char **ret_previous_path) {
        _cleanup_free_ char *p = NULL;

        assert(f);

        if (!journal_file_writable(f))
                return -EINVAL;

        /* Is this a journal file that was passed to us as fd? If so, we synthesized a path name for it, and we refuse
         * rotation, since we don't know the actual path, and couldn't rename the file hence. */
        if (path_startswith(f->path, "/proc/self/fd"))
                return -EINVAL;

        if (!endswith(f->path, ".journal"))
                return -EINVAL;

        if (asprintf(&p, "%.*s@" SD_ID128_FORMAT_STR "-%016"PRIx64"-%016"PRIx64".journal",
                     (int) strlen(f->path) - 8, f->path,
                     SD_ID128_FORMAT_VAL(f->header->seqnum_id),
                     le64toh(f->header->head_entry_seqnum),
                     le64toh(f->header->head_entry_realtime)) < 0)
                return -ENOMEM;

        /* Try to rename the file to the archived version. If the file already was deleted, we'll get ENOENT, let's
         * ignore that case. */
        if (rename(f->path, p) < 0 && errno != ENOENT)
                return -errno;

        /* Sync the rename to disk */
        (void) fsync_directory_of_file(f->fd);

        if (ret_previous_path)
                *ret_previous_path = f->path;
        else
                free(f->path);

        f->path = TAKE_PTR(p);

        /* Set as archive so offlining commits w/state=STATE_ARCHIVED. Previously we would set old_file->header->state
         * to STATE_ARCHIVED directly here, but journal_file_set_offline() short-circuits when state != STATE_ONLINE,
         * which would result in the rotated journal never getting fsync() called before closing.  Now we simply queue
         * the archive state by setting an archive bit, leaving the state as STATE_ONLINE so proper offlining
         * occurs. */
        f->archive = true;

        return 0;
}

int journal_file_dispose(int dir_fd, const char *fname) {
        _cleanup_free_ char *p = NULL;

        assert(fname);

        /* Renames a journal file to *.journal~, i.e. to mark it as corrupted or otherwise uncleanly shutdown. Note that
         * this is done without looking into the file or changing any of its contents. The idea is that this is called
         * whenever something is suspicious and we want to move the file away and make clear that it is not accessed
         * for writing anymore. */

        if (!endswith(fname, ".journal"))
                return -EINVAL;

        if (asprintf(&p, "%.*s@%016" PRIx64 "-%016" PRIx64 ".journal~",
                     (int) strlen(fname) - 8, fname,
                     now(CLOCK_REALTIME),
                     random_u64()) < 0)
                return -ENOMEM;

        if (renameat(dir_fd, fname, dir_fd, p) < 0)
                return -errno;

        return 0;
}

int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint64_t p) {
        _cleanup_free_ EntryItem *items_alloc = NULL;
        EntryItem *items;
        uint64_t q, n, xor_hash = 0;
        const sd_id128_t *boot_id;
        dual_timestamp ts;
        int r;

        assert(from);
        assert(to);
        assert(o);
        assert(p > 0);

        if (!journal_file_writable(to))
                return -EPERM;

        ts = (dual_timestamp) {
                .monotonic = le64toh(o->entry.monotonic),
                .realtime = le64toh(o->entry.realtime),
        };
        boot_id = &o->entry.boot_id;

        n = journal_file_entry_n_items(from, o);

        if (n < ALLOCA_MAX / sizeof(EntryItem) / 2)
                items = newa(EntryItem, n);
        else {
                items_alloc = new(EntryItem, n);
                if (!items_alloc)
                        return -ENOMEM;

                items = items_alloc;
        }

        for (uint64_t i = 0; i < n; i++) {
                uint64_t h;
                void *data;
                size_t l;
                Object *u;

                q = journal_file_entry_item_object_offset(from, o, i);
                r = journal_file_data_payload(from, NULL, q, NULL, 0, 0, &data, &l);
                if (IN_SET(r, -EADDRNOTAVAIL, -EBADMSG)) {
                        log_debug_errno(r, "Entry item %"PRIu64" data object is bad, skipping over it: %m", i);
                        goto next;
                }
                if (r < 0)
                        return r;
                assert(r > 0);

                if (l == 0)
                        return -EBADMSG;

                r = journal_file_append_data(to, data, l, &u, &h);
                if (r < 0)
                        return r;

                if (JOURNAL_HEADER_KEYED_HASH(to->header))
                        xor_hash ^= jenkins_hash64(data, l);
                else
                        xor_hash ^= le64toh(u->data.hash);

                items[i] = (EntryItem) {
                        .object_offset = h,
                        .hash = le64toh(u->data.hash),
                };

        next:
                /* The above journal_file_data_payload() may clear or overwrite cached object. Hence, we need
                 * to re-read the object from the cache. */
                r = journal_file_move_to_object(from, OBJECT_ENTRY, p, &o);
                if (r < 0)
                        return r;
        }

        r = journal_file_append_entry_internal(to, &ts, boot_id, xor_hash, items, n, NULL, NULL, NULL);

        if (mmap_cache_fd_got_sigbus(to->cache_fd))
                return -EIO;

        return r;
}

void journal_reset_metrics(JournalMetrics *m) {
        assert(m);

        /* Set everything to "pick automatic values". */

        *m = (JournalMetrics) {
                .min_use = UINT64_MAX,
                .max_use = UINT64_MAX,
                .min_size = UINT64_MAX,
                .max_size = UINT64_MAX,
                .keep_free = UINT64_MAX,
                .n_max_files = UINT64_MAX,
        };
}

int journal_file_get_cutoff_realtime_usec(JournalFile *f, usec_t *ret_from, usec_t *ret_to) {
        assert(f);
        assert(f->header);
        assert(ret_from || ret_to);

        if (ret_from) {
                if (f->header->head_entry_realtime == 0)
                        return -ENOENT;

                *ret_from = le64toh(f->header->head_entry_realtime);
        }

        if (ret_to) {
                if (f->header->tail_entry_realtime == 0)
                        return -ENOENT;

                *ret_to = le64toh(f->header->tail_entry_realtime);
        }

        return 1;
}

int journal_file_get_cutoff_monotonic_usec(JournalFile *f, sd_id128_t boot_id, usec_t *ret_from, usec_t *ret_to) {
        Object *o;
        uint64_t p;
        int r;

        assert(f);
        assert(ret_from || ret_to);

        /* FIXME: fix return value assignment on success with 0. */

        r = find_data_object_by_boot_id(f, boot_id, &o, &p);
        if (r <= 0)
                return r;

        if (le64toh(o->data.n_entries) <= 0)
                return 0;

        if (ret_from) {
                r = journal_file_move_to_object(f, OBJECT_ENTRY, le64toh(o->data.entry_offset), &o);
                if (r < 0)
                        return r;

                *ret_from = le64toh(o->entry.monotonic);
        }

        if (ret_to) {
                r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
                if (r < 0)
                        return r;

                r = generic_array_get_plus_one(f,
                                               le64toh(o->data.entry_offset),
                                               le64toh(o->data.entry_array_offset),
                                               le64toh(o->data.n_entries) - 1,
                                               DIRECTION_UP,
                                               &o, NULL);
                if (r <= 0)
                        return r;

                *ret_to = le64toh(o->entry.monotonic);
        }

        return 1;
}

bool journal_file_rotate_suggested(JournalFile *f, usec_t max_file_usec, int log_level) {
        assert(f);
        assert(f->header);

        /* If we gained new header fields we gained new features,
         * hence suggest a rotation */
        if (le64toh(f->header->header_size) < sizeof(Header)) {
                log_ratelimit_full(log_level, JOURNAL_LOG_RATELIMIT,
                                   "%s uses an outdated header, suggesting rotation.", f->path);
                return true;
        }

        /* Let's check if the hash tables grew over a certain fill level (75%, borrowing this value from
         * Java's hash table implementation), and if so suggest a rotation. To calculate the fill level we
         * need the n_data field, which only exists in newer versions. */

        if (JOURNAL_HEADER_CONTAINS(f->header, n_data))
                if (le64toh(f->header->n_data) * 4ULL > (le64toh(f->header->data_hash_table_size) / sizeof(HashItem)) * 3ULL) {
                        log_ratelimit_full(
                                log_level, JOURNAL_LOG_RATELIMIT,
                                "Data hash table of %s has a fill level at %.1f (%"PRIu64" of %"PRIu64" items, %"PRIu64" 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))),
                                le64toh(f->header->n_data),
                                le64toh(f->header->data_hash_table_size) / sizeof(HashItem),
                                (uint64_t) f->last_stat.st_size,
                                f->last_stat.st_size / le64toh(f->header->n_data));
                        return true;
                }

        if (JOURNAL_HEADER_CONTAINS(f->header, n_fields))
                if (le64toh(f->header->n_fields) * 4ULL > (le64toh(f->header->field_hash_table_size) / sizeof(HashItem)) * 3ULL) {
                        log_ratelimit_full(
                                log_level, JOURNAL_LOG_RATELIMIT,
                                "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))),
                                le64toh(f->header->n_fields),
                                le64toh(f->header->field_hash_table_size) / sizeof(HashItem));
                        return true;
                }

        /* If there are too many hash collisions somebody is most likely playing games with us. Hence, if our
         * longest chain is longer than some threshold, let's suggest rotation. */
        if (JOURNAL_HEADER_CONTAINS(f->header, data_hash_chain_depth) &&
            le64toh(f->header->data_hash_chain_depth) > HASH_CHAIN_DEPTH_MAX) {
                log_ratelimit_full(
                        log_level, JOURNAL_LOG_RATELIMIT,
                        "Data hash table of %s has deepest hash chain of length %" PRIu64 ", suggesting rotation.",
                        f->path, le64toh(f->header->data_hash_chain_depth));
                return true;
        }

        if (JOURNAL_HEADER_CONTAINS(f->header, field_hash_chain_depth) &&
            le64toh(f->header->field_hash_chain_depth) > HASH_CHAIN_DEPTH_MAX) {
                log_ratelimit_full(
                        log_level, JOURNAL_LOG_RATELIMIT,
                        "Field hash table of %s has deepest hash chain of length at %" PRIu64 ", suggesting rotation.",
                        f->path, le64toh(f->header->field_hash_chain_depth));
                return true;
        }

        /* Are the data objects properly indexed by field objects? */
        if (JOURNAL_HEADER_CONTAINS(f->header, n_data) &&
            JOURNAL_HEADER_CONTAINS(f->header, n_fields) &&
            le64toh(f->header->n_data) > 0 &&
            le64toh(f->header->n_fields) == 0) {
                log_ratelimit_full(
                        log_level, JOURNAL_LOG_RATELIMIT,
                        "Data objects of %s are not indexed by field objects, suggesting rotation.",
                        f->path);
                return true;
        }

        if (max_file_usec > 0) {
                usec_t t, h;

                h = le64toh(f->header->head_entry_realtime);
                t = now(CLOCK_REALTIME);

                if (h > 0 && t > h + max_file_usec) {
                        log_ratelimit_full(
                                log_level, JOURNAL_LOG_RATELIMIT,
                                "Oldest entry in %s is older than the configured file retention duration (%s), suggesting rotation.",
                                f->path, FORMAT_TIMESPAN(max_file_usec, USEC_PER_SEC));
                        return true;
                }
        }

        return false;
}

static const char * const journal_object_type_table[] = {
        [OBJECT_UNUSED] = "unused",
        [OBJECT_DATA] = "data",
        [OBJECT_FIELD] = "field",
        [OBJECT_ENTRY] = "entry",
        [OBJECT_DATA_HASH_TABLE] = "data hash table",
        [OBJECT_FIELD_HASH_TABLE] = "field hash table",
        [OBJECT_ENTRY_ARRAY] = "entry array",
        [OBJECT_TAG] = "tag",
};

DEFINE_STRING_TABLE_LOOKUP_TO_STRING(journal_object_type, ObjectType);
