Add VirtioBlockFeature to cache virtio-blk's features

This commit is contained in:
Cautreoxit
2024-11-14 21:10:55 +08:00
committed by Tate, Hongliang Tian
parent 3cb7f5b721
commit 885950c2a4
2 changed files with 18 additions and 2 deletions

View File

@ -19,7 +19,7 @@ use ostd::{
Pod, Pod,
}; };
use super::{BlockFeatures, VirtioBlockConfig}; use super::{BlockFeatures, VirtioBlockConfig, VirtioBlockFeature};
use crate::{ use crate::{
device::{ device::{
block::{ReqType, RespStatus}, block::{ReqType, RespStatus},
@ -92,6 +92,7 @@ impl aster_block::BlockDevice for BlockDevice {
#[derive(Debug)] #[derive(Debug)]
struct DeviceInner { struct DeviceInner {
config: SafePtr<VirtioBlockConfig, IoMem>, config: SafePtr<VirtioBlockConfig, IoMem>,
features: VirtioBlockFeature,
queue: SpinLock<VirtQueue>, queue: SpinLock<VirtQueue>,
transport: SpinLock<Box<dyn VirtioTransport>>, transport: SpinLock<Box<dyn VirtioTransport>>,
block_requests: DmaStream, block_requests: DmaStream,
@ -122,6 +123,7 @@ impl DeviceInner {
"Not supporting Multi-Queue Block IO Queueing Mechanism, only using the first queue" "Not supporting Multi-Queue Block IO Queueing Mechanism, only using the first queue"
); );
} }
let features = VirtioBlockFeature::new(transport.as_ref());
let queue = VirtQueue::new(0, Self::QUEUE_SIZE, transport.as_mut()) let queue = VirtQueue::new(0, Self::QUEUE_SIZE, transport.as_mut())
.expect("create virtqueue failed"); .expect("create virtqueue failed");
let block_requests = { let block_requests = {
@ -137,6 +139,7 @@ impl DeviceInner {
let device = Arc::new(Self { let device = Arc::new(Self {
config, config,
features,
queue: SpinLock::new(queue), queue: SpinLock::new(queue),
transport: SpinLock::new(transport), transport: SpinLock::new(transport),
block_requests, block_requests,
@ -410,7 +413,7 @@ impl DeviceInner {
/// Flushes any cached data from the guest to the persistent storage on the host. /// Flushes any cached data from the guest to the persistent storage on the host.
/// This will be ignored if the device doesn't support the `VIRTIO_BLK_F_FLUSH` feature. /// This will be ignored if the device doesn't support the `VIRTIO_BLK_F_FLUSH` feature.
fn flush(&self, bio_request: BioRequest) { fn flush(&self, bio_request: BioRequest) {
if self.transport.lock().read_device_features() & BlockFeatures::FLUSH.bits() == 0 { if self.features.support_flush {
bio_request.bios().for_each(|bio| { bio_request.bios().for_each(|bio| {
bio.complete(BioStatus::Complete); bio.complete(BioStatus::Complete);
}); });

View File

@ -111,6 +111,12 @@ pub struct VirtioBlockTopology {
opt_io_size: u32, opt_io_size: u32,
} }
#[derive(Debug, Copy, Clone)]
#[repr(C)]
pub struct VirtioBlockFeature {
support_flush: bool,
}
impl VirtioBlockConfig { impl VirtioBlockConfig {
pub(self) fn new(transport: &dyn VirtioTransport) -> SafePtr<Self, IoMem> { pub(self) fn new(transport: &dyn VirtioTransport) -> SafePtr<Self, IoMem> {
let memory = transport.device_config_memory(); let memory = transport.device_config_memory();
@ -135,3 +141,10 @@ impl VirtioBlockConfig {
.map(|val| val as usize) .map(|val| val as usize)
} }
} }
impl VirtioBlockFeature {
pub(self) fn new(transport: &dyn VirtioTransport) -> Self {
let support_flush = transport.read_device_features() & BlockFeatures::FLUSH.bits() == 1;
VirtioBlockFeature { support_flush }
}
}