93 lines
2.5 KiB
Rust
93 lines
2.5 KiB
Rust
use alloc::sync::Arc;
|
|
use core::any::Any;
|
|
|
|
use libk::vfs::{CommonImpl, InstanceData, Metadata, Node, NodeFlags, NodeRef, RegularImpl};
|
|
use libk_util::sync::{spin_rwlock::IrqSafeRwLock, IrqSafeSpinlock};
|
|
use yggdrasil_abi::{error::Error, io::OpenOptions};
|
|
|
|
use crate::{block::BlockAllocator, bvec::BVec, MemoryFilesystem};
|
|
|
|
pub(crate) struct FileNode<A: BlockAllocator> {
|
|
pub(crate) data: IrqSafeSpinlock<BVec<'static, A>>,
|
|
pub(crate) metadata: IrqSafeRwLock<Metadata>,
|
|
}
|
|
|
|
impl<A: BlockAllocator> FileNode<A> {
|
|
pub fn new(fs: Arc<MemoryFilesystem<A>>, metadata: Metadata) -> NodeRef {
|
|
Node::regular(
|
|
Self {
|
|
data: IrqSafeSpinlock::new(BVec::new()),
|
|
metadata: IrqSafeRwLock::new(metadata),
|
|
},
|
|
NodeFlags::empty(),
|
|
None,
|
|
Some(fs),
|
|
)
|
|
}
|
|
}
|
|
|
|
impl<A: BlockAllocator> CommonImpl for FileNode<A> {
|
|
fn as_any(&self) -> &dyn Any {
|
|
self
|
|
}
|
|
|
|
fn size(&self, _node: &NodeRef) -> Result<u64, Error> {
|
|
Ok(self.data.lock().size() as u64)
|
|
}
|
|
|
|
fn metadata(&self, _node: &NodeRef) -> Result<Metadata, Error> {
|
|
Ok(*self.metadata.read())
|
|
}
|
|
|
|
fn set_metadata(&self, _node: &NodeRef, metadata: &Metadata) -> Result<(), Error> {
|
|
*self.metadata.write() = *metadata;
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl<A: BlockAllocator> RegularImpl for FileNode<A> {
|
|
fn open(
|
|
&self,
|
|
_node: &NodeRef,
|
|
opts: OpenOptions,
|
|
) -> Result<(u64, Option<InstanceData>), Error> {
|
|
// TODO provide APPEND by vfs driver instead
|
|
if opts.contains(OpenOptions::APPEND) {
|
|
Ok((self.data.lock().size() as u64, None))
|
|
} else {
|
|
Ok((0, None))
|
|
}
|
|
}
|
|
|
|
fn read(
|
|
&self,
|
|
_node: &NodeRef,
|
|
_instance: Option<&InstanceData>,
|
|
pos: u64,
|
|
buf: &mut [u8],
|
|
) -> Result<usize, Error> {
|
|
self.metadata.write().set_atime_now();
|
|
self.data.lock().read(pos, buf)
|
|
}
|
|
|
|
fn write(
|
|
&self,
|
|
_node: &NodeRef,
|
|
_instance: Option<&InstanceData>,
|
|
pos: u64,
|
|
buf: &[u8],
|
|
) -> Result<usize, Error> {
|
|
self.metadata.write().set_mtime_now();
|
|
self.data.lock().write(pos, buf)
|
|
}
|
|
|
|
fn truncate(&self, _node: &NodeRef, new_size: u64) -> Result<(), Error> {
|
|
self.metadata.write().set_mtime_now();
|
|
self.data.lock().truncate(new_size)
|
|
}
|
|
|
|
fn close(&self, _node: &NodeRef, _instance: Option<&InstanceData>) -> Result<(), Error> {
|
|
Ok(())
|
|
}
|
|
}
|