diff options
author | Daniel Verkamp <dverkamp@chromium.org> | 2018-09-27 09:34:59 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-09-27 19:44:09 -0700 |
commit | 46f70e8c1679e0758683112db45fec590beb5b5b (patch) | |
tree | 3cc425784407ad13a5bf95d20effe37790237507 /qcow/src/refcount.rs | |
parent | eaaf3e17e68e2a08012b23adb99b2a80b14a21f5 (diff) | |
download | crosvm-46f70e8c1679e0758683112db45fec590beb5b5b.tar crosvm-46f70e8c1679e0758683112db45fec590beb5b5b.tar.gz crosvm-46f70e8c1679e0758683112db45fec590beb5b5b.tar.bz2 crosvm-46f70e8c1679e0758683112db45fec590beb5b5b.tar.lz crosvm-46f70e8c1679e0758683112db45fec590beb5b5b.tar.xz crosvm-46f70e8c1679e0758683112db45fec590beb5b5b.tar.zst crosvm-46f70e8c1679e0758683112db45fec590beb5b5b.zip |
qcow: optimize sync_caches to avoid extra writes
Track the clean/dirty state of the L1 table and the refcount table to avoid writing them out and doing an extra fsyncdata() if nothing has changed. BUG=None TEST=Manually verify strace output contains only the expected fsyncs Change-Id: I20bdd250024039a5b4142605462a8977ced1efcc Signed-off-by: Daniel Verkamp <dverkamp@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1247442 Reviewed-by: Dylan Reid <dgreid@chromium.org>
Diffstat (limited to 'qcow/src/refcount.rs')
-rw-r--r-- | qcow/src/refcount.rs | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/qcow/src/refcount.rs b/qcow/src/refcount.rs index 96b5e0c..13906a1 100644 --- a/qcow/src/refcount.rs +++ b/qcow/src/refcount.rs @@ -29,7 +29,7 @@ pub type Result<T> = std::result::Result<T, Error>; /// Represents the refcount entries for an open qcow file. #[derive(Debug)] pub struct RefCount { - ref_table: Vec<u64>, + ref_table: VecCache<u64>, refcount_table_offset: u64, refblock_cache: CacheMap<VecCache<u16>>, refcount_block_entries: u64, // number of refcounts in a cluster. @@ -48,8 +48,11 @@ impl RefCount { refcount_block_entries: u64, cluster_size: u64, ) -> io::Result<RefCount> { - let ref_table = - raw_file.read_pointer_table(refcount_table_offset, refcount_table_entries, None)?; + let ref_table = VecCache::from_vec(raw_file.read_pointer_table( + refcount_table_offset, + refcount_table_entries, + None, + )?); Ok(RefCount { ref_table, refcount_table_offset, @@ -134,8 +137,19 @@ impl RefCount { } /// Flush the refcount table that keeps the address of the refcounts blocks. - pub fn flush_table(&mut self, raw_file: &mut QcowRawFile) -> io::Result<()> { - raw_file.write_pointer_table(self.refcount_table_offset, &self.ref_table, 0) + /// Returns true if the table changed since the previous `flush_table()` call. + pub fn flush_table(&mut self, raw_file: &mut QcowRawFile) -> io::Result<bool> { + if self.ref_table.dirty() { + raw_file.write_pointer_table( + self.refcount_table_offset, + &self.ref_table.get_values(), + 0, + )?; + self.ref_table.mark_clean(); + Ok(true) + } else { + Ok(false) + } } /// Gets the refcount for a cluster with the given address. @@ -167,7 +181,7 @@ impl RefCount { /// Returns the refcount table for this file. This is only useful for debugging. pub fn ref_table(&self) -> &[u64] { - &self.ref_table + &self.ref_table.get_values() } /// Returns the refcounts stored in the given block. |