mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-07-11 11:13:24 +00:00
新版文件系统重构完成 (#198)
1.重构:VFS 2. 重构:ProcFS 3. 重构:DevFS 4. 重构:FAT32 5. 重构:AHCI驱动 6. 新增:RamFS 7. 新增:MountFS 8. 新增:FAT12 9. 新增:FAT16 10. 重构:设备抽象 Co-authored-by: guanjinquan <1666320330@qq.com> Co-authored-by: DaJiYuQia <88259094+DaJiYuQia@users.noreply.github.com>
This commit is contained in:
@ -10,7 +10,7 @@
|
||||
* @param fifo 队列结构体
|
||||
* @param size 缓冲区大小
|
||||
* @param reserved 暂时保留,请置为0
|
||||
* @return int 错误码:成功->0
|
||||
* @return int 错误码: NOMEM; 成功->0
|
||||
*/
|
||||
int kfifo_alloc(struct kfifo_t *fifo, uint32_t size, uint64_t reserved)
|
||||
{
|
||||
|
@ -52,16 +52,20 @@ void lockref_inc(struct lockref *lock_ref)
|
||||
* @brief 原子地将引用计数加1.如果原来的count≤0,则操作失败。
|
||||
*
|
||||
* @param lock_ref 指向要被操作的lockref变量的指针
|
||||
* @return int 操作成功=>true
|
||||
* @return bool 操作成功=>true
|
||||
* 操作失败=>false
|
||||
*/
|
||||
bool lockref_inc_not_zero(struct lockref *lock_ref)
|
||||
{
|
||||
CMPXCHG_LOOP(lock_ref,
|
||||
if (old.count <= 0) return false;
|
||||
++new.count;
|
||||
,
|
||||
return true;)
|
||||
CMPXCHG_LOOP(
|
||||
lock_ref,
|
||||
{
|
||||
if (old.count <= 0)
|
||||
return false;
|
||||
++new.count;
|
||||
},
|
||||
{ return true; })
|
||||
|
||||
bool retval;
|
||||
spin_lock(&lock_ref->lock);
|
||||
retval = false;
|
||||
@ -86,11 +90,14 @@ bool lockref_inc_not_zero(struct lockref *lock_ref)
|
||||
*/
|
||||
int lockref_dec(struct lockref *lock_ref)
|
||||
{
|
||||
CMPXCHG_LOOP(lock_ref,
|
||||
if (old.count <= 0) break;
|
||||
--new.count;
|
||||
,
|
||||
return new.count;);
|
||||
CMPXCHG_LOOP(
|
||||
lock_ref,
|
||||
{
|
||||
if (old.count <= 0)
|
||||
break;
|
||||
--new.count;
|
||||
},
|
||||
{ return new.count; })
|
||||
|
||||
// 如果xchg时,处于已加锁的状态或者检测到old.count <= 0,则采取加锁处理
|
||||
int retval = -1;
|
||||
@ -117,11 +124,14 @@ int lockref_dec(struct lockref *lock_ref)
|
||||
*/
|
||||
int lockref_dec_return(struct lockref *lock_ref)
|
||||
{
|
||||
CMPXCHG_LOOP(lock_ref,
|
||||
if (old.count <= 0) return -1;
|
||||
--new.count;
|
||||
,
|
||||
return new.count;);
|
||||
CMPXCHG_LOOP(
|
||||
lock_ref,
|
||||
{
|
||||
if (old.count <= 0)
|
||||
return -1;
|
||||
--new.count;
|
||||
},
|
||||
{ return new.count; })
|
||||
|
||||
return -1;
|
||||
}
|
||||
@ -138,11 +148,14 @@ int lockref_dec_return(struct lockref *lock_ref)
|
||||
*/
|
||||
bool lockref_dec_not_zero(struct lockref *lock_ref)
|
||||
{
|
||||
CMPXCHG_LOOP(lock_ref,
|
||||
if (old.count <= 1) return false;
|
||||
--new.count;
|
||||
,
|
||||
return true;)
|
||||
CMPXCHG_LOOP(
|
||||
lock_ref,
|
||||
{
|
||||
if (old.count <= 1)
|
||||
return false;
|
||||
--new.count;
|
||||
},
|
||||
{ return true; })
|
||||
|
||||
bool retval = false;
|
||||
spin_lock(&lock_ref->lock);
|
||||
@ -167,11 +180,14 @@ bool lockref_dec_not_zero(struct lockref *lock_ref)
|
||||
*/
|
||||
bool lockref_dec_or_lock_not_zero(struct lockref *lock_ref)
|
||||
{
|
||||
CMPXCHG_LOOP(lock_ref,
|
||||
if (old.count <= 1) break;
|
||||
--new.count;
|
||||
,
|
||||
return true;);
|
||||
CMPXCHG_LOOP(
|
||||
lock_ref,
|
||||
{
|
||||
if (old.count <= 1)
|
||||
break;
|
||||
--new.count;
|
||||
},
|
||||
{ return true; });
|
||||
|
||||
bool retval = false;
|
||||
spin_lock(&lock_ref->lock);
|
||||
@ -205,11 +221,14 @@ void lockref_mark_dead(struct lockref *lock_ref)
|
||||
*/
|
||||
bool lockref_inc_not_dead(struct lockref *lock_ref)
|
||||
{
|
||||
CMPXCHG_LOOP(lock_ref,
|
||||
if (old.count < 0) return false;
|
||||
++new.count;
|
||||
,
|
||||
return true;)
|
||||
CMPXCHG_LOOP(
|
||||
lock_ref,
|
||||
{
|
||||
if (old.count < 0)
|
||||
return false;
|
||||
++new.count;
|
||||
},
|
||||
{ return true; })
|
||||
|
||||
bool retval = false;
|
||||
// 快捷路径操作失败,尝试加锁
|
||||
|
@ -7,6 +7,9 @@ pub mod atomic;
|
||||
pub mod list;
|
||||
pub mod lockref;
|
||||
pub mod mutex;
|
||||
pub mod vec_cursor;
|
||||
#[macro_use]
|
||||
pub mod volatile_io;
|
||||
pub mod rwlock;
|
||||
pub mod semaphore;
|
||||
pub mod wait_queue;
|
||||
|
251
kernel/src/libs/vec_cursor.rs
Normal file
251
kernel/src/libs/vec_cursor.rs
Normal file
@ -0,0 +1,251 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use core::mem::size_of;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
|
||||
use crate::{
|
||||
include::bindings::bindings::{E2BIG, EINVAL, EOVERFLOW},
|
||||
io::SeekFrom,
|
||||
};
|
||||
|
||||
/// @brief 本模块用于为数组提供游标的功能,以简化其操作。
|
||||
#[derive(Debug)]
|
||||
pub struct VecCursor {
|
||||
/// 游标管理的数据
|
||||
data: Vec<u8>,
|
||||
/// 游标的位置
|
||||
pos: usize,
|
||||
}
|
||||
|
||||
impl VecCursor {
|
||||
/// @brief 新建一个游标
|
||||
pub fn new(data: Vec<u8>) -> Self {
|
||||
return Self { data: data, pos: 0 };
|
||||
}
|
||||
|
||||
/// @brief 创建一个全0的cursor
|
||||
pub fn zerod(length: usize) -> Self {
|
||||
let mut result = VecCursor {
|
||||
data: Vec::new(),
|
||||
pos: 0,
|
||||
};
|
||||
result.data.resize(length, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// @brief 获取游标管理的数据的可变引用
|
||||
pub fn get_mut(&mut self) -> &mut Vec<u8> {
|
||||
return &mut self.data;
|
||||
}
|
||||
|
||||
/// @brief 获取游标管理的数据的不可变引用
|
||||
pub fn get_ref(&self) -> &Vec<u8> {
|
||||
return &self.data;
|
||||
}
|
||||
|
||||
/// @brief 读取一个u8的数据(小端对齐)
|
||||
pub fn read_u8(&mut self) -> Result<u8, i32> {
|
||||
if self.pos >= self.data.len() {
|
||||
return Err(-(E2BIG as i32));
|
||||
}
|
||||
self.pos += 1;
|
||||
return Ok(self.data[self.pos - 1]);
|
||||
}
|
||||
|
||||
/// @brief 读取一个u16的数据(小端对齐)
|
||||
pub fn read_u16(&mut self) -> Result<u16, i32> {
|
||||
if self.pos + 2 > self.data.len() {
|
||||
return Err(-(E2BIG as i32));
|
||||
}
|
||||
let mut res = 0u16;
|
||||
res |= (self.data[self.pos] as u16) & 0xff;
|
||||
self.pos += 1;
|
||||
res |= ((self.data[self.pos] as u16) & 0xff) << 8;
|
||||
self.pos += 1;
|
||||
|
||||
return Ok(res);
|
||||
}
|
||||
|
||||
/// @brief 读取一个u32的数据(小端对齐)
|
||||
pub fn read_u32(&mut self) -> Result<u32, i32> {
|
||||
if self.pos + 4 > self.data.len() {
|
||||
return Err(-(E2BIG as i32));
|
||||
}
|
||||
let mut res = 0u32;
|
||||
for i in 0..4 {
|
||||
res |= ((self.data[self.pos] as u32) & 0xff) << (8 * i);
|
||||
self.pos += 1;
|
||||
}
|
||||
|
||||
return Ok(res);
|
||||
}
|
||||
|
||||
/// @brief 读取一个u64的数据(小端对齐)
|
||||
pub fn read_u64(&mut self) -> Result<u64, i32> {
|
||||
if self.pos + 8 > self.data.len() {
|
||||
return Err(-(E2BIG as i32));
|
||||
}
|
||||
let mut res = 0u64;
|
||||
for i in 0..8 {
|
||||
res |= ((self.data[self.pos] as u64) & 0xff) << (8 * i);
|
||||
self.pos += 1;
|
||||
}
|
||||
|
||||
return Ok(res);
|
||||
}
|
||||
|
||||
/// @brief 精确读取与buf同样大小的数据。
|
||||
///
|
||||
/// @param buf 要读取到的目标缓冲区
|
||||
///
|
||||
/// @return Ok(()) 成功读取
|
||||
/// @retunr Err(-E2BIG) 没有这么多数据,读取失败
|
||||
pub fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), i32> {
|
||||
if self.pos + buf.len() > self.data.len() {
|
||||
return Err(-(E2BIG as i32));
|
||||
}
|
||||
buf.copy_from_slice(&self.data[self.pos..self.pos + buf.len()]);
|
||||
self.pos += buf.len();
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
/// @brief 小端对齐,读取数据到u16数组.
|
||||
///
|
||||
/// @param buf 目标u16数组
|
||||
pub fn read_u16_into(&mut self, buf: &mut [u16]) -> Result<(), i32> {
|
||||
if self.pos + buf.len() * size_of::<u16>() > self.data.len() * size_of::<u16>() {
|
||||
return Err(-(E2BIG as i32));
|
||||
}
|
||||
|
||||
for i in 0..buf.len() {
|
||||
buf[i] = self.read_u16()?;
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
/// @brief 调整游标的位置
|
||||
///
|
||||
/// @param 调整的相对值
|
||||
///
|
||||
/// @return Ok(新的游标位置) 调整成功,返回新的游标位置
|
||||
/// @return Err(-EOVERFLOW) 调整失败,游标超出正确的范围。(失败时游标位置不变)
|
||||
pub fn seek(&mut self, origin: SeekFrom) -> Result<usize, i32> {
|
||||
let pos: i64;
|
||||
match origin {
|
||||
SeekFrom::SeekSet(offset) => {
|
||||
pos = offset;
|
||||
}
|
||||
SeekFrom::SeekCurrent(offset) => {
|
||||
pos = self.pos as i64 + offset;
|
||||
}
|
||||
SeekFrom::SeekEnd(offset) => {
|
||||
// 请注意,此处的offset应小于等于0,否则肯定是不合法的
|
||||
pos = self.data.len() as i64 + offset;
|
||||
}
|
||||
SeekFrom::Invalid => {
|
||||
return Err(-(EINVAL as i32));
|
||||
}
|
||||
}
|
||||
|
||||
if pos < 0 || pos > self.data.len() as i64 {
|
||||
return Err(-(EOVERFLOW as i32));
|
||||
}
|
||||
self.pos = pos as usize;
|
||||
return Ok(self.pos);
|
||||
}
|
||||
|
||||
/// @brief 写入一个u8的数据(小端对齐)
|
||||
pub fn write_u8(&mut self, value: u8) -> Result<u8, i32> {
|
||||
if self.pos >= self.data.len() {
|
||||
return Err(-(E2BIG as i32));
|
||||
}
|
||||
|
||||
self.data[self.pos] = value;
|
||||
self.pos += 1;
|
||||
|
||||
return Ok(value);
|
||||
}
|
||||
|
||||
/// @brief 写入一个u16的数据(小端对齐)
|
||||
pub fn write_u16(&mut self, value: u16) -> Result<u16, i32> {
|
||||
if self.pos + 2 > self.data.len() {
|
||||
return Err(-(E2BIG as i32));
|
||||
}
|
||||
|
||||
self.data[self.pos] = (value & 0xff) as u8;
|
||||
self.pos += 1;
|
||||
self.data[self.pos] = ((value >> 8) & 0xff) as u8;
|
||||
self.pos += 1;
|
||||
|
||||
return Ok(value);
|
||||
}
|
||||
|
||||
/// @brief 写入一个u32的数据(小端对齐)
|
||||
pub fn write_u32(&mut self, value: u32) -> Result<u32, i32> {
|
||||
if self.pos + 4 > self.data.len() {
|
||||
return Err(-(E2BIG as i32));
|
||||
}
|
||||
|
||||
for i in 0..4 {
|
||||
self.data[self.pos] = ((value >> (i * 8)) & 0xff) as u8;
|
||||
self.pos += 1;
|
||||
}
|
||||
|
||||
return Ok(value);
|
||||
}
|
||||
|
||||
/// @brief 写入一个u64的数据(小端对齐)
|
||||
pub fn write_u64(&mut self, value: u64) -> Result<u64, i32> {
|
||||
if self.pos + 8 > self.data.len() {
|
||||
return Err(-(E2BIG as i32));
|
||||
}
|
||||
|
||||
for i in 0..8 {
|
||||
self.data[self.pos] = ((value >> (i * 8)) & 0xff) as u8;
|
||||
self.pos += 1;
|
||||
}
|
||||
|
||||
return Ok(value);
|
||||
}
|
||||
|
||||
/// @brief 精确写入与buf同样大小的数据。
|
||||
///
|
||||
/// @param buf 要写入到的目标缓冲区
|
||||
///
|
||||
/// @return Ok(()) 成功写入
|
||||
/// @retunr Err(-E2BIG) 没有这么多数据,写入失败
|
||||
pub fn write_exact(&mut self, buf: &[u8]) -> Result<(), i32> {
|
||||
if self.pos + buf.len() > self.data.len() {
|
||||
return Err(-(E2BIG as i32));
|
||||
}
|
||||
|
||||
self.data[self.pos..self.pos + buf.len()].copy_from_slice(&buf[..]);
|
||||
self.pos += buf.len();
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
/// @brief 获取当前的数据切片
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
return &self.data[..];
|
||||
}
|
||||
|
||||
/// @brief 获取可变数据切片
|
||||
pub fn as_mut_slice(&mut self) -> &mut [u8] {
|
||||
return &mut self.data[..];
|
||||
}
|
||||
|
||||
/// @brief 获取当前游标的位置
|
||||
#[inline]
|
||||
pub fn pos(&self) -> usize {
|
||||
return self.pos;
|
||||
}
|
||||
|
||||
/// @brief 获取缓冲区数据的大小
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize {
|
||||
return self.data.len();
|
||||
}
|
||||
}
|
37
kernel/src/libs/volatile_io.rs
Normal file
37
kernel/src/libs/volatile_io.rs
Normal file
@ -0,0 +1,37 @@
|
||||
macro_rules! volatile_read {
|
||||
($data: expr) => {
|
||||
unsafe { core::ptr::read_volatile(core::ptr::addr_of!($data)) }
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! volatile_write {
|
||||
($data: expr, $value: expr) => {
|
||||
unsafe { core::ptr::write_volatile(core::ptr::addr_of_mut!($data), $value) }
|
||||
};
|
||||
}
|
||||
|
||||
/// @brief: 用于volatile设置某些bits
|
||||
/// @param val: 设置这些位
|
||||
/// @param flag: true表示设置这些位为1; false表示设置这些位为0;
|
||||
macro_rules! volatile_set_bit {
|
||||
($data: expr, $val: expr, $flag: expr) => {
|
||||
volatile_write!(
|
||||
$data,
|
||||
match $flag {
|
||||
true => core::ptr::read_volatile(core::ptr::addr_of!($data)) | $val,
|
||||
false => core::ptr::read_volatile(core::ptr::addr_of!($data)) & (!$val),
|
||||
}
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
/// @param data: volatile变量
|
||||
/// @param bits: 置1的位才有效,表示写这些位
|
||||
/// @param val: 要写的值
|
||||
/// 比如: 写 x 的 2至8bit, 为 10, 可以这么写 volatile_write_bit(x, (1<<8)-(1<<2), 10<<2);
|
||||
macro_rules! volatile_write_bit {
|
||||
($data: expr, $bits: expr, $val: expr) => {
|
||||
volatile_set_bit!($data, $bits, false);
|
||||
volatile_set_bit!($data, ($val) & ($bits), true);
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user