static int vhd_journal_add_journal_header(vhd_journal_t *j) { int err; off64_t off; vhd_context_t *vhd; vhd = &j->vhd; memset(&j->header, 0, sizeof(vhd_journal_header_t)); err = vhd_seek(vhd, 0, SEEK_END); if (err) return err; off = vhd_position(vhd); if (off == (off64_t)-1) return -errno; err = vhd_get_footer(vhd); if (err) return err; uuid_copy(j->header.uuid, vhd->footer.uuid); memcpy(j->header.cookie, VHD_JOURNAL_HEADER_COOKIE, sizeof(j->header.cookie)); j->header.vhd_footer_offset = off - sizeof(vhd_footer_t); j->header.journal_eof = sizeof(vhd_journal_header_t); return vhd_journal_write_header(j, &j->header); }
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; }
/* * commit indicates the transaction completed * successfully and we can remove the undo log */ int vhd_journal_commit(vhd_journal_t *j) { int err; j->header.journal_data_entries = 0; j->header.journal_metadata_entries = 0; j->header.journal_data_offset = 0; j->header.journal_metadata_offset = 0; err = vhd_journal_write_header(j, &j->header); if (err) return err; if (!j->is_block) err = vhd_journal_truncate(j, sizeof(vhd_journal_header_t)); if (err) return -errno; return 0; }
static int vhd_journal_add_metadata(vhd_journal_t *j) { int err; off_t eof; vhd_context_t *vhd; vhd = &j->vhd; err = vhd_journal_add_footer(j); if (err) return err; if (!vhd_type_dynamic(vhd)) return 0; err = vhd_journal_add_header(j); if (err) return err; err = vhd_journal_add_locators(j); if (err) return err; err = vhd_journal_add_bat(j); if (err) return err; if (vhd_has_batmap(vhd)) { err = vhd_journal_add_batmap(j); if (err) return err; } j->header.journal_data_offset = j->header.journal_eof; return vhd_journal_write_header(j, &j->header); }