-
Notifications
You must be signed in to change notification settings - Fork 55
Open
Milestone
Description
https://github.com/arceos-hypervisor/axvfs
设计目标
创建一个统一、通用、功能完整的 VFS,要求:
✅ 支持相对路径操作(通过文件/目录句柄)
✅ 提供完整的元数据接口
✅ 支持软链接和硬链接
✅ 解决并发访问问题
✅ 通用性:三个平台都能方便接入
✅ 简洁性:接口设计清晰,易于实现
结合 axfs_vfs 和 axfs-ng-vfs,实现统一的虚拟文件系统 axvfs,具有标准通用的接口,arceos,starry和axvisor 分别实现对应的 api 层接入 axvfs。
对文件或路径的操作依然通过std进入arceos_api,然后下层的实现是一套统一的实现方案。
如果有对于starry或axvisor特有的结构或接口,可以通过feature (monolithic & hypervisor)控制。
代码结构
axvfs/
├── Cargo.toml
├── README.md # 使用指南
└── src/
├── file_handle.rs # 文件句柄
├── dir_handle.rs # 目录句柄
├── types.rs # 核心类型
├── traits.rs # Trait 定义
├── path.rs # 路径操作
├── mount.rs # 挂载管理
└── lib.rs # 主库文件
核心模块设计
1. 核心类型 (types.rs)
定义文件系统的基础类型:
// 节点类型
pub enum NodeType {
RegularFile, Directory, Symlink,
CharDevice, BlockDevice, Fifo, Socket
}
// 权限模式 (POSIX 风格)
pub struct NodePermission: u16 {
OWNER_READ, OWNER_WRITE, OWNER_EXEC,
GROUP_READ, GROUP_WRITE, GROUP_EXEC,
OTHER_READ, OTHER_WRITE, OTHER_EXEC,
SET_UID, SET_GID, STICKY
}
// 完整元数据
pub struct Metadata {
device: u64, // 设备 ID
inode: u64, // inode 号
nlink: u64, // 硬链接计数
mode: NodePermission, // 权限
node_type: NodeType, // 节点类型
uid: u32, // 所有者用户 ID
gid: u32, // 所有者组 ID
size: u64, // 大小
block_size: u64, // 块大小
blocks: u64, // 分配的块数
rdev: DeviceId, // 设备 ID(特殊文件)
atime: Duration, // 访问时间
mtime: Duration, // 修改时间
ctime: Duration, // 状态改变时间
}2. 核心 Trait (traits.rs)
FilesystemOps Trait
文件系统操作接口:
pub trait FilesystemOps: Send + Sync {
fn name(&self) -> &str; // 文件系统名称
fn statfs(&self) -> VfsResult<FileSystemInfo>; // 文件系统统计
fn sync(&self) -> VfsResult<()>; // 同步
fn mount(&self, mount_point: &str) -> VfsResult<()>; // 挂载
fn unmount(&self) -> VfsResult<()>; // 卸载
fn root(&self) -> Arc<dyn VnodeOps>; // 根目录
}VnodeOps Trait
虚拟节点操作接口:
pub trait VnodeOps: Send + Sync + Any {
// 基本信息
fn filesystem(&self) -> &Arc<dyn FilesystemOps>;
fn inode(&self) -> u64;
fn node_type(&self) -> NodeType;
fn metadata(&self) -> VfsResult<Metadata>;
fn set_metadata(&self, update: MetadataUpdate) -> VfsResult<()>;
fn parent(&self) -> VfsResult<Option<Arc<dyn VnodeOps>>>;
fn sync(&self, data_only: bool) -> VfsResult<()>;
// 文件操作
fn read_at(&self, offset: u64, buf: &mut [u8]) -> VfsResult<usize>;
fn write_at(&self, offset: u64, buf: &[u8]) -> VfsResult<usize>;
fn truncate(&self, size: u64) -> VfsResult<()>;
// 目录操作
fn lookup(&self, name: &str) -> VfsResult<Arc<dyn VnodeOps>>;
fn create(&self, name: &str, node_type: NodeType, mode: NodePermission)
-> VfsResult<Arc<dyn VnodeOps>>;
fn remove(&self, name: &str) -> VfsResult<()>;
fn link(&self, name: &str, target: &Arc<dyn VnodeOps>) -> VfsResult<()>;
fn unlink(&self, name: &str) -> VfsResult<()>;
fn symlink(&self, name: &str, target: &str) -> VfsResult<()>;
fn readlink(&self) -> VfsResult<String>;
fn rename(&self, old_name: &str, new_dir: &Arc<dyn VnodeOps>, new_name: &str)
-> VfsResult<()>;
fn readdir(&self, offset: usize, sink: &mut dyn DirEntrySink) -> VfsResult<usize>;
fn mkdir(&self, name: &str, mode: NodePermission) -> VfsResult<Arc<dyn VnodeOps>>;
fn rmdir(&self, name: &str) -> VfsResult<()>;
}3. 文件/目录句柄 (file_handle.rs, dir_handle.rs)
FileHandle
支持位置跟踪的文件描述符:
pub struct FileHandle {
vnode: Vnode, // 关联的 vnode
offset: AtomicU64, // 当前位置(原子操作,并发安全)
flags: OpenFlags, // 打开标志
id: u64, // 句柄 ID
}
impl FileHandle {
pub fn read(&self, buf: &mut [u8]) -> VfsResult<usize>;
pub fn write(&self, buf: &[u8]) -> VfsResult<usize>;
pub fn seek(&self, offset: i64, whence: u8) -> VfsResult<u64>;
pub fn truncate(&self, size: u64) -> VfsResult<()>;
pub fn sync(&self, data_only: bool) -> VfsResult<()>;
}DirHandle
支持相对路径操作的目录描述符:
pub struct DirHandle {
vnode: Vnode, // 关联的目录 vnode
offset: AtomicU64, // 读取位置
id: u64,
}
impl DirHandle {
// 相对路径操作
pub fn lookup(&self, name: &str) -> VfsResult<Vnode>;
pub fn create_file(&self, name: &str, mode: NodePermission)
-> VfsResult<Vnode>;
pub fn create_dir(&self, name: &str, mode: NodePermission)
-> VfsResult<Vnode>;
pub fn readdir(&self) -> VfsResult<Vec<DirEntry>>;
pub fn symlink(&self, name: &str, target: &str) -> VfsResult<()>;
pub fn readlink(&self, name: &str) -> VfsResult<String>;
pub fn rename(&self, old_name: &str, new_dir: &DirHandle, new_name: &str)
-> VfsResult<()>;
}相对路径示例:
// openat 等价操作
fn sys_openat(dirfd: i32, path: &str, flags: OpenFlags) -> VfsResult<i32> {
let vnode = if path.starts_with('/') {
// 绝对路径
mount_mgr.lookup(Path::new(path))?
} else {
// 相对路径 - 使用 dir_handle
let dir_handle = dir_table.get(dirfd as usize)?;
dir_handle.lookup(path)?
};
Ok(file_table.insert(FileHandle::new(vnode, flags)?)? as i32)
}4. 路径操作 (path.rs)
完整的路径解析和操作功能:
pub struct Path {
inner: str,
}
pub struct PathBuf {
inner: String,
}
impl Path {
pub fn components(&self) -> Components;
pub fn parent(&self) -> Option<&Path>;
pub fn file_name(&self) -> Option<&str>;
pub fn join(&self, path: &Path) -> PathBuf;
pub fn normalize(&self) -> PathBuf; // 处理 . 和 ..
pub fn is_absolute(&self) -> bool;
}5. 挂载管理 (mount.rs)
管理多个文件系统的挂载和路径解析:
pub struct MountManager {
mounts_by_device: Mutex<BTreeMap<u64, Arc<MountPoint>>>,
mounts_by_path: Mutex<BTreeMap<String, Arc<MountPoint>>>,
root_mount: Mutex<Option<Arc<MountPoint>>>,
}
impl MountManager {
pub fn set_root(&self, filesystem: Arc<dyn FilesystemOps>) -> VfsResult<()>;
pub fn mount(&self, mount_path: &Path, filesystem: Arc<dyn FilesystemOps>)
-> VfsResult<Arc<MountPoint>>;
pub fn unmount(&self, mount_path: &Path) -> VfsResult<()>;
pub fn resolve_mount(&self, path: &Path) -> VfsResult<Arc<MountPoint>>;
pub fn lookup(&self, path: &Path) -> VfsResult<Vnode>;
pub fn statfs(&self, path: &Path) -> VfsResult<FileSystemInfo>;
pub fn build_path(&self, mount: &MountPoint, vnode: &Vnode) -> VfsResult<PathBuf>;
}关键实现:
resolve_mount(): 查找最长匹配的挂载点lookup(): 解析路径到 vnode,支持挂载点跨越build_path(): 从 vnode 向上遍历构建完整路径,用于目录句柄的相对路径操作
6. 文件表和目录表 (file_handle.rs, dir_handle.rs)
管理打开的文件和目录描述符:
pub struct FileTable {
handles: Mutex<Vec<Option<Arc<FileHandle>>>>,
}
impl FileTable {
pub fn new() -> Self;
pub fn insert(&self, file: FileHandle) -> VfsResult<usize>;
pub fn get(&self, fd: usize) -> VfsResult<Arc<FileHandle>>;
pub fn remove(&self, fd: usize) -> VfsResult<()>;
}
pub struct DirTable {
handles: Mutex<Vec<Option<Arc<DirHandle>>>>,
}
impl DirTable {
pub fn new() -> Self;
pub fn insert(&self, dir: DirHandle) -> VfsResult<usize>;
pub fn get(&self, fd: usize) -> VfsResult<Arc<DirHandle>>;
pub fn remove(&self, fd: usize) -> VfsResult<()>;
}特性:
- 线程安全的句柄管理
- 支持 fd 分配和释放
- 支持句柄克隆和共享
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Type
Projects
Status
No status