journal-file.c revision 2a59ea54f136f8fcf6a4e1bdfc51448c81281a3e
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer This file is part of systemd.
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer Copyright 2011 Lennart Poettering
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer systemd is free software; you can redistribute it and/or modify it
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer under the terms of the GNU General Public License as published by
4be4833ece2856e0cacc09f8f8b2c02b320751faMartin Pitt the Free Software Foundation; either version 2 of the License, or
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier (at your option) any later version.
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier systemd is distributed in the hope that it will be useful, but
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier WITHOUT ANY WARRANTY; without even the implied warranty of
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier General Public License for more details.
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier You should have received a copy of the GNU General Public License
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier along with systemd; If not, see <http://www.gnu.org/licenses/>.
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#define DEFAULT_DATA_HASH_TABLE_SIZE (2047ULL*16ULL)
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#define DEFAULT_FIELD_HASH_TABLE_SIZE (2047ULL*16ULL)
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#define DEFAULT_WINDOW_SIZE (128ULL*1024ULL*1024ULL)
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalierstatic const char signature[] = { 'L', 'P', 'K', 'S', 'H', 'H', 'R', 'H' };
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier for (t = 0; t < _WINDOW_MAX; t++)
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier munmap(f->windows[t].ptr, f->windows[t].size);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic int journal_file_init_header(JournalFile *f, JournalFile *template) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier h.arena_offset = htole64(ALIGN64(sizeof(h)));
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (k != sizeof(h))
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic int journal_file_refresh_header(JournalFile *f) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_id128_get_machine(&f->header->machine_id);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (sd_id128_equal(boot_id, f->header->boot_id))
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic int journal_file_verify_header(JournalFile *f) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if ((le64toh(f->header->incompatible_flags) & ~HEADER_INCOMPATIBLE_COMPRESSED) != 0)
b8667ee4162cd2510363602b417cecede9fd2ccaZbigniew Jędrzejewski-Szmek if (f->header->incompatible_flags != 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if ((uint64_t) f->last_stat.st_size < (le64toh(f->header->arena_offset) + le64toh(f->header->arena_size)))
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!sd_id128_equal(machine_id, f->header->machine_id))
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_debug("Journal file %s is already online. Assuming unclean closing. Ignoring.", f->path);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_debug("Journal file %s has unknown state %u. Ignoring.", f->path, state);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* We assume that this file is not sparse, and we know that
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * for sure, since we always call posix_fallocate()
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * ourselves */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (new_size < le64toh(f->header->arena_offset))
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier new_size = le64toh(f->header->arena_offset);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* Note that the glibc fallocate() fallback is very
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier inefficient, hence we try to minimize the allocation area
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier as we can. */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (posix_fallocate(f->fd, old_size, new_size - old_size) < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier f->header->arena_size = new_size - htole64(f->header->arena_offset);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier woffset = offset & ~((uint64_t) page_size() - 1ULL);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* Avoid SIGBUS on invalid accesses */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (woffset + wsize > (uint64_t) PAGE_ALIGN(f->last_stat.st_size))
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier window = mmap(NULL, wsize, f->prot, MAP_SHARED, f->fd, woffset);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier *ret = (uint8_t*) window + (offset - woffset);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic int journal_file_move_to(JournalFile *f, int wt, uint64_t offset, uint64_t size, void **ret) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier *ret = (uint8_t*) w->ptr + (offset - w->offset);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* If the default window size is larger then what was
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * asked for extend the mapping a bit in the hope to
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * minimize needed remappings later on. We add half
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * the window space before and half behind the
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * requested mapping */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier delta = PAGE_ALIGN((DEFAULT_WINDOW_SIZE - size) / 2);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (offset > (uint64_t) f->last_stat.st_size)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (offset + size > (uint64_t) f->last_stat.st_size)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer size = PAGE_ALIGN((uint64_t) f->last_stat.st_size - offset);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (o->object.type == OBJECT_DATA && !(o->object.flags & OBJECT_COMPRESSED)) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer h2 = hash64(o->data.payload, le64toh(o->object.size) - offsetof(Object, data.payload));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer h2 = hash64(o->field.payload, le64toh(o->object.size) - offsetof(Object, field.payload));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return true;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerint journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Object **ret) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = journal_file_move_to(f, type >= 0 ? type : WINDOW_UNKNOWN, offset, sizeof(ObjectHeader), &t);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (s < sizeof(ObjectHeader))
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (s > sizeof(ObjectHeader)) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = journal_file_move_to(f, o->object.type, offset, s, &t);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic uint64_t journal_file_seqnum(JournalFile *f, uint64_t *seqnum) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* If an external seqnum counter was passed, we update
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * both the local and the external one, and set it to
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * the maximum of both */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int journal_file_append_object(JournalFile *f, int type, uint64_t size, Object **ret, uint64_t *offset) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = journal_file_move_to_object(f, -1, p, &tail);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = journal_file_move_to(f, type, p, size, &t);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer f->header->n_objects = htole64(le64toh(f->header->n_objects) + 1);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int journal_file_setup_data_hash_table(JournalFile *f) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer f->header->data_hash_table_offset = htole64(p + offsetof(Object, hash_table.items));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int journal_file_setup_field_hash_table(JournalFile *f) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer f->header->field_hash_table_offset = htole64(p + offsetof(Object, hash_table.items));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int journal_file_map_data_hash_table(JournalFile *f) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer p = le64toh(f->header->data_hash_table_offset);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int journal_file_map_field_hash_table(JournalFile *f) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer p = le64toh(f->header->field_hash_table_offset);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int journal_file_link_data(JournalFile *f, Object *o, uint64_t offset, uint64_t hash) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer o->data.next_hash_offset = o->data.next_field_offset = 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer o->data.entry_offset = o->data.entry_array_offset = 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer h = hash % (le64toh(f->header->data_hash_table_size) / sizeof(HashItem));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer p = le64toh(f->data_hash_table[h].head_hash_offset);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (p == 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* Only entry in the hash table is easy */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer f->data_hash_table[h].head_hash_offset = htole64(offset);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* Temporarily move back to the previous data object,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * to patch in pointer */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = journal_file_move_to_object(f, OBJECT_DATA, offset, &o);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer f->data_hash_table[h].tail_hash_offset = htole64(offset);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const void *data, uint64_t size, uint64_t hash,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer h = hash % (le64toh(f->header->data_hash_table_size) / sizeof(HashItem));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer p = le64toh(f->data_hash_table[h].head_hash_offset);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer while (p > 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!uncompress_blob(o->data.payload, l, &f->compress_buffer, &f->compress_buffer_size, &rsize))
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return journal_file_find_data_object_with_hash(f,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int journal_file_append_data(JournalFile *f, const void *data, uint64_t size, Object **ret, uint64_t *offset) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = journal_file_find_data_object_with_hash(f, data, size, hash, &o, &p);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer else if (r > 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = journal_file_append_object(f, OBJECT_DATA, osize, &o, &p);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer compressed = compress_blob(data, size, o->data.payload, &rsize);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer o->object.size = htole64(offsetof(Object, data.payload) + rsize);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer f->header->incompatible_flags = htole32(le32toh(f->header->incompatible_flags) | HEADER_INCOMPATIBLE_COMPRESSED);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_debug("Compressed data object %lu -> %lu", (unsigned long) size, (unsigned long) rsize);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyeruint64_t journal_file_entry_n_items(Object *o) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(o->object.type == htole64(OBJECT_ENTRY));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return (le64toh(o->object.size) - offsetof(Object, entry.items)) / sizeof(EntryItem);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic uint64_t journal_file_entry_array_n_items(Object *o) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(o->object.type == htole64(OBJECT_ENTRY_ARRAY));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return (le64toh(o->object.size) - offsetof(Object, entry_array.items)) / sizeof(uint64_t);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int link_entry_into_array(JournalFile *f,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer while (a > 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (i < n) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer a = le64toh(o->entry_array.next_entry_array_offset);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = journal_file_append_object(f, OBJECT_ENTRY_ARRAY,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer offsetof(Object, entry_array.items) + n * sizeof(uint64_t),
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, ap, &o);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer o->entry_array.next_entry_array_offset = htole64(q);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int link_entry_into_array_plus_one(JournalFile *f,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int journal_file_link_entry_item(JournalFile *f, Object *o, uint64_t offset, uint64_t i) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerstatic int journal_file_link_entry(JournalFile *f, Object *o, uint64_t offset) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer /* Link up the entry itself */
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_error("=> %s seqnr=%lu n_entries=%lu", f->path, (unsigned long) o->entry.seqnum, (unsigned long) f->header->n_entries);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer f->header->head_entry_realtime = o->entry.realtime;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer f->header->tail_entry_realtime = o->entry.realtime;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer f->header->tail_entry_monotonic = o->entry.monotonic;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer /* Link up the items */
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer for (i = 0; i < n; i++) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = journal_file_link_entry_item(f, o, offset, i);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer osize = offsetof(Object, entry.items) + (n_items * sizeof(EntryItem));
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = journal_file_append_object(f, OBJECT_ENTRY, osize, &o, &np);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer o->entry.seqnum = htole64(journal_file_seqnum(f, seqnum));
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer memcpy(o->entry.items, items, n_items * sizeof(EntryItem));
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerstatic void journal_file_post_change(JournalFile *f) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer /* inotify() does not receive IN_MODIFY events from file
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer * accesses done via mmap(). After each access we hence
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer * trigger IN_MODIFY by truncating the journal file to its
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer * current size which triggers IN_MODIFY. */
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (ftruncate(f->fd, f->last_stat.st_size) < 0)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_error("Failed to to truncate file to its own size: %m");
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerint journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const struct iovec iovec[], unsigned n_iovec, uint64_t *seqnum, Object **ret, uint64_t *offset) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer ts->monotonic < le64toh(f->header->tail_entry_monotonic))
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (ts->realtime < le64toh(f->header->tail_entry_realtime))
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer for (i = 0; i < n_iovec; i++) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = journal_file_append_data(f, iovec[i].iov_base, iovec[i].iov_len, &o, &p);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = journal_file_append_entry_internal(f, ts, xor_hash, items, n_iovec, seqnum, ret, offset);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer while (a > 0) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (i < n) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer a = le64toh(o->entry_array.next_entry_array_offset);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (a <= 0 || p <= 0)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerstatic int generic_array_get_plus_one(JournalFile *f,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (i == 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = journal_file_move_to_object(f, OBJECT_ENTRY, extra, &o);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return generic_array_get(f, first, i-1, ret, offset);
1ecf6a2b4960229ad1d06c591b4776ddf065e834Harald Hoyer int (*test_object)(JournalFile *f, uint64_t p, uint64_t needle),
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer while (a > 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &array);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = direction == DIRECTION_DOWN ? TEST_RIGHT : TEST_LEFT;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = direction == DIRECTION_DOWN ? TEST_RIGHT : TEST_LEFT;
if (subtract_one && t == 0 && i == 0)
if (subtract_one && i == 0)
p = last_p;
else if (subtract_one)
if (ret)
*ret = o;
if (offset)
*offset = p;
if (idx)
uint64_t n,
assert(f);
else if (r == TEST_FOUND) {
Object *o;
if (ret)
*ret = o;
if (offset)
if (idx)
*idx = 0;
} else if (r == TEST_RIGHT)
(*idx) ++;
Object *o;
assert(f);
assert(p > 0);
return TEST_FOUND;
return TEST_LEFT;
return TEST_RIGHT;
JournalFile *f,
return generic_array_bisect(f,
Object *o;
assert(f);
assert(p > 0);
return TEST_FOUND;
return TEST_LEFT;
return TEST_RIGHT;
JournalFile *f,
return generic_array_bisect(f,
Object *o;
assert(f);
assert(p > 0);
return TEST_FOUND;
return TEST_LEFT;
return TEST_RIGHT;
JournalFile *f,
Object *o;
return -ENOENT;
return generic_array_bisect_plus_one(f,
assert(f);
assert(p > 0);
if (p == needle)
return TEST_FOUND;
else if (p < needle)
return TEST_LEFT;
return TEST_RIGHT;
JournalFile *f,
uint64_t i, n;
assert(f);
assert(p > 0 || !o);
return -EINVAL;
r = generic_array_bisect(f,
return generic_array_get(f,
JournalFile *f,
uint64_t i, n;
assert(f);
assert(o);
assert(p > 0);
return -EINVAL;
r = generic_array_bisect(f,
if (skip < 0) {
return -EBADMSG;
return generic_array_get(f,
JournalFile *f,
uint64_t n, i;
Object *d;
assert(f);
assert(p > 0 || !o);
return -EINVAL;
return generic_array_get_plus_one(f,
JournalFile *f,
Object *d;
return generic_array_bisect_plus_one(f,
JournalFile *f,
Object *d;
return generic_array_bisect_plus_one(f,
Object *o;
uint64_t p;
assert(f);
f->path,
goto fail;
case OBJECT_UNUSED:
case OBJECT_DATA:
case OBJECT_ENTRY:
case OBJECT_FIELD_HASH_TABLE:
case OBJECT_DATA_HASH_TABLE:
case OBJECT_ENTRY_ARRAY:
fail:
int journal_file_open(
const char *fname,
int flags,
JournalFile *f;
bool newly_created = false;
return -EINVAL;
return -ENOMEM;
if (!f->path) {
r = -ENOMEM;
goto fail;
if (f->fd < 0) {
r = -errno;
goto fail;
r = -errno;
goto fail;
newly_created = true;
goto fail;
r = -errno;
goto fail;
r = -EIO;
goto fail;
r = -errno;
goto fail;
if (!newly_created) {
r = journal_file_verify_header(f);
goto fail;
if (f->writable) {
r = journal_file_refresh_header(f);
goto fail;
if (newly_created) {
goto fail;
goto fail;
goto fail;
r = journal_file_map_data_hash_table(f);
goto fail;
if (ret)
*ret = f;
fail:
size_t l;
assert(f);
assert(*f);
old_file = *f;
return -EINVAL;
return -EINVAL;
return -ENOMEM;
free(p);
return -errno;
*f = new_file;
struct vacuum_info {
char *filename;
const struct vacuum_info *a, *b;
a = _a;
b = _b;
DIR *d;
if (max_use <= 0)
return -errno;
size_t q;
goto finish;
if (!de)
r = -ENOMEM;
goto finish;
free(p);
free(p);
struct vacuum_info *j;
free(p);
r = -ENOMEM;
goto finish;
list = j;
n_list ++;
for(i = 0; i < n_list; i++) {
r = -errno;
goto finish;
for (i = 0; i < n_list; i++)
closedir(d);