assert(offset > 0);
assert(o->object.type == OBJECT_DATA);
+ /* 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;
/* Only entry in the hash table is easy */
f->data_hash_table[h].head_hash_offset = htole64(offset);
} else {
- /* Temporarily move back to the previous data object,
- * to patch in pointer */
+ /* 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);
-
- r = journal_file_move_to_object(f, OBJECT_DATA, offset, &o);
- if (r < 0)
- return r;
}
f->data_hash_table[h].tail_hash_offset = htole64(offset);
JournalFile *f,
const void *data, uint64_t size, uint64_t hash,
Object **ret, uint64_t *offset) {
+
uint64_t p, osize, h;
int r;
ret, offset);
}
-static int journal_file_append_data(JournalFile *f, const void *data, uint64_t size, Object **ret, uint64_t *offset) {
+static int journal_file_append_data(
+ JournalFile *f,
+ const void *data, uint64_t size,
+ Object **ret, uint64_t *offset) {
+
uint64_t hash, p;
uint64_t osize;
Object *o;
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 (ret)
*ret = o;
uint64_t journal_file_entry_n_items(Object *o) {
assert(o);
- assert(o->object.type == htole64(OBJECT_ENTRY));
+ assert(o->object.type == OBJECT_ENTRY);
return (le64toh(o->object.size) - offsetof(Object, entry.items)) / sizeof(EntryItem);
}
static uint64_t journal_file_entry_array_n_items(Object *o) {
assert(o);
- assert(o->object.type == htole64(OBJECT_ENTRY_ARRAY));
+ assert(o->object.type == OBJECT_ENTRY_ARRAY);
return (le64toh(o->object.size) - offsetof(Object, entry_array.items)) / sizeof(uint64_t);
}
o->entry_array.items[i] = htole64(p);
if (ap == 0)
- *first = q;
+ *first = htole64(q);
else {
r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, ap, &o);
if (r < 0)
else {
uint64_t i;
- i = le64toh(*idx) - 1;
+ i = htole64(le64toh(*idx) - 1);
r = link_entry_into_array(f, first, &i, p);
if (r < 0)
return r;
(flags & O_ACCMODE) != O_RDWR)
return -EINVAL;
+ if (!endswith(fname, ".journal"))
+ return -EINVAL;
+
f = new0(JournalFile, 1);
if (!f)
return -ENOMEM;
l = strlen(old_file->path);
- p = new(char, l + 1 + 16 + 1 + 32 + 1 + 16 + 1);
+ p = new(char, l + 1 + 32 + 1 + 16 + 1 + 16 + 1);
if (!p)
return -ENOMEM;
return r;
}
+int journal_file_open_reliably(
+ const char *fname,
+ int flags,
+ mode_t mode,
+ JournalFile *template,
+ JournalFile **ret) {
+
+ int r;
+ size_t l;
+ char *p;
+
+ r = journal_file_open(fname, flags, mode, template, ret);
+ if (r != -EBADMSG)
+ return r;
+
+ if ((flags & O_ACCMODE) == O_RDONLY)
+ return r;
+
+ if (!(flags & O_CREAT))
+ return r;
+
+ l = strlen(fname);
+ if (asprintf(&p, "%.*s@%016llx-%016llx.journal~",
+ (int) (l-8), fname,
+ (unsigned long long) now(CLOCK_REALTIME),
+ random_ull()) < 0)
+ return -ENOMEM;
+
+ r = rename(fname, p);
+ free(p);
+ if (r < 0)
+ return -errno;
+
+ log_warning("File %s corrupted, renaming and replacing.", fname);
+
+ return journal_file_open(fname, flags, mode, template, ret);
+}
+
struct vacuum_info {
off_t usage;
char *filename;