pub mod dev;
mod device;
mod dir;
mod dyn_debug;
mod file;
mod fs;
mod proc;
#[cfg(not(feature = "plat-dyn"))]
mod sysfs;
mod tmp;
#[cfg(feature = "plat-dyn")]
pub(crate) mod usbfs;
use alloc::sync::Arc;
use ax_errno::LinuxResult;
use ax_fs::{FS_CONTEXT, FsContext};
use axfs_ng_vfs::{DirNodeOps, FileNodeOps, Filesystem, NodePermission, WeakDirEntry};
pub use tmp::MemoryFs;
pub use self::{device::*, dir::*, file::*, fs::*};
pub type DirMaker = Arc<dyn Fn(WeakDirEntry) -> Arc<dyn DirNodeOps> + Send + Sync>;
#[derive(Clone)]
pub enum NodeOpsMux {
Dir(DirMaker),
File(Arc<dyn FileNodeOps>),
}
impl From<DirMaker> for NodeOpsMux {
fn from(maker: DirMaker) -> Self {
Self::Dir(maker)
}
}
impl<T: FileNodeOps> From<Arc<T>> for NodeOpsMux {
fn from(ops: Arc<T>) -> Self {
Self::File(ops)
}
}
const DIR_PERMISSION: NodePermission = NodePermission::from_bits_truncate(0o755);
fn mount_at(fs: &FsContext, path: &str, mount_fs: Filesystem) -> LinuxResult<()> {
if fs.resolve(path).is_err() {
fs.create_dir(path, DIR_PERMISSION)?;
}
fs.resolve(path)?.mount(&mount_fs)?;
info!("Mounted {} at {}", mount_fs.name(), path);
Ok(())
}
pub fn mount_all() -> LinuxResult<()> {
info!("Initialize pseudofs...");
let fs = FS_CONTEXT.lock();
mount_at(&fs, "/dev", dev::new_devfs())?;
#[cfg(feature = "plat-dyn")]
mount_at(&fs, "/dev/bus/usb", usbfs::new_usbfs()?)?;
mount_at(&fs, "/dev/shm", tmp::MemoryFs::new())?;
mount_at(&fs, "/tmp", tmp::MemoryFs::new())?;
mount_at(&fs, "/proc", proc::new_procfs())?;
#[cfg(feature = "plat-dyn")]
mount_at(&fs, "/sys", usbfs::new_sysfs())?;
#[cfg(not(feature = "plat-dyn"))]
mount_at(&fs, "/sys", sysfs::new_sysfs())?;
drop(fs);
#[cfg(feature = "dev-log")]
dev::bind_dev_log().expect("Failed to bind /dev/log");
Ok(())
}