diff --git a/virtio-devices/src/block_io_uring.rs b/virtio-devices/src/block_io_uring.rs index 131a5bff1..e1e2e5a17 100644 --- a/virtio-devices/src/block_io_uring.rs +++ b/virtio-devices/src/block_io_uring.rs @@ -11,7 +11,7 @@ use super::Error as DeviceError; use super::{ ActivateError, ActivateResult, EpollHelper, EpollHelperError, EpollHelperHandler, Queue, - VirtioDevice, VirtioDeviceType, VirtioInterruptType, EPOLL_HELPER_EVENT_LAST, + VirtioCommon, VirtioDevice, VirtioDeviceType, VirtioInterruptType, EPOLL_HELPER_EVENT_LAST, }; use crate::VirtioInterrupt; use anyhow::anyhow; @@ -300,13 +300,12 @@ impl EpollHelperHandler for BlockIoUringEpollHandler { /// Virtio device for exposing block level read/write operations on a host file. pub struct BlockIoUring { + common: VirtioCommon, id: String, kill_evt: Option, disk_image: File, disk_path: PathBuf, disk_nsectors: u64, - avail_features: u64, - acked_features: u64, config: VirtioBlockConfig, queue_evts: Option>, interrupt_cb: Option>, @@ -373,13 +372,15 @@ impl BlockIoUring { } Ok(BlockIoUring { + common: VirtioCommon { + avail_features, + acked_features: 0u64, + }, id, kill_evt: None, disk_image, disk_path, disk_nsectors, - avail_features, - acked_features: 0u64, config, queue_evts: None, interrupt_cb: None, @@ -397,8 +398,8 @@ impl BlockIoUring { BlockState { disk_path: self.disk_path.clone(), disk_nsectors: self.disk_nsectors, - avail_features: self.avail_features, - acked_features: self.acked_features, + avail_features: self.common.avail_features, + acked_features: self.common.acked_features, config: self.config, } } @@ -406,8 +407,8 @@ impl BlockIoUring { fn set_state(&mut self, state: &BlockState) -> io::Result<()> { self.disk_path = state.disk_path.clone(); self.disk_nsectors = state.disk_nsectors; - self.avail_features = state.avail_features; - self.acked_features = state.acked_features; + self.common.avail_features = state.avail_features; + self.common.acked_features = state.acked_features; self.config = state.config; Ok(()) @@ -415,13 +416,12 @@ impl BlockIoUring { fn update_writeback(&mut self) { // Use writeback from config if VIRTIO_BLK_F_CONFIG_WCE - let writeback = - if self.acked_features & 1 << VIRTIO_BLK_F_CONFIG_WCE == 1 << VIRTIO_BLK_F_CONFIG_WCE { - self.config.writeback == 1 - } else { - // Else check if VIRTIO_BLK_F_FLUSH negotiated - self.acked_features & 1 << VIRTIO_BLK_F_FLUSH == 1 << VIRTIO_BLK_F_FLUSH - }; + let writeback = if self.common.feature_acked(VIRTIO_BLK_F_CONFIG_WCE.into()) { + self.config.writeback == 1 + } else { + // Else check if VIRTIO_BLK_F_FLUSH negotiated + self.common.feature_acked(VIRTIO_BLK_F_FLUSH.into()) + }; info!( "Changing cache mode to {}", @@ -454,20 +454,11 @@ impl VirtioDevice for BlockIoUring { } fn features(&self) -> u64 { - self.avail_features + self.common.avail_features } fn ack_features(&mut self, value: u64) { - let mut v = value; - // Check if the guest is ACK'ing a feature that we didn't claim to have. - let unrequested_features = v & !self.avail_features; - if unrequested_features != 0 { - warn!("Received acknowledge request for unknown feature."); - - // Don't count these features as acked. - v &= !unrequested_features; - } - self.acked_features |= v; + self.common.ack_features(value) } fn read_config(&self, offset: u64, data: &mut [u8]) {