pub struct Inode<T: CacheManager, F: CacheManager> {
pub file_content: Mutex<FileContent<T>>,
pub file_type: ReadOnly<DiskInodeType>,
pub parent_dir: Option<(Arc<Self>, u32)>,
pub fs: Arc<EasyFileSystem<T, F>>,
pub time: Mutex<InodeTime>,
}
Expand description
The functionality of ClusLi & Inode can be merged. The struct for file information
Fields
file_content: Mutex<FileContent<T>>
File Content
file_type: ReadOnly<DiskInodeType>
File type
parent_dir: Option<(Arc<Self>, u32)>
The parent directory of this inode
fs: Arc<EasyFileSystem<T, F>>
file system
time: Mutex<InodeTime>
Struct to hold time related information
Implementations
Constructor
Constructor for Inodes
Arguments
fst_clus
: The first cluster of the file
type_
: The type of the inode determined by the file
size
: NOTE: the size
field should be set to None
for a directory
parent_dir
: parent directory
fs
: The pointer to the file system
Basic Funtions
Get first cluster of inode. If cluster list is empty, it will return None.
Warning
This function is an external interface. May cause DEADLOCK if called on internal interface
Get inode number of inode. See first sector number as inode number.
!!! This function have many bugs
Get the neighboring 8 or fewer(the trailing mod-of-eight blocks of the file) blocks
of inner_block_id
,
Get file size
Warning
This function is an external interface. May cause DEADLOCK if called on internal interface
Get the number of clusters corresponding to the size.
Get the number of clusters needed after rounding up according to size.
Get block id corresponding to the blk
File Content Operation
Allocate required clusters
Deallocate required cluster If the required number is greater than the number of clusters in the file, all clusters will be deallocated
Change the size of current file. This operation is ignored if the result size is negative
Warning
This function will lock parent’s file content. May cause DEADLOCK
Open File Table
Open file table static operation function.
IO
pub fn read_at_block_cache(
&self,
lock: &mut MutexGuard<'_, FileContent<T>>,
offset: usize,
buf: &mut [u8]
) -> usize
pub fn read_at_block_cache(
&self,
lock: &mut MutexGuard<'_, FileContent<T>>,
offset: usize,
buf: &mut [u8]
) -> usize
The get_block_cache
version of read_at
Read the inode(file) denoted by self, starting from offset.
read till the minor of buf.len()
and self.size
Arguments
buf
: The destination buffer of the read dataoffset
: The offsetblock_device
: the block_dev
pub fn write_at_block_cache(
&self,
lock: &mut MutexGuard<'_, FileContent<T>>,
offset: usize,
buf: &[u8]
) -> usize
Directory Operation
fn dir_iter<'a>(
&'a self,
lock: MutexGuard<'a, FileContent<T>>,
offset: Option<u32>,
mode: DirIterMode,
forward: bool
) -> DirIter<'a, T, F>ⓘNotable traits for DirIter<'_, T, F>impl<T: CacheManager, F: CacheManager> Iterator for DirIter<'_, T, F> type Item = FATDirEnt;
fn dir_iter<'a>(
&'a self,
lock: MutexGuard<'a, FileContent<T>>,
offset: Option<u32>,
mode: DirIterMode,
forward: bool
) -> DirIter<'a, T, F>ⓘNotable traits for DirIter<'_, T, F>impl<T: CacheManager, F: CacheManager> Iterator for DirIter<'_, T, F> type Item = FATDirEnt;
impl<T: CacheManager, F: CacheManager> Iterator for DirIter<'_, T, F> type Item = FATDirEnt;
Iter Construct
fn alloc_dir_ent<'a>(
parent_dir: &'a Arc<Self>,
lock: MutexGuard<'a, FileContent<T>>,
alloc_num: usize
) -> Result<(u32, MutexGuard<'a, FileContent<T>>), ()>
fn alloc_dir_ent<'a>(
parent_dir: &'a Arc<Self>,
lock: MutexGuard<'a, FileContent<T>>,
alloc_num: usize
) -> Result<(u32, MutexGuard<'a, FileContent<T>>), ()>
return the offset of last free entry
Delete Little thinking: The real delete operation is done by unlink syscall(this maybe a big problem) So we don’t care about atomic deletes in the filesystem We can recycle resources at will, and don’t care about the resource competition of this inode
Delete the short and the long entry of self
from parent_dir
Create
Create a file or a directory from the parent.
Construct a [u16,13] corresponding to the long_ent_num
’th 13-u16 or shorter name slice
NOTE: the first entry is of number 1 for long_ent_num
fn gen_short_name_slice(
parent_dir: &Arc<Self>,
name: &String,
short_name_slice: &mut [u8; 11]
) -> Result<(), ()>
Create a file from directory entry.
Arguments
parent_dir
: the parent directory inode pointer
ent
: the short entry as the source of information
offset
: the offset of the short directory entry in the parent_dir
fn write_back_dir_ent(
parent_dir: &Arc<Self>,
short_ent_offset: u32,
lock: MutexGuard<'_, FileContent<T>>,
short_ent: FATShortDirEnt,
long_ents: Vec<FATLongDirEnt>
)
fn write_back_dir_ent(
parent_dir: &Arc<Self>,
short_ent_offset: u32,
lock: MutexGuard<'_, FileContent<T>>,
short_ent: FATShortDirEnt,
long_ents: Vec<FATLongDirEnt>
)
Write back both long and short directories.
The short directory is created from the fst_clus
and the name
.
fn fill_empty_dir(
parent_dir: &Arc<Inode<T, F>>,
current_dir: &Arc<Inode<T, F>>,
current_lock: MutexGuard<'_, FileContent<T>>,
fst_clus: u32
)
fn fill_empty_dir(
parent_dir: &Arc<Inode<T, F>>,
current_dir: &Arc<Inode<T, F>>,
current_lock: MutexGuard<'_, FileContent<T>>,
fst_clus: u32
)
Fill out an empty directory with only the ‘.’ & ‘..’ entries.
ls - General Purose file filterer
Argument/Modes
Apart from None
mode, all modes will quit IMMEDIATELY returning a vector of one after the first successful match.
Modes are conveyed through enum DirFilter
. Four modes are provided, namely:
Name(String)
: Used for exact match of names.FstClus(u64)
: First Cluster matching. Note that this shouldn’t be used for zero-sized files for they MAY contain NO by specification. For this mode, it returns an Err(()) for the next of reaching the last item.DirentBegOffset(u32)
: Search should begin with theNone
: List all files inself
.
WARNING
The definition of OFFSET is CHANGED for this item. It should point to the NEXT USED entry whether it as a long entry whenever possible or a short entry if no long ones exist.
Return value
On success, the function returns Ok(_)
. On failure, multiple chances exist: either the Vec is empty, or the Result is Err(())
.
Implementation Information
The iterator stops at the last available item when it reaches the end,
returning None
from then on,
so relying on the offset of the last item to decide whether it has reached an end is not recommended.