diff --git a/block/src/qcow/metadata.rs b/block/src/qcow/metadata.rs index b4b64cabd..37bb7847b 100644 --- a/block/src/qcow/metadata.rs +++ b/block/src/qcow/metadata.rs @@ -333,11 +333,6 @@ impl QcowMetadata { pub fn cluster_size(&self) -> u64 { self.inner.read().unwrap().raw_file.cluster_size() } - - /// Returns the intra cluster byte offset for a given guest address. - pub fn cluster_offset(&self, address: u64) -> u64 { - self.inner.read().unwrap().raw_file.cluster_offset(address) - } } impl QcowState { diff --git a/block/src/qcow_async.rs b/block/src/qcow_async.rs index 308c2e27d..a0f470674 100644 --- a/block/src/qcow_async.rs +++ b/block/src/qcow_async.rs @@ -177,6 +177,7 @@ pub struct QcowAsync { alignment: usize, /// I/O alignment for the AsyncIo trait (at least SECTOR_SIZE). io_alignment: u64, + cluster_size: u64, io_uring: IoUring, eventfd: EventFd, completion_list: VecDeque<(u64, i32)>, @@ -197,6 +198,7 @@ impl QcowAsync { io_uring.submitter().register_eventfd(eventfd.as_raw_fd())?; Ok(QcowAsync { + cluster_size: metadata.cluster_size(), metadata, data_file, backing_file, @@ -296,6 +298,7 @@ impl AsyncIo for QcowAsync { &self.data_file, &self.backing_file, self.alignment, + self.cluster_size, )?; let total_len: usize = iovecs.iter().map(|v| v.iov_len).sum(); @@ -325,7 +328,7 @@ impl AsyncIo for QcowAsync { fn punch_hole(&mut self, offset: u64, length: u64, user_data: u64) -> AsyncIoResult<()> { let virtual_size = self.metadata.virtual_size(); - let cluster_size = self.metadata.cluster_size(); + let cluster_size = self.cluster_size; let result = self .metadata @@ -425,6 +428,7 @@ impl AsyncIo for QcowAsync { &self.data_file, &self.backing_file, self.alignment, + self.cluster_size, )?; sync_completions.push((req.user_data, total_len as i32)); } @@ -571,14 +575,14 @@ impl QcowAsync { data_file: &QcowRawFile, backing_file: &Option>, alignment: usize, + cluster_size: u64, ) -> AsyncIoResult<()> { let total_len: usize = iovecs.iter().map(|v| v.iov_len).sum(); - let cluster_size = metadata.cluster_size(); let mut buf_offset = 0usize; while buf_offset < total_len { let curr_addr = address + buf_offset as u64; - let intra_offset = metadata.cluster_offset(curr_addr); + let intra_offset = curr_addr & (cluster_size - 1); let remaining_in_cluster = (cluster_size - intra_offset) as usize; let count = min(total_len - buf_offset, remaining_in_cluster); diff --git a/block/src/qcow_sync.rs b/block/src/qcow_sync.rs index 44b8efaf5..fd2c61143 100644 --- a/block/src/qcow_sync.rs +++ b/block/src/qcow_sync.rs @@ -156,6 +156,7 @@ pub struct QcowSync { sparse: bool, /// O_DIRECT alignment requirement (0 = no alignment needed). alignment: usize, + cluster_size: u64, eventfd: EventFd, completion_list: VecDeque<(u64, i32)>, } @@ -169,6 +170,7 @@ impl QcowSync { ) -> Self { let alignment = data_file.file().alignment(); QcowSync { + cluster_size: metadata.cluster_size(), metadata, data_file, backing_file, @@ -278,9 +280,8 @@ impl AsyncIo for QcowSync { while buf_offset < total_len { let curr_addr = address + buf_offset as u64; - let cluster_size = self.metadata.cluster_size(); - let intra_offset = self.metadata.cluster_offset(curr_addr); - let remaining_in_cluster = (cluster_size - intra_offset) as usize; + let intra_offset = curr_addr & (self.cluster_size - 1); + let remaining_in_cluster = (self.cluster_size - intra_offset) as usize; let count = min(total_len - buf_offset, remaining_in_cluster); // Read backing data for COW if this is a partial cluster @@ -288,10 +289,10 @@ impl AsyncIo for QcowSync { let backing_data = if let Some(backing) = self .backing_file .as_ref() - .filter(|_| intra_offset != 0 || count < cluster_size as usize) + .filter(|_| intra_offset != 0 || count < self.cluster_size as usize) { let cluster_begin = curr_addr - intra_offset; - let mut data = vec![0u8; cluster_size as usize]; + let mut data = vec![0u8; self.cluster_size as usize]; backing .read_at(cluster_begin, &mut data) .map_err(AsyncIoError::WriteVectored)?; @@ -357,7 +358,7 @@ impl AsyncIo for QcowSync { fn punch_hole(&mut self, offset: u64, length: u64, user_data: u64) -> AsyncIoResult<()> { let virtual_size = self.metadata.virtual_size(); - let cluster_size = self.metadata.cluster_size(); + let cluster_size = self.cluster_size; let result = self .metadata