Rename some variables and let src_name_addr can be NULL for some mount operations

This commit is contained in:
Chen Chengjun 2025-11-03 03:29:11 +00:00 committed by Tate, Hongliang Tian
parent 1ef7a1a11b
commit 6f8877f252
1 changed files with 60 additions and 32 deletions

View File

@ -13,29 +13,29 @@ use crate::{
};
pub fn sys_mount(
devname_addr: Vaddr,
dirname_addr: Vaddr,
fstype_addr: Vaddr,
src_name_addr: Vaddr,
dst_name_addr: Vaddr,
fs_type_addr: Vaddr,
flags: u64,
// The `data` argument is interpreted by the different filesystems.
// Typically it is a string of comma-separated options understood by
// this filesystem. The current implementation only considers the case
// where it is `NULL`. Because it should be interpreted by the specific filesystems.
data: Vaddr,
data_addr: Vaddr,
ctx: &Context,
) -> Result<SyscallReturn> {
let user_space = ctx.user_space();
let devname = user_space.read_cstring(devname_addr, MAX_FILENAME_LEN)?;
let dirname = user_space.read_cstring(dirname_addr, MAX_FILENAME_LEN)?;
let dst_name = ctx
.user_space()
.read_cstring(dst_name_addr, MAX_FILENAME_LEN)?;
let mount_flags = MountFlags::from_bits_truncate(flags as u32);
debug!(
"devname = {:?}, dirname = {:?}, fstype = 0x{:x}, flags = {:?}, data = 0x{:x}",
devname, dirname, fstype_addr, mount_flags, data,
"src_name_addr = 0x{:x}, dst_name = {:?}, fstype = 0x{:x}, flags = {:?}, data_addr = 0x{:x}",
src_name_addr, dst_name, fs_type_addr, mount_flags, data_addr,
);
let dst_path = {
let dirname = dirname.to_string_lossy();
let fs_path = FsPath::from_fd_and_path(AT_FDCWD, &dirname)?;
let dst_name = dst_name.to_string_lossy();
let fs_path = FsPath::from_fd_and_path(AT_FDCWD, &dst_name)?;
ctx.thread_local
.borrow_fs()
.resolver()
@ -47,10 +47,10 @@ pub fn sys_mount(
// If `MS_BIND` is specified, only the mount flags are changed.
do_remount_mnt(&dst_path, mount_flags, ctx)?;
} else if mount_flags.contains(MountFlags::MS_REMOUNT) {
do_remount_mnt_and_fs(&dst_path, mount_flags, data, ctx)?;
do_remount_mnt_and_fs(&dst_path, mount_flags, data_addr, ctx)?;
} else if mount_flags.contains(MountFlags::MS_BIND) {
do_bind_mount(
devname,
src_name_addr,
dst_path,
mount_flags.contains(MountFlags::MS_REC),
ctx,
@ -58,9 +58,16 @@ pub fn sys_mount(
} else if mount_flags.intersects(MS_PROPAGATION) {
do_change_type(dst_path, mount_flags, ctx)?;
} else if mount_flags.contains(MountFlags::MS_MOVE) {
do_move_mount_old(devname, dst_path, ctx)?;
do_move_mount_old(src_name_addr, dst_path, ctx)?;
} else {
do_new_mount(devname, mount_flags, fstype_addr, dst_path, data, ctx)?;
do_new_mount(
src_name_addr,
mount_flags,
fs_type_addr,
dst_path,
data_addr,
ctx,
)?;
}
Ok(SyscallReturn::Return(0))
@ -74,13 +81,18 @@ fn do_remount_mnt(path: &Path, flags: MountFlags, ctx: &Context) -> Result<()> {
}
/// Remounts the filesystem with new flags and data.
fn do_remount_mnt_and_fs(path: &Path, flags: MountFlags, data: Vaddr, ctx: &Context) -> Result<()> {
fn do_remount_mnt_and_fs(
path: &Path,
flags: MountFlags,
data_addr: Vaddr,
ctx: &Context,
) -> Result<()> {
let per_mount_flags = PerMountFlags::from(flags);
let fs_flags = FsFlags::from(flags);
let data = if data == 0 {
let data = if data_addr == 0 {
None
} else {
Some(ctx.user_space().read_cstring(data, MAX_FILENAME_LEN)?)
Some(ctx.user_space().read_cstring(data_addr, MAX_FILENAME_LEN)?)
};
path.remount(per_mount_flags, Some(fs_flags), data, ctx)
@ -90,8 +102,16 @@ fn do_remount_mnt_and_fs(path: &Path, flags: MountFlags, data: Vaddr, ctx: &Cont
///
/// If recursive is true, then bind the mount recursively.
/// Such as use user command `mount --rbind src dst`.
fn do_bind_mount(src_name: CString, dst_path: Path, recursive: bool, ctx: &Context) -> Result<()> {
fn do_bind_mount(
src_name_addr: Vaddr,
dst_path: Path,
recursive: bool,
ctx: &Context,
) -> Result<()> {
let src_path = {
let src_name = ctx
.user_space()
.read_cstring(src_name_addr, MAX_FILENAME_LEN)?;
let src_name = src_name.to_string_lossy();
let fs_path = FsPath::from_fd_and_path(AT_FDCWD, &src_name)?;
ctx.thread_local
@ -139,8 +159,11 @@ fn do_change_type(target_path: Path, flags: MountFlags, ctx: &Context) -> Result
}
/// Moves a mount from src location to dst location.
fn do_move_mount_old(src_name: CString, dst_path: Path, ctx: &Context) -> Result<()> {
fn do_move_mount_old(src_name_addr: Vaddr, dst_path: Path, ctx: &Context) -> Result<()> {
let src_path = {
let src_name = ctx
.user_space()
.read_cstring(src_name_addr, MAX_FILENAME_LEN)?;
let src_name = src_name.to_string_lossy();
let fs_path = FsPath::from_fd_and_path(AT_FDCWD, &src_name)?;
ctx.thread_local
@ -157,48 +180,53 @@ fn do_move_mount_old(src_name: CString, dst_path: Path, ctx: &Context) -> Result
/// Mounts a new filesystem.
fn do_new_mount(
devname: CString,
src_name_addr: Vaddr,
flags: MountFlags,
fs_type: Vaddr,
fs_type_addr: Vaddr,
target_path: Path,
data: Vaddr,
data_addr: Vaddr,
ctx: &Context,
) -> Result<()> {
if target_path.type_() != InodeType::Dir {
return_errno_with_message!(Errno::ENOTDIR, "mountpoint must be directory");
};
let fs_type = ctx.user_space().read_cstring(fs_type, MAX_FILENAME_LEN)?;
let fs_type = ctx
.user_space()
.read_cstring(fs_type_addr, MAX_FILENAME_LEN)?;
if fs_type.is_empty() {
return_errno_with_message!(Errno::EINVAL, "fs_type is empty");
}
let fs = get_fs(devname, flags, fs_type, data, ctx)?;
let fs = get_fs(src_name_addr, flags, fs_type, data_addr, ctx)?;
target_path.mount(fs, flags.into(), ctx)?;
Ok(())
}
/// Gets the filesystem by fs_type and devname.
fn get_fs(
devname: CString,
src_name_addr: Vaddr,
flags: MountFlags,
fs_type: CString,
data: Vaddr,
data_addr: Vaddr,
ctx: &Context,
) -> Result<Arc<dyn FileSystem>> {
let user_space = ctx.user_space();
let data = if data == 0 {
let data = if data_addr == 0 {
None
} else {
Some(user_space.read_cstring(data, MAX_FILENAME_LEN)?)
Some(user_space.read_cstring(data_addr, MAX_FILENAME_LEN)?)
};
let fs_type = fs_type
.to_str()
.map_err(|_| Error::with_message(Errno::ENODEV, "Invalid file system type"))?;
let fs_type = crate::fs::registry::look_up(fs_type)
.ok_or(Error::with_message(Errno::EINVAL, "Invalid fs type"))?;
.map_err(|_| Error::with_message(Errno::ENODEV, "invalid file system type"))?;
let fs_type = crate::fs::registry::look_up(fs_type).ok_or(Error::with_message(
Errno::ENODEV,
"the filesystem is not configured in the kernel",
))?;
let disk = if fs_type.properties().contains(FsProperties::NEED_DISK) {
let devname = user_space.read_cstring(src_name_addr, MAX_FILENAME_LEN)?;
Some(
aster_block::get_device(devname.to_str().unwrap())
.ok_or(Error::with_message(Errno::ENOENT, "device does not exist"))?,