Skip to content
Open
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
2 changes: 1 addition & 1 deletion etc/syscalls_linux_aarch64.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
| 0x25 (37) | linkat | (int olddfd, const char *oldname, int newdfd, const char *newname, int flags) | __arm64_sys_linkat | true |
| 0x26 (38) | renameat | (int olddfd, const char *oldname, int newdfd, const char *newname) | __arm64_sys_renameat | true |
| 0x27 (39) | umount | (char *name, int flags) | __arm64_sys_umount | false |
| 0x28 (40) | mount | (char *dev_name, char *dir_name, char *type, unsigned long flags, void *data) | __arm64_sys_mount | false |
| 0x28 (40) | mount | (char *dev_name, char *dir_name, char *type, unsigned long flags, void *data) | __arm64_sys_mount | partial |
| 0x29 (41) | pivot_root | (const char *new_root, const char *put_old) | __arm64_sys_pivot_root | false |
| 0x2b (43) | statfs | (const char *pathname, struct statfs *buf) | __arm64_sys_statfs | dummy |
| 0x2c (44) | fstatfs | (unsigned int fd, struct statfs *buf) | __arm64_sys_fstatfs | dummy |
Expand Down
11 changes: 11 additions & 0 deletions src/arch/arm64/exceptions/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use crate::{
ioctl::sys_ioctl,
iov::{sys_preadv, sys_preadv2, sys_pwritev, sys_pwritev2, sys_readv, sys_writev},
listxattr::{sys_flistxattr, sys_listxattr, sys_llistxattr},
mount::sys_mount,
removexattr::{sys_fremovexattr, sys_lremovexattr, sys_removexattr},
rw::{sys_pread64, sys_pwrite64, sys_read, sys_write},
seek::sys_lseek,
Expand Down Expand Up @@ -224,6 +225,16 @@ pub async fn handle_syscall() {
)
.await
}
0x28 => {
sys_mount(
TUA::from_value(arg1 as _),
TUA::from_value(arg2 as _),
TUA::from_value(arg3 as _),
arg4 as _,
TUA::from_value(arg5 as _),
)
.await
}
0x2b | 0x2c => Err(KernelError::NotSupported),
0x2d => sys_truncate(TUA::from_value(arg1 as _), arg2 as _).await,
0x2e => sys_ftruncate(arg1.into(), arg2 as _).await,
Expand Down
27 changes: 26 additions & 1 deletion src/drivers/fs/proc/task/fd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::drivers::fs::proc::{get_inode_id, procfs};
use crate::process::fd_table::Fd;
use crate::process::{TaskDescriptor, find_task_by_descriptor};
use crate::sched::current::current_task_shared;
use alloc::borrow::ToOwned;
use alloc::boxed::Box;
use alloc::format;
use alloc::string::ToString;
Expand All @@ -11,6 +12,7 @@ use async_trait::async_trait;
use libkernel::error::Result;
use libkernel::error::{FsError, KernelError};
use libkernel::fs::attr::FileAttr;
use libkernel::fs::pathbuf::PathBuf;
use libkernel::fs::{
DirStream, Dirent, FileType, Filesystem, Inode, InodeId, SimpleDirStream, SimpleFile,
};
Expand Down Expand Up @@ -115,7 +117,11 @@ impl ProcFdFile {
Self {
id: inode_id,
attr: FileAttr {
file_type: FileType::File,
file_type: if fd_info {
FileType::File
} else {
FileType::Symlink
},
// Define appropriate file attributes for fdinfo file.
..FileAttr::default()
},
Expand Down Expand Up @@ -151,4 +157,23 @@ impl SimpleFile for ProcFdFile {
Err(KernelError::NotSupported)
}
}

async fn readlink(&self) -> Result<PathBuf> {
if !self.fd_info {
if let Some(task) = find_task_by_descriptor(&self.desc) {
let Some(file) = task.fd_table.lock_save_irq().get(Fd(self.fd)) else {
return Err(FsError::NotFound.into());
};
if let Some(path) = file.path() {
Ok(path.to_owned())
} else {
todo!();
}
} else {
Err(FsError::NotFound.into())
}
} else {
Err(KernelError::NotSupported)
}
}
}
20 changes: 20 additions & 0 deletions src/fs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ impl VfsState {
self.mounts.insert(mount_point_id, mount);
}

/// Removes a mount point by its inode ID.
fn remove_mount(&mut self, mount_point_id: &InodeId) -> Option<()> {
let mount = self.mounts.remove(mount_point_id)?;
self.filesystems.remove(&mount.fs.id())?;
Some(())
}

/// Checks if an inode is a mount point and returns the root inode of the
/// mounted filesystem if it is.
fn get_mount_root(&self, inode_id: &InodeId) -> Option<Arc<dyn Inode>> {
Expand Down Expand Up @@ -177,6 +184,19 @@ impl VFS {
Ok(())
}

#[expect(unused)]
pub async fn unmount(&self, mount_point: Arc<dyn Inode>) -> Result<()> {
let mount_point_id = mount_point.id();

// Lock the state and remove the mount.
self.state
.lock_save_irq()
.remove_mount(&mount_point_id)
.ok_or(FsError::NotFound)?;

Ok(())
}

/// Resolves a path string to an Inode, starting from a given root for
/// relative paths.
pub async fn resolve_path(
Expand Down
1 change: 1 addition & 0 deletions src/fs/syscalls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub mod getxattr;
pub mod ioctl;
pub mod iov;
pub mod listxattr;
pub mod mount;
pub mod open;
pub mod removexattr;
pub mod rw;
Expand Down
93 changes: 93 additions & 0 deletions src/fs/syscalls/mount.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
use crate::fs::VFS;
use crate::memory::uaccess::cstr::UserCStr;
use crate::sched::current::current_task_shared;
use bitflags::bitflags;
use core::ffi::c_char;
use libkernel::error::{KernelError, Result};
use libkernel::fs::path::Path;
use libkernel::memory::address::{TUA, UA};

bitflags! {
#[derive(Debug)]
pub struct MountFlags: u64 {
const MS_RDONLY = 1;
const MS_NOSUID = 2;
const MS_NODEV = 4;
const MS_NOEXEC = 8;
const MS_SYNCHRONOUS = 16;
const MS_REMOUNT = 32;
const MS_MANDLOCK = 64;
const MS_DIRSYNC = 128;
const NOSYMFOLLOW = 256;
const MS_NOATIME = 1024;
const MS_NODIRATIME = 2048;
const MS_BIND = 4096;
const MS_MOVE = 8192;
const MS_REC = 16384;
const MS_VERBOSE = 32768;
const MS_SILENT = 65536;
const MS_POSIXACL = 1 << 16;
const MS_UNBINDABLE = 1 << 17;
const MS_PRIVATE = 1 << 18;
const MS_SLAVE = 1 << 19;
const MS_SHARED = 1 << 20;
const MS_RELATIME = 1 << 21;
const MS_KERNMOUNT = 1 << 22;
const MS_I_VERSION = 1 << 23;
const MS_STRICTATIME = 1 << 24;
const MS_LAZYTIME = 1 << 25;
const MS_SUBMOUNT = 1 << 26;
const MS_NOREMOTELOCK = 1 << 27;
const MS_NOSEC = 1 << 28;
const MS_BORN = 1 << 29;
const MS_ACTIVE = 1 << 30;
const MS_NOUSER = 1 << 31;
}
}

pub async fn sys_mount(
dev_name: TUA<c_char>,
dir_name: TUA<c_char>,
type_: TUA<c_char>,
flags: i64,
_data: UA,
) -> Result<usize> {
let flags = MountFlags::from_bits_truncate(flags as u64);
if flags.contains(MountFlags::MS_REC) {
// TODO: Handle later
return Ok(0);
}
let mut buf = [0u8; 1024];
let dev_name = UserCStr::from_ptr(dev_name)
.copy_from_user(&mut buf)
.await
.ok();
let mut buf = [0u8; 1024];
let dir_name = UserCStr::from_ptr(dir_name)
.copy_from_user(&mut buf)
.await?;
let mount_point = VFS
.resolve_path(
Path::new(dir_name),
VFS.root_inode(),
&current_task_shared(),
)
.await?;
let mut buf = [0u8; 1024];
let _type = UserCStr::from_ptr(type_)
.copy_from_user(&mut buf)
.await
.ok();
if let Some(dev_name) = dev_name {
let dev_name = match dev_name {
"proc" => "procfs",
"devtmpfs" => "devfs",
"cgroup2" => "cgroupfs",
s => s,
};
VFS.mount(mount_point, dev_name, None).await?;
Ok(0)
} else {
Err(KernelError::NotSupported)
}
}