mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-22 00:43:24 +00:00
Revise the BlockDevice
trait
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
e83e1fc01b
commit
ff525112d0
@ -6,6 +6,7 @@ use core::{fmt::Debug, hint::spin_loop, mem::size_of};
|
||||
use aster_block::{
|
||||
bio::{BioEnqueueError, BioStatus, BioType, SubmittedBio},
|
||||
request_queue::{BioRequest, BioRequestSingleQueue},
|
||||
BlockDeviceMeta,
|
||||
};
|
||||
use aster_util::safe_ptr::SafePtr;
|
||||
use id_alloc::IdAlloc;
|
||||
@ -79,8 +80,12 @@ impl aster_block::BlockDevice for BlockDevice {
|
||||
self.queue.enqueue(bio)
|
||||
}
|
||||
|
||||
fn max_nr_segments_per_bio(&self) -> usize {
|
||||
self.queue.max_nr_segments_per_bio()
|
||||
fn metadata(&self) -> BlockDeviceMeta {
|
||||
let device_config = self.device.config.read().unwrap();
|
||||
BlockDeviceMeta {
|
||||
max_nr_segments_per_bio: self.queue.max_nr_segments_per_bio(),
|
||||
nr_sectors: device_config.capacity_sectors(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,6 +106,11 @@ impl DeviceInner {
|
||||
/// Creates and inits the device.
|
||||
pub fn init(mut transport: Box<dyn VirtioTransport>) -> Result<Arc<Self>, VirtioDeviceError> {
|
||||
let config = VirtioBlockConfig::new(transport.as_mut());
|
||||
assert_eq!(
|
||||
config.read().unwrap().block_size(),
|
||||
VirtioBlockConfig::sector_size(),
|
||||
"currently not support customized device logical block size"
|
||||
);
|
||||
let num_queues = transport.num_queues();
|
||||
if num_queues != 1 {
|
||||
return Err(VirtioDeviceError::QueuesAmountDoNotMatch(num_queues, 1));
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
pub mod device;
|
||||
|
||||
use aster_block::SECTOR_SIZE;
|
||||
use aster_util::safe_ptr::SafePtr;
|
||||
use bitflags::bitflags;
|
||||
use int_to_c_enum::TryFromInt;
|
||||
@ -56,18 +57,32 @@ pub enum RespStatus {
|
||||
#[derive(Debug, Copy, Clone, Pod)]
|
||||
#[repr(C)]
|
||||
pub struct VirtioBlockConfig {
|
||||
/// The number of 512-byte sectors.
|
||||
capacity: u64,
|
||||
/// The maximum segment size.
|
||||
size_max: u64,
|
||||
/// The geometry of the device.
|
||||
geometry: VirtioBlockGeometry,
|
||||
/// The block size. If `logical_block_size` is not given in qemu cmdline,
|
||||
/// `blk_size` will be set to sector size (512 bytes) by default.
|
||||
blk_size: u32,
|
||||
/// The topology of the device.
|
||||
topology: VirtioBlockTopology,
|
||||
/// Writeback mode.
|
||||
writeback: u8,
|
||||
unused0: [u8; 3],
|
||||
/// The maximum discard sectors for one segment.
|
||||
max_discard_sectors: u32,
|
||||
/// The maximum number of discard segments in a discard command.
|
||||
max_discard_seg: u32,
|
||||
/// Discard commands must be aligned to this number of sectors.
|
||||
discard_sector_alignment: u32,
|
||||
/// The maximum number of write zeroes sectors in one segment.
|
||||
max_write_zeroes_sectors: u32,
|
||||
/// The maximum number of segments in a write zeroes command.
|
||||
max_write_zeroes_seg: u32,
|
||||
/// Set if a write zeroes command may result in the
|
||||
/// deallocation of one or more of the sectors.
|
||||
write_zeros_may_unmap: u8,
|
||||
unused1: [u8; 3],
|
||||
}
|
||||
@ -83,9 +98,13 @@ pub struct VirtioBlockGeometry {
|
||||
#[derive(Debug, Copy, Clone, Pod)]
|
||||
#[repr(C)]
|
||||
pub struct VirtioBlockTopology {
|
||||
/// Exponent for physical block per logical block.
|
||||
physical_block_exp: u8,
|
||||
/// Alignment offset in logical blocks.
|
||||
alignment_offset: u8,
|
||||
/// Minimum I/O size without performance penalty in logical blocks.
|
||||
min_io_size: u16,
|
||||
/// Optimal sustained I/O size in logical blocks.
|
||||
opt_io_size: u32,
|
||||
}
|
||||
|
||||
@ -94,4 +113,20 @@ impl VirtioBlockConfig {
|
||||
let memory = transport.device_config_memory();
|
||||
SafePtr::new(memory, 0)
|
||||
}
|
||||
|
||||
pub(self) const fn sector_size() -> usize {
|
||||
SECTOR_SIZE
|
||||
}
|
||||
|
||||
pub(self) fn block_size(&self) -> usize {
|
||||
self.blk_size as usize
|
||||
}
|
||||
|
||||
pub(self) fn capacity_sectors(&self) -> usize {
|
||||
self.capacity as usize
|
||||
}
|
||||
|
||||
pub(self) fn capacity_bytes(&self) -> usize {
|
||||
self.capacity_sectors() * Self::sector_size()
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user