Skip to content

Commit

Permalink
Support NONBLOCK file open flag
Browse files Browse the repository at this point in the history
  • Loading branch information
rafalmiel committed Jun 14, 2024
1 parent 653b62d commit c661d38
Show file tree
Hide file tree
Showing 20 changed files with 118 additions and 66 deletions.
4 changes: 2 additions & 2 deletions cykusz-rs/src/arch/x86_64/task/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use core::mem::size_of;
use core::ptr::Unique;

use syscall_defs::exec::ExeArgs;
use syscall_defs::{MMapFlags, MMapProt};
use syscall_defs::{MMapFlags, MMapProt, OpenFlags};

use crate::arch::gdt;
use crate::arch::gdt::update_tss_rps0;
Expand Down Expand Up @@ -124,7 +124,7 @@ fn prepare_tls(vm: &VM, p_table: &mut P4Table, tls: &TlsVmInfo) -> VirtAddr {

if let Ok(r) = tls.file.inode().read_at(tls.file_offset + offset, unsafe {
frame.address_mapped().as_bytes_mut(to_read)
}) {
}, OpenFlags::empty()) {
if r != to_read {
panic!("Failed to read tls data");
}
Expand Down
4 changes: 2 additions & 2 deletions cykusz-rs/src/drivers/ps2/kbd/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ impl Device for KbdState {
}

impl INode for KbdState {
fn read_at(&self, _offset: usize, buf: &mut [u8]) -> crate::kernel::fs::vfs::Result<usize> {
fn read_at(&self, _offset: usize, buf: &mut [u8], flags: OpenFlags) -> crate::kernel::fs::vfs::Result<usize> {
if buf.len() % core::mem::size_of::<Event>() != 0 {
Err(FsError::InvalidParam)
} else {
Ok(self.buf.read_data_flags(buf, WaitQueueFlags::IRQ_DISABLE)?)
Ok(self.buf.read_data_flags(buf, WaitQueueFlags::IRQ_DISABLE | WaitQueueFlags::from(flags))?)
}
}

Expand Down
4 changes: 2 additions & 2 deletions cykusz-rs/src/drivers/ps2/mouse/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,11 @@ impl Device for MouseState {
}

impl INode for MouseState {
fn read_at(&self, _offset: usize, buf: &mut [u8]) -> crate::kernel::fs::vfs::Result<usize> {
fn read_at(&self, _offset: usize, buf: &mut [u8], flags: OpenFlags) -> crate::kernel::fs::vfs::Result<usize> {
if buf.len() % core::mem::size_of::<Event>() != 0 {
Err(FsError::InvalidParam)
} else {
Ok(self.buf.read_data_flags(buf, WaitQueueFlags::IRQ_DISABLE)?)
Ok(self.buf.read_data_flags(buf, WaitQueueFlags::IRQ_DISABLE | WaitQueueFlags::from(flags))?)
}
}

Expand Down
3 changes: 2 additions & 1 deletion cykusz-rs/src/drivers/random.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use alloc::string::String;
use alloc::sync::{Arc, Weak};

use rand::{RngCore, SeedableRng};
use syscall_defs::OpenFlags;

use crate::kernel::device::dev_t::DevId;
use crate::kernel::device::Device;
Expand Down Expand Up @@ -38,7 +39,7 @@ impl Random {
}

impl INode for Random {
fn read_at(&self, _offset: usize, buf: &mut [u8]) -> crate::kernel::fs::vfs::Result<usize> {
fn read_at(&self, _offset: usize, buf: &mut [u8], _flags: OpenFlags) -> crate::kernel::fs::vfs::Result<usize> {
self.rng.lock().fill_bytes(buf);

Ok(buf.len())
Expand Down
18 changes: 9 additions & 9 deletions cykusz-rs/src/drivers/tty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ use crate::kernel::device::dev_t::DevId;
use crate::kernel::device::Device;
use crate::kernel::fs::inode::INode;
use crate::kernel::fs::poll::PollTable;
use crate::kernel::fs::vfs;
use crate::kernel::fs::vfs::FsError;
use crate::kernel::kbd::KeyListener;
use crate::kernel::mm::VirtAddr;
use crate::kernel::sched::current_task_ref;
use crate::kernel::session::{sessions, Group};
use crate::kernel::signal::{SignalError, SignalResult};
use crate::kernel::sync::{LockApi, Spin, SpinGuard};
use crate::kernel::task::Task;
use crate::kernel::tty::TerminalDevice;
Expand Down Expand Up @@ -133,21 +133,21 @@ impl Tty {
})
}

fn read(&self, buf: *mut u8, len: usize) -> SignalResult<usize> {
fn read(&self, buf: *mut u8, len: usize, flags: OpenFlags) -> vfs::Result<usize> {
if let Some(fg) = &*self.fg_group.lock_irq() {
let task = current_task_ref();

if !fg.has_process(task.pid()) {
task.signal(syscall_defs::signal::SIGTTIN);
return Err(SignalError::Interrupted);
return Err(FsError::Interrupted);
}
}
let mut buffer = self
.wait_queue
.wait_lock_for(WaitQueueFlags::IRQ_DISABLE, &self.buffer, |lck| {
.wait_lock_for(WaitQueueFlags::IRQ_DISABLE | WaitQueueFlags::from(flags), &self.buffer, |lck| {
lck.has_data()
})?
.unwrap();
.ok_or(FsError::WouldBlock)?;

Ok(buffer.read(buf, len))
}
Expand Down Expand Up @@ -461,21 +461,21 @@ impl TerminalDevice for Tty {
}

impl INode for Tty {
fn read_at(&self, _offset: usize, buf: &mut [u8]) -> Result<usize, FsError> {
fn read_at(&self, _offset: usize, buf: &mut [u8], flags: OpenFlags) -> Result<usize, FsError> {
logln2!("try tty read");
let r = self.read(buf.as_mut_ptr(), buf.len());
let r = self.read(buf.as_mut_ptr(), buf.len(), flags);
logln2!("tty read {:?} {:?}", r, buf);

match r {
Ok(s) => Ok(s),
Err(e) => {
logln2!("tty signal error");
logln2!("tty error {:?}", e);
Err(e.into())
}
}
}

fn write_at(&self, _offset: usize, buf: &[u8]) -> Result<usize, FsError> {
fn write_at(&self, _offset: usize, buf: &[u8], _flags: OpenFlags) -> Result<usize, FsError> {
if let Err(_) = self.write_str(unsafe { core::str::from_utf8_unchecked(buf) }) {
Err(FsError::InvalidParam)
} else {
Expand Down
8 changes: 4 additions & 4 deletions cykusz-rs/src/kernel/fs/ext2/inode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ impl Ext2INode {

impl RawAccess for LockedExt2INode {
fn read_direct(&self, addr: usize, dest: &mut [u8]) -> Option<usize> {
if let Ok(read) = self.read_at(addr, dest) {
if let Ok(read) = self.read_at(addr, dest, OpenFlags::empty()) {
Some(read)
} else {
None
Expand Down Expand Up @@ -729,7 +729,7 @@ impl INode for LockedExt2INode {
Ok(())
}

fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize> {
fn read_at(&self, offset: usize, buf: &mut [u8], _flags: OpenFlags) -> Result<usize> {
if self.ftype()? != FileType::File && self.ftype()? != FileType::Symlink {
return Err(FsError::NotFile);
}
Expand All @@ -739,7 +739,7 @@ impl INode for LockedExt2INode {
Ok(reader.read(buf))
}

fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize> {
fn write_at(&self, offset: usize, buf: &[u8], _flags: OpenFlags) -> Result<usize> {
if self.ftype()? != FileType::File && self.ftype()? != FileType::Symlink {
return Err(FsError::NotFile);
}
Expand Down Expand Up @@ -846,7 +846,7 @@ impl INode for LockedExt2INode {

let new_inode = self.mk_inode(FileType::Symlink)?;

if let Err(e) = new_inode.write_at(0, target.as_bytes()) {
if let Err(e) = new_inode.write_at(0, target.as_bytes(), OpenFlags::empty()) {
self.ext2_fs().free_inode(&new_inode.as_ext2_inode());

return Err(e);
Expand Down
11 changes: 5 additions & 6 deletions cykusz-rs/src/kernel/fs/inode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,20 +53,19 @@ pub trait INode: Send + Sync + DowncastSync {
Err(FsError::NotSupported)
}

fn read_at(&self, _offset: usize, _buf: &mut [u8]) -> Result<usize> {
fn read_at(&self, _offset: usize, _buf: &mut [u8], _flags: OpenFlags) -> Result<usize> {
Err(FsError::NotSupported)
}

fn read_all(&self) -> Vec<u8> {
fn read_all(&self) -> Result<Vec<u8>> {
let meta = self.metadata().unwrap();
let mut data = Vec::<u8>::new();
data.resize(meta.size, 0);
self.read_at(0, data.as_mut_slice())
.expect("fstab read failed");
data
self.read_at(0, data.as_mut_slice(), OpenFlags::empty())?;
Ok(data)
}

fn write_at(&self, _offset: usize, _buf: &[u8]) -> Result<usize> {
fn write_at(&self, _offset: usize, _buf: &[u8], _flags: OpenFlags) -> Result<usize> {
Err(FsError::NotSupported)
}

Expand Down
4 changes: 2 additions & 2 deletions cykusz-rs/src/kernel/fs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ pub fn mount_root() {
mount::mark_mounted(root_fs.clone());

if let Ok(fstab) = lookup_by_path(&Path::new("/etc/fstab"), LookupMode::None) {
let data = fstab.inode().read_all();
let data = fstab.inode().read_all().expect("/etc/fstab read failed");

if let Ok(content) = core::str::from_utf8(data.as_slice()) {
for line in content.split("\n") {
Expand Down Expand Up @@ -165,7 +165,7 @@ pub fn read_link(inode: &Arc<dyn INode>) -> Result<String> {
let mut offset = 0;

loop {
offset += inode.read_at(offset, &mut path.as_mut_slice()[offset..])?;
offset += inode.read_at(offset, &mut path.as_mut_slice()[offset..], OpenFlags::empty())?;

if offset == path.len() {
path.resize(offset + 128, 0);
Expand Down
9 changes: 5 additions & 4 deletions cykusz-rs/src/kernel/fs/pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::kernel::fs::vfs::{FsError, Result};
use crate::kernel::sync::{LockApi, Mutex, MutexGuard};
use crate::kernel::utils::buffer::BufferQueue;
use crate::kernel::utils::node_map::{NodeMap, NodeMapItem};
use crate::kernel::utils::wait_queue::WaitQueueFlags;

pub struct Pipe {
buf: BufferQueue,
Expand Down Expand Up @@ -87,12 +88,12 @@ impl INode for Pipe {

Ok(stat)
}
fn read_at(&self, _offset: usize, buf: &mut [u8]) -> Result<usize> {
Ok(self.buf.read_data(buf)?)
fn read_at(&self, _offset: usize, buf: &mut [u8], flags: OpenFlags) -> Result<usize> {
Ok(self.buf.read_data_flags(buf, WaitQueueFlags::from(flags))?)
}

fn write_at(&self, _offset: usize, buf: &[u8]) -> Result<usize> {
self.buf.append_data(buf)
fn write_at(&self, _offset: usize, buf: &[u8], flags: OpenFlags) -> Result<usize> {
self.buf.append_data_flags(buf, WaitQueueFlags::from(flags))
}

fn poll(
Expand Down
4 changes: 2 additions & 2 deletions cykusz-rs/src/kernel/fs/ramfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ impl INode for LockedRamINode {
self.make_inode(name, FileType::Dir, |_| Ok(()))
}

fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize> {
fn read_at(&self, offset: usize, buf: &mut [u8], _flags: OpenFlags) -> Result<usize> {
let i = self.0.read();

match &i.content {
Expand All @@ -147,7 +147,7 @@ impl INode for LockedRamINode {
}
}

fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize> {
fn write_at(&self, offset: usize, buf: &[u8], _flags: OpenFlags) -> Result<usize> {
let i = self.0.read();

match &i.content {
Expand Down
2 changes: 2 additions & 0 deletions cykusz-rs/src/kernel/fs/vfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub enum FsError {
IsPipe,
Interrupted,
NoSuchDevice,
WouldBlock
}

impl From<FsError> for syscall_defs::SyscallError {
Expand All @@ -37,6 +38,7 @@ impl From<FsError> for syscall_defs::SyscallError {
FsError::IsPipe => SyscallError::ESPIPE,
FsError::Interrupted => SyscallError::EINTR,
FsError::NoSuchDevice => SyscallError::ENXIO,
FsError::WouldBlock => SyscallError::EAGAIN,
}
}
}
Expand Down
14 changes: 7 additions & 7 deletions cykusz-rs/src/kernel/net/tcp/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -907,7 +907,7 @@ impl Socket {
offset,
buf,
flags.contains(MsgFlags::MSG_PEEK),
WaitQueueFlags::empty(),
WaitQueueFlags::from(flags),
)?)
}

Expand All @@ -928,13 +928,13 @@ impl INode for Socket {
Ok(stat)
}

fn read_at(&self, _offset: usize, buf: &mut [u8]) -> Result<usize> {
fn read_at(&self, _offset: usize, buf: &mut [u8], flags: OpenFlags) -> Result<usize> {
//let data = self.data.lock();
//if data.is_listening() {
// return Err(FsError::NotSupported);
//}
//drop(data);
let r = self.read(0, buf, MsgFlags::empty())?;
let r = self.read(0, buf, MsgFlags::from(flags))?;

if r > 0 {
self.update_window();
Expand All @@ -943,7 +943,7 @@ impl INode for Socket {
Ok(r)
}

fn write_at(&self, _offset: usize, buf: &[u8]) -> Result<usize> {
fn write_at(&self, _offset: usize, buf: &[u8], flags: OpenFlags) -> Result<usize> {
logln5!("write_at socket, len: {}", buf.len());
let mut data = self.data.lock();

Expand All @@ -960,7 +960,7 @@ impl INode for Socket {

//println!("[ TCP ] Proxy Buffer avail: {}", data.proxy_buffer.available_size());

while data.proxy_buffer.available_size() < buf.len() {
while data.proxy_buffer.available_size() < buf.len() && !flags.contains(OpenFlags::NONBLOCK) {
if let Err(e) = WaitQueue::wait_lock(data) {
data = self.data.lock();

Expand Down Expand Up @@ -1122,14 +1122,14 @@ impl SocketService for Socket {
Ok(0)
}

fn msg_send(&self, hdr: &MsgHdr, _flags: MsgFlags) -> SyscallResult {
fn msg_send(&self, hdr: &MsgHdr, flags: MsgFlags) -> SyscallResult {
logln!("tcp msg_send");
let iovecs = hdr.iovecs();

let mut total = 0;

for iovec in iovecs {
total += self.write_at(0, iovec.get_bytes())?;
total += self.write_at(0, iovec.get_bytes(), OpenFlags::from(flags))?;
}

Ok(total)
Expand Down
8 changes: 4 additions & 4 deletions cykusz-rs/src/kernel/net/udp/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,12 @@ impl INode for Socket {
Ok(stat)
}

fn read_at(&self, _offset: usize, buf: &mut [u8]) -> Result<usize> {
fn read_at(&self, _offset: usize, buf: &mut [u8], flags: OpenFlags) -> Result<usize> {
logln4!("udp read {}", buf.len());
let mut data = self
.buffer_wq
.wait_lock_for(WaitQueueFlags::empty(), &self.buffer, |l| !l.is_empty())?
.unwrap();
.wait_lock_for(WaitQueueFlags::from(flags), &self.buffer, |l| !l.is_empty())?
.ok_or(FsError::WouldBlock)?;

let packet = data.pop_front().unwrap();

Expand All @@ -168,7 +168,7 @@ impl INode for Socket {
Ok(size)
}

fn write_at(&self, _offset: usize, buf: &[u8]) -> Result<usize> {
fn write_at(&self, _offset: usize, buf: &[u8], _flags: OpenFlags) -> Result<usize> {
self.send(buf, None)
}

Expand Down
Loading

0 comments on commit c661d38

Please sign in to comment.