Skip to content

Commit

Permalink
Add yield and chmod syscalls
Browse files Browse the repository at this point in the history
  • Loading branch information
rafalmiel committed Nov 8, 2023
1 parent 81d08ca commit c3345f9
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 37 deletions.
9 changes: 9 additions & 0 deletions cykusz-rs/src/kernel/fs/ext2/inode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use intrusive_collections::LinkedList;

use syscall_defs::poll::PollEventFlags;
use syscall_defs::{FileType, OpenFlags};
use syscall_defs::stat::Mode;

use crate::arch::mm::PAGE_SIZE;
use crate::kernel::fs::cache::Cacheable;
Expand Down Expand Up @@ -912,6 +913,14 @@ impl INode for LockedExt2INode {
Ok(())
}

fn chmod(&self, mode: Mode) -> Result<()> {
let mut node = self.d_inode_writer();

node.set_perm(mode.bits() as u16);

Ok(())
}

fn truncate(&self, size: usize) -> Result<()> {
if self.ftype()? != FileType::File {
return Err(FsError::NotFile);
Expand Down
4 changes: 4 additions & 0 deletions cykusz-rs/src/kernel/fs/inode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ pub trait INode: Send + Sync + DowncastSync {
return Err(FsError::NotSupported);
}

fn chmod(&self, _mode: syscall_defs::stat::Mode) -> Result<()> {
return Err(FsError::NotSupported);
}

fn truncate(&self, _size: usize) -> Result<()> {
return Err(FsError::NotSupported);
}
Expand Down
8 changes: 5 additions & 3 deletions cykusz-rs/src/kernel/syscall/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub fn syscall_handler(num: u64, a: u64, b: u64, c: u64, d: u64, e: u64, f: u64)
SYS_WRITE => sys::sys_write(a, b, c).maybe_into_erestartsys(),
SYS_OPEN => sys::sys_open(a, b, c, d).maybe_into_erestartsys(),
SYS_CLOSE => sys::sys_close(a),
SYS_CHDIR => sys::sys_chdir(a, b),
SYS_CHDIR => sys::sys_chdir(a, b, c),
SYS_GETCWD => sys::sys_getcwd(a, b),
SYS_MKDIR => sys::sys_mkdir(a, b, c),
SYS_GETDENTS => sys::sys_getdents(a, b, c),
Expand All @@ -58,8 +58,8 @@ pub fn syscall_handler(num: u64, a: u64, b: u64, c: u64, d: u64, e: u64, f: u64)
SYS_SYMLINK => sys::sys_symlink(a, b, c, d, e),
SYS_RMDIR => sys::sys_rmdir(a, b),
SYS_UNLINK => sys::sys_unlink(a, b, c, d),
SYS_LINK => sys::sys_link(a, b, c, d),
SYS_RENAME => sys::sys_rename(a, b, c, d),
SYS_LINK => sys::sys_link(a, b, c, d, e, f),
SYS_RENAME => sys::sys_rename(a, b, c, d, e, f),
SYS_FORK => sys::sys_fork(),
SYS_EXEC => sys::sys_exec(a, b, c, d, e, f),
SYS_FCNTL => sys::sys_fcntl(a, b, c),
Expand Down Expand Up @@ -97,6 +97,8 @@ pub fn syscall_handler(num: u64, a: u64, b: u64, c: u64, d: u64, e: u64, f: u64)
SYS_GETPGID => sys::sys_getpgid(a),
SYS_TRUNCATE => sys::sys_truncate(a, b),
SYS_READLINK => sys::sys_readlink(a, b, c, d, e, f),
SYS_YIELD => sys::sys_yield(),
SYS_CHMOD => sys::sys_chmod(a, b, c, d,e),
a => {
logln!("NO SYS????? {}", a);
Err(SyscallError::ENOSYS)
Expand Down
135 changes: 103 additions & 32 deletions cykusz-rs/src/kernel/syscall/sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use syscall_defs::{
AtFlags, FcntlCmd, FcntlSetFDFlags, FileType, MMapFlags, MMapProt, OpenFD, SyscallResult,
};
use syscall_defs::{OpenFlags, SyscallError};
use syscall_defs::stat::Mode;

use crate::kernel::fs::dirent::{DirEntry, DirEntryItem};
use crate::kernel::fs::path::Path;
Expand Down Expand Up @@ -84,7 +85,12 @@ fn get_dir_entry(
};

if let Some(path) = path {
Ok(lookup_by_path_at(file_dir, &path, lookup_mode, get_symlink_entry)?)
Ok(lookup_by_path_at(
file_dir,
&path,
lookup_mode,
get_symlink_entry,
)?)
} else {
Ok(file_dir.clone())
}
Expand Down Expand Up @@ -186,8 +192,20 @@ pub fn sys_read(fd: u64, buf: u64, len: u64) -> SyscallResult {
};
}

pub fn sys_readlink(at: u64, path: u64, path_len: u64, buf: u64, max_size: u64, len: u64) -> SyscallResult {
let inode = get_dir_entry(OpenFD::try_from(at)?, make_path(path, path_len), LookupMode::None, true)?;
pub fn sys_readlink(
at: u64,
path: u64,
path_len: u64,
buf: u64,
max_size: u64,
len: u64,
) -> SyscallResult {
let inode = get_dir_entry(
OpenFD::try_from(at)?,
make_path(path, path_len),
LookupMode::None,
true,
)?;

if inode.inode().ftype()? != FileType::Symlink {
return Err(SyscallError::EINVAL);
Expand Down Expand Up @@ -404,22 +422,23 @@ pub fn sys_maps() -> SyscallResult {
Ok(0)
}

pub fn sys_chdir(path: u64, len: u64) -> SyscallResult {
if let Ok(path) = core::str::from_utf8(make_buf(path, len)) {
if let Ok(dentry) = lookup_by_path(&Path::new(path), LookupMode::None) {
let dir = dentry.read().inode.clone();
pub fn sys_chdir(at: u64, path: u64, len: u64) -> SyscallResult {
let dir = get_dir_entry(
OpenFD::try_from(at)?,
make_path(path, len),
LookupMode::None,
false,
)?;

if dir.ftype()? == FileType::Dir {
let task = current_task_ref();
task.set_cwd(dentry);
return Ok(0);
} else {
return Err(SyscallError::ENOTDIR);
}
}
}
let inode = dir.inode();

Err(SyscallError::EINVAL)
return if inode.ftype()? == FileType::Dir {
let task = current_task_ref();
task.set_cwd(dir);
Ok(0)
} else {
Err(SyscallError::ENOTDIR)
};
}

pub fn sys_getcwd(buf: u64, len: u64) -> SyscallResult {
Expand Down Expand Up @@ -447,7 +466,10 @@ pub fn sys_mkdir(at: u64, path: u64, path_len: u64) -> SyscallResult {
let (inode, name) = {
let (dir, target) = path.containing_dir();

(get_dir_entry(at, Some(dir), LookupMode::None, false)?.inode(), target)
(
get_dir_entry(at, Some(dir), LookupMode::None, false)?.inode(),
target,
)
};

if inode.ftype()? != FileType::Dir {
Expand Down Expand Up @@ -489,7 +511,10 @@ pub fn sys_symlink(
let (inode, name) = {
let (dir, target) = path.containing_dir();

(get_dir_entry(OpenFD::try_from(at)?, Some(dir), LookupMode::None, false)?.inode(), target)
(
get_dir_entry(OpenFD::try_from(at)?, Some(dir), LookupMode::None, false)?.inode(),
target,
)
};

if inode.ftype()? == FileType::Dir {
Expand Down Expand Up @@ -553,18 +578,30 @@ pub fn sys_unlink(at: u64, path: u64, path_len: u64, flags: u64) -> SyscallResul
}
}

pub fn sys_link(target: u64, target_len: u64, linkpath: u64, linkpath_len: u64) -> SyscallResult {
let target = make_str(target, target_len);
let path = make_str(linkpath, linkpath_len);

let target_entry = lookup_by_real_path(&Path::new(target), LookupMode::None)?;

let path = Path::new(path);
pub fn sys_link(
target_at: u64,
target: u64,
target_len: u64,
link_at: u64,
linkpath: u64,
linkpath_len: u64,
) -> SyscallResult {
let target_entry = get_dir_entry(
target_at.try_into()?,
make_path(target, target_len),
LookupMode::None,
true,
)?;

let (inode, name) = {
let path = Path::new(make_str(linkpath, linkpath_len));

let (dir, name) = path.containing_dir();

(lookup_by_path(&dir, LookupMode::None)?.inode(), name)
(
get_dir_entry(link_at.try_into()?, Some(dir), LookupMode::None, false)?.inode(),
name,
)
};

if Weak::as_ptr(&inode.fs().unwrap()) != Weak::as_ptr(&target_entry.inode().fs().unwrap()) {
Expand All @@ -580,16 +617,44 @@ pub fn sys_link(target: u64, target_len: u64, linkpath: u64, linkpath_len: u64)
Ok(0)
}

pub fn sys_rename(oldpath: u64, oldpath_len: u64, newpath: u64, newpath_len: u64) -> SyscallResult {
let old_path = Path::new(make_str(oldpath, oldpath_len));
let new_path = Path::new(make_str(newpath, newpath_len));
pub fn sys_chmod(at: u64, path: u64, path_len: u64, mode: u64, flags: u64) -> SyscallResult {
let flags = AtFlags::from_bits(flags).ok_or(SyscallError::EINVAL)?;
let inode = get_dir_entry(
at.try_into()?,
make_path(path, path_len),
LookupMode::None,
flags.contains(AtFlags::SYMLINK_NOFOLLOW),
)?;

inode.inode().chmod(Mode::mode_bits_truncate(mode as u32))?;

let old = lookup_by_real_path(&old_path, LookupMode::None)?;
Ok(0)
}

pub fn sys_rename(
old_at: u64,
oldpath: u64,
oldpath_len: u64,
new_at: u64,
newpath: u64,
newpath_len: u64,
) -> SyscallResult {
let old = get_dir_entry(
old_at.try_into()?,
make_path(oldpath, oldpath_len),
LookupMode::None,
true,
)?;

let (new, name) = {
let new_path = Path::new(make_str(newpath, newpath_len));

let (dir, name) = new_path.containing_dir();

(lookup_by_real_path(&dir, LookupMode::None)?, name)
(
get_dir_entry(new_at.try_into()?, Some(dir), LookupMode::None, true)?,
name,
)
};

if new.inode().fs().unwrap().as_ptr() != old.inode().fs().unwrap().as_ptr() {
Expand Down Expand Up @@ -1436,3 +1501,9 @@ pub fn sys_reboot() -> SyscallResult {
Ok(0)
}
}

pub fn sys_yield() -> SyscallResult {
crate::kernel::sched::reschedule();

Ok(0)
}
2 changes: 2 additions & 0 deletions syscall-defs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ pub const SYS_MSGRECV: usize = 66;
pub const SYS_MSGSEND: usize = 67;
pub const SYS_SETSOCKOPT: usize = 68;
pub const SYS_GETSOCKOPT: usize = 69;
pub const SYS_YIELD: usize = 70;
pub const SYS_CHMOD: usize = 71;

#[derive(Copy, Clone, PartialEq, Debug)]
#[repr(u64)]
Expand Down
6 changes: 6 additions & 0 deletions syscall-defs/src/stat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ bitflags! {
}
}

impl Mode {
pub fn mode_bits_truncate(v: u32) -> Mode {
Mode::from_bits_truncate(v & 0o7777)
}
}

#[repr(C)]
#[derive(Default, Debug)]
pub struct Stat {
Expand Down
6 changes: 4 additions & 2 deletions syscall-user/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ pub fn sync() -> SyscallResult {
}

pub fn chdir(path: &str) -> SyscallResult {
unsafe { syscall2(SYS_CHDIR, path.as_ptr() as usize, path.len()) }
unsafe { syscall3(SYS_CHDIR, OpenFD::Cwd.into(), path.as_ptr() as usize, path.len()) }
}

pub fn getcwd(buf: &mut [u8]) -> SyscallResult {
Expand Down Expand Up @@ -267,10 +267,12 @@ pub fn unlink(path: &str) -> SyscallResult {

pub fn rename(oldpath: &str, newpath: &str) -> SyscallResult {
unsafe {
syscall4(
syscall6(
SYS_RENAME,
OpenFD::Cwd.into(),
oldpath.as_ptr() as usize,
oldpath.len(),
OpenFD::Cwd.into(),
newpath.as_ptr() as usize,
newpath.len(),
)
Expand Down

0 comments on commit c3345f9

Please sign in to comment.