refactor: fix clippy warnings

This commit is contained in:
Mark Poliakov 2021-11-11 22:46:01 +02:00
parent 0a10b3c0b3
commit 00c368c36b
12 changed files with 83 additions and 30 deletions

View File

@ -121,7 +121,7 @@ doc-open:
clippy:
cd kernel && cargo clippy $(CARGO_BUILD_OPTS)
cd init && cargo clippy \
cd user && cargo clippy \
--target=../etc/$(ARCH)-osdev5.json \
-Zbuild-std=core,alloc,compiler_builtins $(CARGO_COMMON_OPTS)

View File

@ -20,6 +20,7 @@ pub trait CharDevice {
/// will immediately return an error.
fn write(&self, blocking: bool, data: &[u8]) -> Result<usize, Errno>;
/// Performs a TTY control request
fn ioctl(&self, cmd: IoctlCmd, ptr: usize, lim: usize) -> Result<usize, Errno>;
}

View File

@ -80,6 +80,7 @@ pub trait VnodeImpl {
/// Reports the size of this filesystem object in bytes
fn size(&mut self, node: VnodeRef) -> Result<usize, Errno>;
/// Performs filetype-specific request
fn ioctl(
&mut self,
node: VnodeRef,

View File

@ -26,9 +26,12 @@ pub struct CharRing<const N: usize> {
inner: IrqSafeSpinLock<CharRingInner<N>>,
}
/// Generic teletype device interface
pub trait TtyDevice<const N: usize>: SerialDevice {
/// Returns a reference to character device's ring buffer
fn ring(&self) -> &CharRing<N>;
/// Performs a TTY control request
fn tty_ioctl(&self, cmd: IoctlCmd, ptr: usize, _len: usize) -> Result<usize, Errno> {
match cmd {
IoctlCmd::TtyGetAttributes => {
@ -46,6 +49,7 @@ pub trait TtyDevice<const N: usize>: SerialDevice {
}
}
/// Processes and writes output an output byte
fn line_send(&self, byte: u8) -> Result<(), Errno> {
let config = self.ring().config.lock();
@ -56,6 +60,7 @@ pub trait TtyDevice<const N: usize>: SerialDevice {
self.send(byte)
}
/// Receives input bytes and processes them
fn recv_byte(&self, mut byte: u8) {
let ring = self.ring();
let config = ring.config.lock();
@ -96,7 +101,7 @@ pub trait TtyDevice<const N: usize>: SerialDevice {
let ring = self.ring();
let mut config = ring.config.lock();
if data.len() == 0 {
if data.is_empty() {
return Ok(0);
}
@ -104,7 +109,7 @@ pub trait TtyDevice<const N: usize>: SerialDevice {
drop(config);
let byte = ring.getc()?;
data[0] = byte;
return Ok(1);
Ok(1)
} else {
let mut rem = data.len();
let mut off = 0;
@ -164,6 +169,7 @@ pub trait TtyDevice<const N: usize>: SerialDevice {
}
}
/// Processes and writes string bytes
fn line_write(&self, data: &[u8]) -> Result<usize, Errno> {
for &byte in data.iter() {
self.line_send(byte)?;
@ -171,6 +177,7 @@ pub trait TtyDevice<const N: usize>: SerialDevice {
Ok(data.len())
}
/// Writes string bytes without any processing
fn raw_write(&self, data: &[u8]) -> Result<usize, Errno> {
for &byte in data.iter() {
self.send(byte)?;

View File

@ -97,25 +97,28 @@ unsafe impl Manager for SimpleManager {
fn copy_cow_page(&mut self, src: usize) -> Result<usize, Errno> {
let src_index = self.page_index(src);
let page = &mut self.pages[src_index];
let usage = page.usage;
if usage != PageUsage::UserPrivate {
panic!("CoW not available for non-UserPrivate pages: {:?}", usage);
}
let (usage, refcount) = {
let page = &mut self.pages[src_index];
let usage = page.usage;
if usage != PageUsage::UserPrivate {
panic!("CoW not available for non-UserPrivate pages: {:?}", usage);
}
let count = page.refcount;
if count > 1 {
page.refcount -= 1;
}
(usage, count)
};
if page.refcount > 1 {
page.refcount -= 1;
drop(page);
if refcount == 0 {
Ok(src)
} else {
let dst_index = self.alloc_single_index(usage)?;
let dst = (self.base_index + dst_index) * PAGE_SIZE;
unsafe {
memcpy(virtualize(dst) as *mut u8, virtualize(src) as *mut u8, 4096);
}
Ok(dst)
} else {
assert_eq!(page.refcount, 1);
// No additional operations needed
Ok(src)
}
}

View File

@ -89,6 +89,12 @@ pub unsafe fn free_page(page: usize) -> Result<(), Errno> {
MANAGER.lock().as_mut().unwrap().free_page(page)
}
/// Clones the source page.
///
/// If returned address is the same as `page`, this means
/// `page`'s refcount has increased and the page is Copy-on-Write.
/// This case has to be handled accordingly
///
/// # Safety
///
/// Unsafe: accepts arbitrary `page` arguments
@ -96,6 +102,12 @@ pub unsafe fn fork_page(page: usize) -> Result<usize, Errno> {
MANAGER.lock().as_mut().unwrap().fork_page(page)
}
/// Copies a Copy-on-Write page. If refcount is already 1,
/// page does not need to be copied and the same address is returned.
///
/// # Safety
///
/// Unsafe: accepts arbitrary `page` arguments
pub unsafe fn copy_cow_page(page: usize) -> Result<usize, Errno> {
MANAGER.lock().as_mut().unwrap().copy_cow_page(page)
}

View File

@ -38,6 +38,7 @@ bitflags! {
/// This page is used for device-MMIO mapping and uses MAIR attribute #1
const DEVICE = 1 << 2;
/// Pages marked with this bit are Copy-on-Write
const EX_COW = 1 << 55;
/// UXN bit -- if set, page may not be used for instruction fetching from EL0
@ -209,6 +210,8 @@ impl Space {
}
}
/// Attempts to resolve a page fault at `virt` address by copying the
/// underlying Copy-on-Write mapping (if any is present)
pub fn try_cow_copy(&mut self, virt: usize) -> Result<(), Errno> {
let virt = virt & !0xFFF;
let l0i = virt >> 30;
@ -284,6 +287,13 @@ impl Space {
Ok(res)
}
/// Releases all the mappings from the address space. Frees all
/// memory pages referenced by this space as well as those used for
/// its paging tables.
///
/// # Safety
///
/// Unsafe: may invalidate currently active address space
pub unsafe fn release(space: &mut Self) {
for l0i in 0..512 {
let l0_entry = space.0[l0i];

View File

@ -125,6 +125,11 @@ impl Pid {
self.0
}
/// Constructs [Pid] from raw [u32] value
///
/// # Safety
///
/// Unsafe: does not check `num`
pub const unsafe fn from_raw(num: u32) -> Self {
Self(num)
}
@ -150,6 +155,7 @@ impl Process {
SCHED.current_process()
}
/// Returns process (if any) to which `pid` refers
pub fn get(pid: Pid) -> Option<ProcessRef> {
PROCESSES.lock().get(&pid).cloned()
}
@ -168,6 +174,7 @@ impl Process {
(&mut *ctx).enter()
}
/// Executes a function allowing mutation of the process address space
#[inline]
pub fn manipulate_space<F: FnOnce(&mut Space) -> Result<(), Errno>>(
&self,

View File

@ -126,6 +126,7 @@ impl Scheduler {
}
}
/// Returns `true` if the scheduler has been initialized
pub fn is_ready() -> bool {
SCHED.inner.is_initialized()
}

View File

@ -3,7 +3,6 @@ use crate::{
ioctl::IoctlCmd,
stat::{FileMode, OpenFlags, Stat},
};
use core::mem::size_of;
// TODO document the syscall ABI
@ -188,6 +187,9 @@ pub unsafe fn sys_waitpid(pid: u32, status: &mut i32) -> i32 {
syscall!(abi::SYS_WAITPID, argn!(pid), argp!(status as *mut i32)) as i32
}
/// # Safety
///
/// System call
#[inline(always)]
pub unsafe fn sys_ioctl(fd: u32, cmd: IoctlCmd, ptr: usize, len: usize) -> isize {
syscall!(

View File

@ -5,22 +5,31 @@
#[macro_use]
extern crate libusr;
use core::cmp::Ordering;
#[no_mangle]
fn main() -> i32 {
let pid = unsafe { libusr::sys::sys_fork() };
if pid < 0 {
eprintln!("fork() failed");
return -1;
} else if pid == 0 {
return unsafe { libusr::sys::sys_execve("/bin/shell") };
} else {
let mut status = 0;
let res = unsafe { libusr::sys::sys_waitpid(pid as u32, &mut status) };
if res == 0 {
println!("Process {} exited with status {}", pid, status);
} else {
eprintln!("waitpid() failed");
match pid.cmp(&0) {
Ordering::Less => {
eprintln!("fork() failed");
-1
}
Ordering::Equal => unsafe { libusr::sys::sys_execve("/bin/shell") },
Ordering::Greater => {
let mut status = 0;
let res = unsafe { libusr::sys::sys_waitpid(pid as u32, &mut status) };
if res == 0 {
println!("Process {} exited with status {}", pid, status);
} else {
eprintln!("waitpid() failed");
}
loop {
unsafe {
asm!("nop");
}
}
}
}
loop {}
}

View File

@ -31,5 +31,5 @@ fn main() -> i32 {
}
}
return 0;
0
}