Skip to content
This repository was archived by the owner on Nov 26, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions apps/oscomp/judge_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,20 +453,20 @@ def get_runner(name):
"test_chdir",
"test_execve",
"test_pipe",
# "test_close",
# "test_dup",
# "test_dup2",
# "test_fstat",
# "test_getcwd",
# "test_mkdir",
# "test_open",
# "test_read",
# "test_unlink",
# "test_write",
# "test_openat",
# "test_getdents",
# "test_mount",
# "test_umount",
"test_close",
"test_dup",
"test_dup2",
"test_fstat",
"test_getcwd",
"test_mkdir",
"test_open",
"test_read",
"test_unlink",
"test_write",
"test_openat",
"test_getdents",
"test_mount",
"test_umount",
]

if __name__ == '__main__':
Expand Down
28 changes: 14 additions & 14 deletions scripts/oscomp_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,20 @@ basic_testlist=(
"/$LIBC/basic/chdir"
"/$LIBC/basic/execve"
"/$LIBC/basic/pipe"
# "/$LIBC/basic/close"
# "/$LIBC/basic/dup"
# "/$LIBC/basic/dup2"
# "/$LIBC/basic/fstat"
# "/$LIBC/basic/getcwd"
# "/$LIBC/basic/mkdir_"
# "/$LIBC/basic/open"
# "/$LIBC/basic/read"
# "/$LIBC/basic/unlink"
# "/$LIBC/basic/write"
# "/$LIBC/basic/openat"
# "/$LIBC/basic/getdents"
# "/$LIBC/basic/mount"
# "/$LIBC/basic/umount"
"/$LIBC/basic/close"
"/$LIBC/basic/dup"
"/$LIBC/basic/dup2"
"/$LIBC/basic/fstat"
"/$LIBC/basic/getcwd"
"/$LIBC/basic/mkdir_"
"/$LIBC/basic/open"
"/$LIBC/basic/read"
"/$LIBC/basic/unlink"
"/$LIBC/basic/write"
"/$LIBC/basic/openat"
"/$LIBC/basic/getdents"
"/$LIBC/basic/mount"
"/$LIBC/basic/umount"
)
busybox_testlist=("/$LIBC/busybox sh /$LIBC/busybox_testcode.sh")
iozone_testlist=("/$LIBC/busybox sh /$LIBC/iozone_testcode.sh")
Expand Down
2 changes: 2 additions & 0 deletions src/syscall_imp/fs/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
mod ctl;
mod fd_ops;
mod io;
mod mount;
mod pipe;
mod stat;

pub(crate) use self::ctl::*;
pub(crate) use self::fd_ops::*;
pub(crate) use self::io::*;
pub(crate) use self::mount::*;
pub(crate) use self::pipe::*;
pub(crate) use self::stat::*;
138 changes: 138 additions & 0 deletions src/syscall_imp/fs/mount.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
use alloc::vec::Vec;
use arceos_posix_api::{AT_FDCWD, FilePath, handle_file_path};
use axerrno::{LinuxError, LinuxResult};
use axsync::Mutex;
use core::ffi::{c_char, c_void};

use crate::ptr::UserConstPtr;

pub fn sys_mount(
source: UserConstPtr<c_char>,
target: UserConstPtr<c_char>,
fs_type: UserConstPtr<c_char>,
_flags: i32,
_data: UserConstPtr<c_void>,
) -> LinuxResult<isize> {
info!("sys_mount");
let source = source.get_as_null_terminated()?;
let target = target.get_as_null_terminated()?;
let fs_type = fs_type.get_as_str()?;
let device_path = handle_file_path(AT_FDCWD, Some(source.as_ptr() as _), false)?;
let mount_path = handle_file_path(AT_FDCWD, Some(target.as_ptr() as _), true)?;
info!(
"mount {:?} to {:?} with fs_type={:?}",
device_path, mount_path, fs_type
);

if fs_type != "vfat" {
debug!("fs_type can only be vfat.");
return Err(LinuxError::EPERM);
}

if !mount_path.exists() {
debug!("mount path not exist");
return Err(LinuxError::EPERM);
}

if check_mounted(&mount_path) {
debug!("mount path includes mounted fs");
return Err(LinuxError::EPERM);
}

if !mount_fat_fs(&device_path, &mount_path) {
debug!("mount error");
return Err(LinuxError::EPERM);
}
Ok(0)
}

pub fn sys_umount2(target: UserConstPtr<c_char>, flags: i32) -> LinuxResult<isize> {
info!("sys_umount2");
let target = target.get_as_null_terminated()?;
let mount_path = handle_file_path(AT_FDCWD, Some(target.as_ptr() as _), true)?;
if flags != 0 {
debug!("flags unimplemented");
return Err(LinuxError::EPERM);
}

if !mount_path.exists() {
debug!("mount path not exist");
return Err(LinuxError::EPERM);
}

if !umount_fat_fs(&mount_path) {
debug!("umount error");
return Err(LinuxError::EPERM);
}
Ok(0)
}

/// Mounted File System
/// "Mount" means read&write a file as a file system now
pub struct MountedFs {
//pub inner: Arc<Mutex<FATFileSystem>>,
pub device: FilePath,
pub mnt_dir: FilePath,
}

impl MountedFs {
pub fn new(device: &FilePath, mnt_dir: &FilePath) -> Self {
assert!(
device.is_file() && mnt_dir.is_dir(),
"device must be a file and mnt_dir must be a dir"
);
Self {
device: device.clone(),
mnt_dir: mnt_dir.clone(),
}
}
#[allow(unused)]
pub fn device(&self) -> FilePath {
self.device.clone()
}

pub fn mnt_dir(&self) -> FilePath {
self.mnt_dir.clone()
}
}

/// List of mounted file system
/// Note that the startup file system is not in the vec, but in mod.rs
static MOUNTED: Mutex<Vec<MountedFs>> = Mutex::new(Vec::new());

/// Mount a fatfs device
pub fn mount_fat_fs(device_path: &FilePath, mount_path: &FilePath) -> bool {
// device_path needs symlink lookup, but mount_path does not
// only opened files will be added to the symlink table for now, so do not convert now
// debug!("mounting {} to {}", device_path.path(), mount_path.path());
// if let Some(true_device_path) = real_path(device_path) {
if mount_path.exists() {
MOUNTED.lock().push(MountedFs::new(device_path, mount_path));
info!(
"mounted {} to {}",
device_path.as_str(),
mount_path.as_str()
);
return true;
}
info!(
"mount failed: {} to {}",
device_path.as_str(),
mount_path.as_str()
);
false
}

/// unmount a fatfs device
pub fn umount_fat_fs(mount_path: &FilePath) -> bool {
let mut mounted = MOUNTED.lock();
let length_before_deletion = mounted.len();
mounted.retain(|m| m.mnt_dir() != *mount_path);
length_before_deletion > mounted.len()
}

/// check if a path is mounted
pub fn check_mounted(path: &FilePath) -> bool {
let mounted = MOUNTED.lock();
mounted.iter().any(|m| path.starts_with(&m.mnt_dir()))
}
8 changes: 8 additions & 0 deletions src/syscall_imp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,14 @@ fn handle_syscall(tf: &TrapFrame, syscall_num: usize) -> isize {
Sysno::unlinkat => sys_unlinkat(tf.arg0() as _, tf.arg1().into(), tf.arg2() as _),
Sysno::uname => sys_uname(tf.arg0().into()),
Sysno::fstat => sys_fstat(tf.arg0() as _, tf.arg1().into()),
Sysno::mount => sys_mount(
tf.arg0().into(),
tf.arg1().into(),
tf.arg2().into(),
tf.arg3() as _,
tf.arg4().into(),
) as _,
Sysno::umount2 => sys_umount2(tf.arg0().into(), tf.arg1() as _) as _,
#[cfg(target_arch = "x86_64")]
Sysno::newfstatat => sys_fstatat(
tf.arg0() as _,
Expand Down