Write the updated reference count blocks and reftable.
(
refcounts: &[u64],
mut header: QcowHeader,
ref_table: &[u64],
raw_file: &mut QcowRawFile,
refcount_block_entries: u64,
)
| 1200 | |
| 1201 | // Write the updated reference count blocks and reftable. |
| 1202 | fn write_refblocks( |
| 1203 | refcounts: &[u64], |
| 1204 | mut header: QcowHeader, |
| 1205 | ref_table: &[u64], |
| 1206 | raw_file: &mut QcowRawFile, |
| 1207 | refcount_block_entries: u64, |
| 1208 | ) -> Result<()> { |
| 1209 | // Rewrite the header with lazy refcounts enabled while we are rebuilding the tables. |
| 1210 | header.compatible_features |= COMPATIBLE_FEATURES_LAZY_REFCOUNTS; |
| 1211 | raw_file.file_mut().rewind().map_err(Error::SeekingFile)?; |
| 1212 | header.write_to(raw_file.file_mut())?; |
| 1213 | |
| 1214 | for (i, refblock_addr) in ref_table.iter().enumerate() { |
| 1215 | // Write a block of refcounts to the location indicated by refblock_addr. |
| 1216 | let refblock_start = i * (refcount_block_entries as usize); |
| 1217 | let refblock_end = min( |
| 1218 | refcounts.len(), |
| 1219 | refblock_start + refcount_block_entries as usize, |
| 1220 | ); |
| 1221 | let refblock = &refcounts[refblock_start..refblock_end]; |
| 1222 | raw_file |
| 1223 | .write_refcount_block(*refblock_addr, refblock) |
| 1224 | .map_err(Error::WritingHeader)?; |
| 1225 | |
| 1226 | // If this is the last (partial) cluster, pad it out to a full refblock cluster. |
| 1227 | if refblock.len() < refcount_block_entries as usize { |
| 1228 | let refblock_padding = |
| 1229 | vec![0u64; refcount_block_entries as usize - refblock.len()]; |
| 1230 | let byte_offset = |
| 1231 | refblock.len() as u64 * raw_file.cluster_size() / refcount_block_entries; |
| 1232 | raw_file |
| 1233 | .write_refcount_block(*refblock_addr + byte_offset, &refblock_padding) |
| 1234 | .map_err(Error::WritingHeader)?; |
| 1235 | } |
| 1236 | } |
| 1237 | |
| 1238 | // Rewrite the top-level refcount table. |
| 1239 | raw_file |
| 1240 | .write_pointer_table_direct(header.refcount_table_offset, ref_table.iter()) |
| 1241 | .map_err(Error::WritingHeader)?; |
| 1242 | |
| 1243 | // Rewrite the header again, now with lazy refcounts disabled. |
| 1244 | header.compatible_features &= !COMPATIBLE_FEATURES_LAZY_REFCOUNTS; |
| 1245 | raw_file.file_mut().rewind().map_err(Error::SeekingFile)?; |
| 1246 | header.write_to(raw_file.file_mut())?; |
| 1247 | |
| 1248 | Ok(()) |
| 1249 | } |
| 1250 | |
| 1251 | let cluster_size = raw_file.cluster_size(); |
| 1252 |
nothing calls this directly
no test coverage detected