mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-28 11:53:24 +00:00
Add Ext2 fs and basic bio layer
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
1616f2d32c
commit
9473889c6b
93
services/libs/aster-std/src/fs/ext2/utils.rs
Normal file
93
services/libs/aster-std/src/fs/ext2/utils.rs
Normal file
@ -0,0 +1,93 @@
|
||||
use super::prelude::*;
|
||||
|
||||
use core::ops::MulAssign;
|
||||
|
||||
pub trait IsPowerOf: Copy + Sized + MulAssign + PartialOrd {
|
||||
/// Returns true if and only if `self == x^k` for some `k` where `k > 0`.
|
||||
///
|
||||
/// The `x` must be a positive value.
|
||||
fn is_power_of(&self, x: Self) -> bool {
|
||||
let mut power = x;
|
||||
while power < *self {
|
||||
power *= x;
|
||||
}
|
||||
|
||||
power == *self
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_ipo_for {
|
||||
($($ipo_ty:ty),*) => {
|
||||
$(impl IsPowerOf for $ipo_ty {})*
|
||||
};
|
||||
}
|
||||
|
||||
impl_ipo_for!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, isize, usize);
|
||||
|
||||
/// The `Dirty` wraps a value of type `T` with functions similar to that of a rw-lock,
|
||||
/// but simply sets a dirty flag on `write()`.
|
||||
pub struct Dirty<T: Debug> {
|
||||
value: T,
|
||||
dirty: bool,
|
||||
}
|
||||
|
||||
impl<T: Debug> Dirty<T> {
|
||||
/// Creates a new Dirty without setting the dirty flag.
|
||||
pub fn new(val: T) -> Dirty<T> {
|
||||
Dirty {
|
||||
value: val,
|
||||
dirty: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new Dirty with setting the dirty flag.
|
||||
pub fn new_dirty(val: T) -> Dirty<T> {
|
||||
Dirty {
|
||||
value: val,
|
||||
dirty: true,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if dirty, false otherwise.
|
||||
pub fn is_dirty(&self) -> bool {
|
||||
self.dirty
|
||||
}
|
||||
|
||||
/// Clears the dirty flag.
|
||||
pub fn clear_dirty(&mut self) {
|
||||
self.dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Debug> Deref for Dirty<T> {
|
||||
type Target = T;
|
||||
|
||||
/// Returns the imutable value.
|
||||
fn deref(&self) -> &T {
|
||||
&self.value
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Debug> DerefMut for Dirty<T> {
|
||||
/// Returns the mutable value, sets the dirty flag.
|
||||
fn deref_mut(&mut self) -> &mut T {
|
||||
self.dirty = true;
|
||||
&mut self.value
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Debug> Drop for Dirty<T> {
|
||||
/// Guards if it is dirty when dropping.
|
||||
fn drop(&mut self) {
|
||||
if self.is_dirty() {
|
||||
warn!("[{:?}] is dirty then dropping", self.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Debug> Debug for Dirty<T> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
let tag = if self.dirty { "Dirty" } else { "Clean" };
|
||||
write!(f, "[{}] {:?}", tag, self.value)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user