static int vhd_journal_write_header(vhd_journal_t *j, vhd_journal_header_t *header) { int err; size_t size; vhd_journal_header_t h; memcpy(&h, header, sizeof(vhd_journal_header_t)); err = vhd_journal_validate_header(j, &h); if (err) return err; vhd_journal_header_out(&h); size = sizeof(vhd_journal_header_t); err = vhd_journal_seek(j, 0, SEEK_SET); if (err) return err; err = vhd_journal_write(j, &h, size); if (err) return err; return 0; }
static int vhd_journal_update(vhd_journal_t *j, off_t offset, char *buf, size_t size, uint32_t type) { int err; off_t eof; uint64_t *off, off_bak; uint32_t *entries; vhd_journal_entry_t entry; entry.type = type; entry.size = size; entry.offset = offset; entry.cookie = VHD_JOURNAL_ENTRY_COOKIE; entry.checksum = vhd_journal_checksum_entry(&entry, buf, size); err = vhd_journal_seek(j, j->header.journal_eof, SEEK_SET); if (err) return err; err = vhd_journal_write_entry(j, &entry); if (err) goto fail; err = vhd_journal_write(j, buf, size); if (err) goto fail; if (type == VHD_JOURNAL_ENTRY_TYPE_DATA) { off = &j->header.journal_data_offset; entries = &j->header.journal_data_entries; } else { off = &j->header.journal_metadata_offset; entries = &j->header.journal_metadata_entries; } off_bak = *off; if (!(*entries)++) *off = j->header.journal_eof; j->header.journal_eof += (size + sizeof(vhd_journal_entry_t)); err = vhd_journal_write_header(j, &j->header); if (err) { if (!--(*entries)) *off = off_bak; j->header.journal_eof -= (size + sizeof(vhd_journal_entry_t)); goto fail; } return 0; fail: if (!j->is_block) vhd_journal_truncate(j, j->header.journal_eof); return err; }
static int vhd_journal_write_entry(vhd_journal_t *j, vhd_journal_entry_t *entry) { int err; vhd_journal_entry_t e; err = vhd_journal_validate_entry(entry); if (err) return err; memcpy(&e, entry, sizeof(vhd_journal_entry_t)); vhd_journal_entry_out(&e); err = vhd_journal_write(j, &e, sizeof(vhd_journal_entry_t)); if (err) return err; return 0; }