diff --git a/minivhd.c b/minivhd.c index 9f2a9f9..a56d1ec 100644 --- a/minivhd.c +++ b/minivhd.c @@ -565,34 +565,24 @@ int vhd_format_sectors(VHDMeta *vhdm, FILE *f, int offset, int nr_sectors) if (vhdm->type == VHD_DYNAMIC) { - int start_blk = offset / vhdm->sparse_spb; - int end_blk = (offset + (transfer_sectors - 1)) / vhdm->sparse_spb; int sbsz = vhdm->sparse_sb_sz / VHD_SECTOR_SZ; - /* Most common case. No need to access multiple data blocks. */ - if (start_blk == end_blk) + int prev_blk, curr_blk; + prev_blk = -1; + uint32_t s, ls, sib; + ls = offset + (transfer_sectors - 1); + for (s = offset; s <= ls; s++) { - uint32_t sib = offset % vhdm->sparse_spb; - if (vhdm->sparse_bat_arr[start_blk] != VHD_SPARSE_BLK) + curr_blk = s / vhdm->sparse_spb; + if (vhdm->sparse_bat_arr[curr_blk] != VHD_SPARSE_BLK) { - uint32_t file_sect_offs = vhdm->sparse_bat_arr[start_blk] + sbsz + sib; - fseeko64(f, (uint64_t)file_sect_offs * VHD_SECTOR_SZ, SEEK_SET); - fwrite(zero_buffer, transfer_sectors * VHD_SECTOR_SZ, 1, f); - } - } - else - { - uint32_t s, ls; - ls = offset + (transfer_sectors - 1); - for (s = offset; s <= ls; s++) - { - int blk = s / vhdm->sparse_spb; - uint32_t sib = s % vhdm->sparse_spb; - if (vhdm->sparse_bat_arr[blk] != VHD_SPARSE_BLK) + if (curr_blk != prev_blk) { - uint32_t file_sect_offs = vhdm->sparse_bat_arr[blk] + sbsz + sib; + sib = s % vhdm->sparse_spb; + uint32_t file_sect_offs = vhdm->sparse_bat_arr[curr_blk] + sbsz + sib; fseeko64(f, (uint64_t)file_sect_offs * VHD_SECTOR_SZ, SEEK_SET); - fwrite(zero_buffer, VHD_SECTOR_SZ, 1, f); + prev_blk = curr_blk; } + fwrite(zero_buffer, VHD_SECTOR_SZ, 1, f); } } }