diff options
-rw-r--r-- | qcow/src/qcow.rs | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/qcow/src/qcow.rs b/qcow/src/qcow.rs index 640f469..6373d01 100644 --- a/qcow/src/qcow.rs +++ b/qcow/src/qcow.rs @@ -388,7 +388,7 @@ impl QcowFile { let l2_entries = cluster_size / size_of::<u64>() as u64; - let qcow = QcowFile { + let mut qcow = QcowFile { raw_file, header, l1_table, @@ -410,6 +410,8 @@ impl QcowFile { .checked_add(u64::from(qcow.header.refcount_table_clusters) * cluster_size) .ok_or(Error::InvalidRefcountTableOffset)?; + qcow.find_avail_clusters()?; + Ok(qcow) } @@ -517,6 +519,29 @@ impl QcowFile { Ok(None) } + fn find_avail_clusters(&mut self) -> Result<()> { + let cluster_size = self.raw_file.cluster_size(); + + let file_size = self + .raw_file + .file_mut() + .metadata() + .map_err(Error::GettingFileSize)? + .len(); + + for i in (0..file_size).step_by(cluster_size as usize) { + let refcount = self + .refcounts + .get_cluster_refcount(&mut self.raw_file, i) + .map_err(Error::GettingRefcount)?; + if refcount == 0 { + self.avail_clusters.push(i); + } + } + + Ok(()) + } + /// Rebuild the reference count tables. fn rebuild_refcounts(raw_file: &mut QcowRawFile, header: QcowHeader) -> Result<()> { fn add_ref(refcounts: &mut [u16], cluster_size: u64, cluster_address: u64) -> Result<()> { |