From 0272aa10705493b46b5269efc10eb4a896950b80 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Sat, 23 Mar 2019 11:33:53 +0800 Subject: [PATCH] Implement sys_readlink and improve sys_mremap --- crate/memory/src/memory_set/mod.rs | 9 ++++- kernel/Cargo.lock | 4 +-- kernel/src/syscall/fs.rs | 55 +++++++++++++++++++++++++++++- kernel/src/syscall/mod.rs | 5 +-- 4 files changed, 65 insertions(+), 8 deletions(-) diff --git a/crate/memory/src/memory_set/mod.rs b/crate/memory/src/memory_set/mod.rs index 4bc7afb..a36a93e 100644 --- a/crate/memory/src/memory_set/mod.rs +++ b/crate/memory/src/memory_set/mod.rs @@ -301,7 +301,14 @@ impl MemorySet { let new_area = MemoryArea { start_addr: area.start_addr, end_addr: start_addr, attr: area.attr, handler: area.handler, name: area.name }; self.areas.insert(i, new_area); } else { - unimplemented!(""); + // superset + let area = self.areas.remove(i); + let dead_area = MemoryArea { start_addr: start_addr, end_addr: end_addr, attr: area.attr, handler: area.handler.box_clone(), name: area.name }; + self.page_table.edit(|pt| dead_area.unmap(pt)); + let new_area_left = MemoryArea { start_addr: area.start_addr, end_addr: start_addr, attr: area.attr, handler: area.handler.box_clone(), name: area.name }; + self.areas.insert(i, new_area_left); + let new_area_right = MemoryArea { start_addr: end_addr, end_addr: area.start_addr, attr: area.attr, handler: area.handler, name: area.name }; + self.areas.insert(i, new_area_right); } return; } diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index 9b43ed7..02a7ef8 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -338,12 +338,12 @@ dependencies = [ [[package]] name = "rcore-fs" version = "0.1.0" -source = "git+https://github.com/rcore-os/rcore-fs?branch=sefs#38dab25178eb25abaab8e6d929af354a56158d5f" +source = "git+https://github.com/rcore-os/rcore-fs?branch=sefs#47df4e1cc97f061fa6eadf66eaacf774d22bb806" [[package]] name = "rcore-fs-sfs" version = "0.1.0" -source = "git+https://github.com/rcore-os/rcore-fs?branch=sefs#38dab25178eb25abaab8e6d929af354a56158d5f" +source = "git+https://github.com/rcore-os/rcore-fs?branch=sefs#47df4e1cc97f061fa6eadf66eaacf774d22bb806" dependencies = [ "bitvec 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index 9341205..f2863cd 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -384,6 +384,23 @@ pub fn sys_lstat(path: *const u8, stat_ptr: *mut Stat) -> SysResult { Ok(0) } +pub fn sys_readlink(path: *const u8, base: *mut u8, len: usize) -> SysResult { + let proc = process(); + let path = unsafe { proc.vm.check_and_clone_cstr(path)? }; + proc.vm.check_write_array(base, len)?; + info!("readlink: path: {:?}, base: {:?}, len: {}", path, base, len); + + let inode = proc.lookup_inode(&path)?; + if inode.metadata()?.type_ == FileType::SymLink { + // TODO: recursive link resolution and loop detection + let mut slice = unsafe { slice::from_raw_parts_mut(base, len) }; + let len = inode.read_at(0, &mut slice)?; + Ok(len) + } else { + Err(SysError::EINVAL) + } +} + pub fn sys_lseek(fd: usize, offset: i64, whence: u8) -> SysResult { let pos = match whence { SEEK_SET => SeekFrom::Start(offset as u64), @@ -441,7 +458,7 @@ pub fn sys_getdents64(fd: usize, buf: *mut LinuxDirent64, buf_size: usize) -> Sy r => r, }?; // TODO: get ino from dirent - let ok = writer.try_write(0, 0, &name); + let ok = writer.try_write(0, DirentType::from_type(&info.type_).bits(), &name); if !ok { break; } } Ok(writer.written_size) @@ -799,6 +816,42 @@ impl DirentBufWriter { } } +bitflags! { + pub struct DirentType: u8 { + const DT_UNKNOWN = 0; + /// FIFO (named pipe) + const DT_FIFO = 1; + /// Character device + const DT_CHR = 2; + /// Directory + const DT_DIR = 4; + /// Block device + const DT_BLK = 6; + /// Regular file + const DT_REG = 8; + /// Symbolic link + const DT_LNK = 10; + /// UNIX domain socket + const DT_SOCK = 12; + /// ??? + const DT_WHT = 14; + } +} + +impl DirentType { + fn from_type(type_: &FileType) -> Self { + match type_ { + FileType::File => Self::DT_REG, + FileType::Dir => Self::DT_DIR, + FileType::SymLink => Self::DT_LNK, + FileType::CharDevice => Self::DT_CHR, + FileType::BlockDevice => Self::DT_BLK, + FileType::Socket => Self::DT_SOCK, + FileType::NamedPipe => Self::DT_FIFO, + } + } +} + #[cfg(target_arch = "x86_64")] #[repr(C)] #[derive(Debug)] diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index b721bc4..7ffe97e 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -243,16 +243,13 @@ fn x86_64_syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> Option sys_rmdir(args[0] as *const u8), SYS_LINK => sys_link(args[0] as *const u8, args[1] as *const u8), SYS_UNLINK => sys_unlink(args[0] as *const u8), + SYS_READLINK => sys_readlink(args[0] as *const u8, args[1] as *mut u8, args[2]), SYS_ARCH_PRCTL => sys_arch_prctl(args[0] as i32, args[1], tf), SYS_TIME => sys_time(args[0] as *mut u64), SYS_ALARM => { warn!("sys_alarm is unimplemented"); Ok(0) } - SYS_READLINK => { - warn!("sys_readlink is unimplemented"); - Err(SysError::ENOENT) - } SYS_CHOWN => { warn!("sys_chown is unimplemented"); Ok(0)