Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 添加gendisk抽象 #903

Merged
merged 4 commits into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 115 additions & 3 deletions kernel/src/driver/base/block/block_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ use crate::driver::{
block::cache::{cached_block_device::BlockCache, BlockCacheError, BLOCK_SIZE},
};

use alloc::{sync::Arc, vec::Vec};
use core::any::Any;
use alloc::{string::String, sync::Arc, vec::Vec};
use core::{any::Any, fmt::Display, ops::Deref};
use log::error;
use system_error::SystemError;

use super::disk_info::Partition;
use super::{disk_info::Partition, gendisk::GenDisk, manager::BlockDevMeta};

/// 该文件定义了 Device 和 BlockDevice 的接口
/// Notice 设备错误码使用 Posix 规定的 int32_t 的错误码表示,而不是自己定义错误enum
Expand All @@ -36,6 +36,41 @@ pub const BLK_SIZE_LOG2_LIMIT: u8 = 12; // 设定块设备的块大小不能超
/// 在DragonOS中,我们认为磁盘的每个LBA大小均为512字节。(注意,文件系统的1个扇区可能事实上是多个LBA)
pub const LBA_SIZE: usize = 512;

#[derive(Debug, Clone, Copy)]
pub struct GeneralBlockRange {
pub lba_start: usize,
pub lba_end: usize,
}

impl GeneralBlockRange {
pub fn new(lba_start: usize, lba_end: usize) -> Option<Self> {
if lba_start >= lba_end {
return None;
}
return Some(GeneralBlockRange { lba_start, lba_end });
}

#[inline]
pub fn len(&self) -> usize {
return self.lba_end - self.lba_start;
}

/// 取交集
pub fn intersects_with(&self, rhs: &Self) -> Option<Self> {
// 检查是否相交
if self.lba_start <= rhs.lba_end && self.lba_end >= rhs.lba_start {
// 计算相交部分的起始和结束 LBA
let start = usize::max(self.lba_start, rhs.lba_start);
let end = usize::min(self.lba_end, rhs.lba_end);
// 返回相交部分
GeneralBlockRange::new(start, end)
} else {
// 不相交,返回 None
None
}
}
}

/// @brief 块设备的迭代器
/// @usage 某次操作读/写块设备的[L,R]范围内的字节,
/// 那么可以使用此结构体进行迭代遍历,每次调用next()返回一个BlockRange
Expand Down Expand Up @@ -186,8 +221,80 @@ pub fn __lba_to_bytes(lba_id: usize, blk_size: usize) -> BlockId {
return lba_id * blk_size;
}

/// 块设备的名字
pub struct BlockDevName {
name: Arc<String>,
id: usize,
}

impl BlockDevName {
pub fn new(name: String, id: usize) -> Self {
return BlockDevName {
name: Arc::new(name),
id,
};
}

#[inline]
pub fn id(&self) -> usize {
return self.id;
}
}

impl core::fmt::Debug for BlockDevName {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
return write!(f, "{}", self.name);
}
}

impl Display for BlockDevName {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
return write!(f, "{}", self.name);
}
}

impl Clone for BlockDevName {
fn clone(&self) -> Self {
return BlockDevName {
name: self.name.clone(),
id: self.id,
};
}
}

impl core::hash::Hash for BlockDevName {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.name.hash(state);
}
}

impl Deref for BlockDevName {
type Target = String;

fn deref(&self) -> &Self::Target {
return self.name.as_ref();
}
}

impl PartialEq for BlockDevName {
fn eq(&self, other: &Self) -> bool {
return self.name == other.name;
}
}

impl Eq for BlockDevName {}

/// @brief 块设备应该实现的操作
pub trait BlockDevice: Device {
/// # dev_name
/// 返回块设备的名字
fn dev_name(&self) -> &BlockDevName;

fn blkdev_meta(&self) -> &BlockDevMeta;

/// 获取设备的扇区范围
fn disk_range(&self) -> GeneralBlockRange;

/// @brief: 在块设备中,从第lba_id_start个块开始,读取count个块数据,存放到buf中
///
/// @parameter lba_id_start: 起始块
Expand Down Expand Up @@ -379,6 +486,11 @@ pub trait BlockDevice: Device {
}
return Ok(len);
}

/// # gendisk注册成功的回调函数
fn callback_gendisk_registered(&self, _gendisk: &Arc<GenDisk>) -> Result<(), SystemError> {
Ok(())
}
}

/// @brief 块设备框架函数集
Expand Down
46 changes: 34 additions & 12 deletions kernel/src/driver/base/block/disk_info.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
#![allow(dead_code)]
use alloc::sync::{Arc, Weak};
use system_error::SystemError;

use super::block_device::BlockDevice;
use super::block_device::{BlockDevice, GeneralBlockRange};

pub type SectorT = u64;

pub const BLK_TYPE_AHCI: u64 = 0;
pub const DISK_NAME_LEN: usize = 32; // 磁盘名称的最大长度
pub const BLK_GF_AHCI: u16 = 1 << 0; // 定义blk_gendisk中的标志位

/// @brief: 磁盘的分区信息 - (保留了c版本的数据信息)
#[derive(Debug)]
pub struct Partition {
pub start_sector: SectorT, // 该分区的起始扇区
pub lba_start: u64, // 起始LBA号
pub sectors_num: u64, // 该分区的扇区数
disk: Weak<dyn BlockDevice>, // 当前分区所属的磁盘
pub partno: u16, // 在磁盘上的分区号
pub start_sector: SectorT, // 该分区的起始扇区
pub lba_start: u64, // 起始LBA号
pub sectors_num: u64, // 该分区的扇区数
disk: Option<Weak<dyn BlockDevice>>, // 当前分区所属的磁盘
pub partno: u16, // 在磁盘上的分区号
}

/// @brief: 分区信息 - 成员函数
Expand All @@ -33,14 +30,39 @@ impl Partition {
start_sector,
lba_start,
sectors_num,
disk,
disk: Some(disk),
partno,
});
}

pub fn new_raw(start_sector: SectorT, lba_start: u64, sectors_num: u64, partno: u16) -> Self {
return Partition {
start_sector,
lba_start,
sectors_num,
disk: None,
partno,
};
}

/// @brief 获取当前分区所属的磁盘的Arc指针
#[inline]
pub fn disk(&self) -> Arc<dyn BlockDevice> {
return self.disk.upgrade().unwrap();
return self.disk.as_ref().unwrap().upgrade().unwrap();
}
}

impl TryInto<GeneralBlockRange> for Partition {
type Error = SystemError;

fn try_into(self) -> Result<GeneralBlockRange, Self::Error> {
if let Some(range) = GeneralBlockRange::new(
self.lba_start as usize,
(self.lba_start + self.sectors_num) as usize,
) {
return Ok(range);
} else {
return Err(SystemError::EINVAL);
}
}
}
Loading
Loading