Add support for chdir and fchdir

This commit is contained in:
LI Qing 2023-03-06 15:21:19 +08:00 committed by Tate, Hongliang Tian
parent c227c1e765
commit 54119e80bc
3 changed files with 58 additions and 2 deletions

View File

@ -1,5 +1,5 @@
use crate::prelude::*;
use super::{DirentWriterContext, Inode, InodeMode, InodeType, Metadata, PageCacheManager};
use crate::prelude::*;
use crate::rights::Rights;
use crate::vm::vmo::{Vmo, VmoFlags, VmoOptions};
use alloc::string::String;
@ -21,7 +21,7 @@ struct Inner {
impl Vnode {
pub fn new(inode: Arc<dyn Inode>) -> Result<Self> {
let page_cache_manager = Arc::new(PageCacheManager::new(&Arc::downgrade(&inode)));
let page_cache = VmoOptions::<Rights>::new(inode.metadata().size)
let page_cache = VmoOptions::<Rights>::new(inode.len())
.flags(VmoFlags::RESIZABLE)
.pager(page_cache_manager.clone())
.alloc()?;

View File

@ -0,0 +1,50 @@
use crate::fs::{file_table::FileDescripter, fs_resolver::FsPath, utils::InodeType};
use crate::log_syscall_entry;
use crate::prelude::*;
use crate::syscall::constants::MAX_FILENAME_LEN;
use crate::util::read_cstring_from_user;
use super::SyscallReturn;
use super::{SYS_CHDIR, SYS_FCHDIR};
pub fn sys_chdir(pathname_addr: Vaddr) -> Result<SyscallReturn> {
log_syscall_entry!(SYS_CHDIR);
let pathname = read_cstring_from_user(pathname_addr, MAX_FILENAME_LEN)?;
debug!("pathname = {:?}", pathname);
let current = current!();
let mut fs = current.fs().write();
let dentry = {
let pathname = pathname.to_string_lossy();
if pathname.is_empty() {
return_errno_with_message!(Errno::ENOENT, "path is empty");
}
let fs_path = FsPath::try_from(pathname.as_ref())?;
fs.lookup(&fs_path)?
};
if dentry.inode_type() != InodeType::Dir {
return_errno_with_message!(Errno::ENOTDIR, "must be directory");
}
fs.set_cwd(dentry);
Ok(SyscallReturn::Return(0))
}
pub fn sys_fchdir(fd: FileDescripter) -> Result<SyscallReturn> {
log_syscall_entry!(SYS_FCHDIR);
debug!("fd = {}", fd);
let current = current!();
let dentry = {
let file_table = current.file_table().lock();
let file = file_table.get_file(fd)?;
let inode_handle = file
.as_inode_handle()
.ok_or(Error::with_message(Errno::EBADE, "not inode"))?;
inode_handle.dentry().clone()
};
if dentry.inode_type() != InodeType::Dir {
return_errno_with_message!(Errno::ENOTDIR, "must be directory");
}
current.fs().write().set_cwd(dentry);
Ok(SyscallReturn::Return(0))
}

View File

@ -4,6 +4,7 @@ use crate::prelude::*;
use crate::syscall::access::sys_access;
use crate::syscall::arch_prctl::sys_arch_prctl;
use crate::syscall::brk::sys_brk;
use crate::syscall::chdir::{sys_chdir, sys_fchdir};
use crate::syscall::clock_nanosleep::sys_clock_nanosleep;
use crate::syscall::clone::sys_clone;
use crate::syscall::close::sys_close;
@ -60,6 +61,7 @@ use jinux_frame::cpu::CpuContext;
mod access;
mod arch_prctl;
mod brk;
mod chdir;
mod clock_nanosleep;
mod clone;
mod close;
@ -175,6 +177,8 @@ define_syscall_nums!(
SYS_UNAME = 63,
SYS_FCNTL = 72,
SYS_GETCWD = 79,
SYS_CHDIR = 80,
SYS_FCHDIR = 81,
SYS_RENAME = 82,
SYS_MKDIR = 83,
SYS_RMDIR = 84,
@ -297,6 +301,8 @@ pub fn syscall_dispatch(
SYS_UNAME => syscall_handler!(1, sys_uname, args),
SYS_FCNTL => syscall_handler!(3, sys_fcntl, args),
SYS_GETCWD => syscall_handler!(2, sys_getcwd, args),
SYS_CHDIR => syscall_handler!(1, sys_chdir, args),
SYS_FCHDIR => syscall_handler!(1, sys_fchdir, args),
SYS_RENAME => syscall_handler!(2, sys_rename, args),
SYS_MKDIR => syscall_handler!(2, sys_mkdir, args),
SYS_RMDIR => syscall_handler!(1, sys_rmdir, args),