sz = le64toh(READ_NOW(o->object.size));
if (sz < offsetof(Object, entry.items) ||
- (sz - offsetof(Object, entry.items)) % sizeof(EntryItem) != 0)
+ (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)) / sizeof(EntryItem) <= 0)
+ 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)) / sizeof(EntryItem),
+ (sz - offsetof(Object, entry.items)) / journal_file_entry_item_size(f),
offset);
if (le64toh(o->entry.seqnum) <= 0)
return 0;
}
-uint64_t journal_file_entry_n_items(Object *o) {
+uint64_t journal_file_entry_n_items(JournalFile *f, Object *o) {
uint64_t sz;
+
+ assert(f);
assert(o);
if (o->object.type != OBJECT_ENTRY)
if (sz < offsetof(Object, entry.items))
return 0;
- return (sz - offsetof(Object, entry.items)) / sizeof(EntryItem);
+ return (sz - offsetof(Object, entry.items)) / journal_file_entry_item_size(f);
}
uint64_t journal_file_entry_array_n_items(JournalFile *f, Object *o) {
return 0;
}
-static int journal_file_link_entry_item(JournalFile *f, Object *o, uint64_t offset, uint64_t i) {
- uint64_t p;
+static int journal_file_link_entry_item(JournalFile *f, Object *o, uint64_t offset, uint64_t p) {
int r;
assert(f);
assert(o);
assert(offset > 0);
- p = le64toh(o->entry.items[i].object_offset);
r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
if (r < 0)
return r;
offset);
}
-static int journal_file_link_entry(JournalFile *f, Object *o, uint64_t offset) {
- uint64_t n;
+static int journal_file_link_entry(
+ JournalFile *f,
+ Object *o,
+ uint64_t offset,
+ const EntryItem items[],
+ size_t n_items) {
+
int r;
assert(f);
f->header->tail_entry_monotonic = o->entry.monotonic;
/* Link up the items */
- n = journal_file_entry_n_items(o);
- for (uint64_t i = 0; i < n; i++) {
+ 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, o, offset, i);
+ k = journal_file_link_entry_item(f, o, offset, items[i].object_offset);
if (k == -E2BIG)
r = k;
else if (k < 0)
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[], unsigned n_items,
+ const EntryItem items[], size_t n_items,
uint64_t *seqnum,
Object **ret, uint64_t *ret_offset) {
uint64_t np;
assert(items || n_items == 0);
assert(ts);
- osize = offsetof(Object, entry.items) + (n_items * sizeof(EntryItem));
+ 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));
- memcpy_safe(o->entry.items, items, n_items * sizeof(EntryItem));
o->entry.realtime = htole64(ts->realtime);
o->entry.monotonic = htole64(ts->monotonic);
o->entry.xor_hash = htole64(xor_hash);
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);
+ r = journal_file_link_entry(f, o, np, items, n_items);
if (r < 0)
return r;
}
static int entry_item_cmp(const EntryItem *a, const EntryItem *b) {
- return CMP(le64toh(a->object_offset), le64toh(b->object_offset));
+ return CMP(a->object_offset, b->object_offset);
}
static size_t remove_duplicate_entry_items(EntryItem items[], size_t n) {
-
- /* This function relies on the items array being sorted. */
size_t j = 1;
if (n <= 1)
xor_hash ^= le64toh(o->data.hash);
items[i] = (EntryItem) {
- .object_offset = htole64(p),
- .hash = o->data.hash,
+ .object_offset = p,
+ .hash = le64toh(o->data.hash),
};
}
};
boot_id = &o->entry.boot_id;
- n = journal_file_entry_n_items(o);
+ n = journal_file_entry_n_items(from, o);
items = newa(EntryItem, n);
for (uint64_t i = 0; i < n; i++) {
void *data;
Object *u;
- q = le64toh(o->entry.items[i].object_offset);
+ q = journal_file_entry_item_object_offset(from, o, i);
r = journal_file_move_to_object(from, OBJECT_DATA, q, &o);
if (r < 0)
xor_hash ^= le64toh(u->data.hash);
items[i] = (EntryItem) {
- .object_offset = htole64(h),
- .hash = u->data.hash,
+ .object_offset = h,
+ .hash = le64toh(u->data.hash),
};
r = journal_file_move_to_object(from, OBJECT_ENTRY, p, &o);
}
case OBJECT_ENTRY:
- if ((le64toh(o->object.size) - offsetof(Object, entry.items)) % sizeof(EntryItem) != 0) {
+ if ((le64toh(o->object.size) - offsetof(Object, entry.items)) % journal_file_entry_item_size(f) != 0) {
error(offset,
"Bad entry size (<= %zu): %"PRIu64,
offsetof(Object, entry.items),
return -EBADMSG;
}
- if ((le64toh(o->object.size) - offsetof(Object, entry.items)) / sizeof(EntryItem) <= 0) {
+ if ((le64toh(o->object.size) - offsetof(Object, entry.items)) / journal_file_entry_item_size(f) <= 0) {
error(offset,
"Invalid number items in entry: %"PRIu64,
- (le64toh(o->object.size) - offsetof(Object, entry.items)) / sizeof(EntryItem));
+ (le64toh(o->object.size) - offsetof(Object, entry.items)) / journal_file_entry_item_size(f));
return -EBADMSG;
}
return -EBADMSG;
}
- for (uint64_t i = 0; i < journal_file_entry_n_items(o); i++) {
- if (le64toh(o->entry.items[i].object_offset) == 0 ||
- !VALID64(le64toh(o->entry.items[i].object_offset))) {
+ for (uint64_t i = 0; i < journal_file_entry_n_items(f, o); i++) {
+ if (journal_file_entry_item_object_offset(f, o, i) == 0 ||
+ !VALID64(journal_file_entry_item_object_offset(f, o, i))) {
error(offset,
"Invalid entry item (%"PRIu64"/%"PRIu64") offset: "OFSfmt,
- i, journal_file_entry_n_items(o),
- le64toh(o->entry.items[i].object_offset));
+ i, journal_file_entry_n_items(f, o),
+ journal_file_entry_item_object_offset(f, o, i));
return -EBADMSG;
}
}
assert(o);
assert(cache_data_fd);
- n = journal_file_entry_n_items(o);
+ n = journal_file_entry_n_items(f, o);
for (i = 0; i < n; i++) {
uint64_t q;
Object *u;
- q = le64toh(o->entry.items[i].object_offset);
+ q = journal_file_entry_item_object_offset(f, o, i);
if (!contains_uint64(cache_data_fd, n_data, q)) {
error(p, "Invalid data object of entry");
field_length = strlen(field);
- uint64_t n = journal_file_entry_n_items(o);
+ uint64_t n = journal_file_entry_n_items(f, o);
for (uint64_t i = 0; i < n; i++) {
Object *d;
uint64_t p, l;
size_t t;
Compression c;
- p = le64toh(o->entry.items[i].object_offset);
+ p = journal_file_entry_item_object_offset(f, o, i);
r = journal_file_move_to_object(f, OBJECT_DATA, p, &d);
if (IN_SET(r, -EADDRNOTAVAIL, -EBADMSG)) {
log_debug_errno(r, "Entry item %"PRIu64" data object is bad, skipping over it: %m", i);
if (r < 0)
return r;
- for (uint64_t n = journal_file_entry_n_items(o); j->current_field < n; j->current_field++) {
+ for (uint64_t n = journal_file_entry_n_items(f, o); j->current_field < n; j->current_field++) {
uint64_t p;
- p = le64toh(o->entry.items[j->current_field].object_offset);
+ p = journal_file_entry_item_object_offset(f, o, j->current_field);
r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
if (IN_SET(r, -EADDRNOTAVAIL, -EBADMSG)) {
log_debug_errno(r, "Entry item %"PRIu64" data object is bad, skipping over it: %m", j->current_field);