int get_header(server *srv, chunkqueue *cq, vhd_state_t *state, off_t *curr_off) { int err; vhd_context_t *vhd; off_t off; uint32_t vhd_blks; vhd = &state->vhd; off = vhd->footer.data_offset; err = fill(srv, cq, &vhd->header, sizeof(vhd_header_t), off, curr_off); if (err) return err; if (*curr_off < off + sizeof(vhd_header_t)) return 0; DEBUGLOG("s", "Header all in"); vhd_header_in(&vhd->header); err = vhd_validate_header(&vhd->header); if (err) { LOG("sd", "ERROR: VHD header invalid:", err); return err; } vhd->spb = vhd->header.block_size >> VHD_SECTOR_SHIFT; vhd->bm_secs = secs_round_up_no_zero(vhd->spb >> 3); vhd_blks = vhd->footer.curr_size >> VHD_BLOCK_SHIFT; vhd->bat.spb = vhd->header.block_size >> VHD_SECTOR_SHIFT; vhd->bat.entries = vhd_blks; LOG("sOsDsd", "VHD virt size:", vhd->footer.curr_size, "; blocks:", vhd_blks, "; max BAT size:", vhd->header.max_bat_size); if (vhd->header.max_bat_size < vhd_blks) { LOG("s", "ERROR: BAT smaller than VHD size!"); return -EINVAL; } state->bat_buf_size = vhd_bytes_padded(vhd_blks * sizeof(uint32_t)); err = posix_memalign((void **)&vhd->bat.bat, VHD_SECTOR_SIZE, state->bat_buf_size); if (err) { LOG("sd", "ERROR: failed to allocate BAT buffer:", err); return err; } state->curr_bitmap = malloc(vhd->bm_secs << VHD_SECTOR_SHIFT); if (!state->curr_bitmap) { LOG("sd", "ERROR: failed to allocate bitmap buffer!"); return -ENOMEM; } return 0; }
static int vhd_journal_read_header(vhd_journal_t *j, vhd_header_t *header) { int err; vhd_journal_entry_t entry; err = vhd_journal_read_entry(j, &entry); if (err) return err; if (entry.type != VHD_JOURNAL_ENTRY_TYPE_HEADER) return -EINVAL; if (entry.size != sizeof(vhd_header_t)) return -EINVAL; err = vhd_journal_read(j, header, entry.size); if (err) return err; vhd_header_in(header); return vhd_validate_header(header); }