use alloc::{sync::Arc, vec::Vec};
use libc_core::fcntl::OpenFlags;
use sync::Mutex;
use vfscore::{FileSystem, INodeInterface, VfsResult};
use crate::{file::File, pathbuf::PathBuf};
pub static MOUNTED_FS: Mutex<Vec<(PathBuf, DEntryNode)>> = Mutex::new(Vec::new());
#[derive(Clone)]
pub struct DEntryNode {
pub fs: Arc<dyn FileSystem>,
node: Arc<dyn INodeInterface>,
}
impl DEntryNode {
#[inline]
pub fn node(&self) -> Arc<dyn INodeInterface> {
self.node.clone()
}
}
pub fn get_mounted(path: &PathBuf) -> (DEntryNode, PathBuf) {
let mounted = MOUNTED_FS.lock();
let finded = mounted
.iter()
.rev()
.find(|x| path.starts_with(&x.0))
.unwrap();
(finded.1.clone(), path.trim_start(&finded.0))
}
pub fn mount_fs(fs: Arc<dyn FileSystem>, path: &str) {
if path != "/" {
let _ = File::open(path, OpenFlags::DIRECTORY | OpenFlags::CREAT);
}
let path = PathBuf::from(path);
info!("SYSTEM FS mount {} @ {}", fs.name(), path);
let node = fs.root_dir();
MOUNTED_FS.lock().push((path, DEntryNode { fs, node }));
}
pub fn umount(path: PathBuf) -> VfsResult<()> {
MOUNTED_FS.lock().retain(|x| x.0 != path);
Ok(())
}