1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-23 00:16:17 +04:00

update fs. support poll for INode.

This commit is contained in:
WangRunji 2019-04-05 23:20:08 +08:00
parent 56cb8654ae
commit a712f37c65
6 changed files with 77 additions and 65 deletions

4
kernel/Cargo.lock generated
View File

@ -345,12 +345,12 @@ dependencies = [
[[package]] [[package]]
name = "rcore-fs" name = "rcore-fs"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/rcore-os/rcore-fs#c611248f800e946acf44d64b218aeb8fc6751640" source = "git+https://github.com/rcore-os/rcore-fs#d7a2006cc316c98b7050aec63a2770dd690a4a80"
[[package]] [[package]]
name = "rcore-fs-sfs" name = "rcore-fs-sfs"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/rcore-os/rcore-fs#c611248f800e946acf44d64b218aeb8fc6751640" source = "git+https://github.com/rcore-os/rcore-fs#d7a2006cc316c98b7050aec63a2770dd690a4a80"
dependencies = [ dependencies = [
"bitvec 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -2,7 +2,7 @@
use alloc::{string::String, sync::Arc}; use alloc::{string::String, sync::Arc};
use rcore_fs::vfs::{FsError, INode, Metadata, Result}; use rcore_fs::vfs::{FsError, INode, Metadata, PollStatus, Result};
#[derive(Clone)] #[derive(Clone)]
pub struct FileHandle { pub struct FileHandle {
@ -108,4 +108,12 @@ impl FileHandle {
self.offset += 1; self.offset += 1;
Ok(name) Ok(name)
} }
pub fn poll(&self) -> Result<PollStatus> {
self.inode.poll()
}
pub fn io_control(&self, cmd: u32, arg: u32) -> Result<()> {
self.inode.io_control(cmd, arg)
}
} }

View File

@ -2,8 +2,9 @@ use core::fmt;
use super::FileHandle; use super::FileHandle;
use crate::net::Socket; use crate::net::Socket;
use crate::syscall::SysResult; use crate::syscall::{SysError, SysResult};
use alloc::boxed::Box; use alloc::boxed::Box;
use rcore_fs::vfs::PollStatus;
// TODO: merge FileLike to FileHandle ? // TODO: merge FileLike to FileHandle ?
// TODO: fix dup and remove Clone // TODO: fix dup and remove Clone
@ -30,12 +31,22 @@ impl FileLike {
} }
pub fn ioctl(&mut self, request: usize, arg1: usize, arg2: usize, arg3: usize) -> SysResult { pub fn ioctl(&mut self, request: usize, arg1: usize, arg2: usize, arg3: usize) -> SysResult {
match self { match self {
FileLike::File(file) => { FileLike::File(file) => file.io_control(request as u32, arg1 as u32)?,
warn!("ioctl not implemented for file"); FileLike::Socket(socket) => {
socket.ioctl(request, arg1, arg2, arg3)?;
}
}
Ok(0) Ok(0)
} }
FileLike::Socket(socket) => socket.ioctl(request, arg1, arg2, arg3), pub fn poll(&self) -> Result<PollStatus, SysError> {
let status = match self {
FileLike::File(file) => file.poll()?,
FileLike::Socket(socket) => {
let (read, write, error) = socket.poll();
PollStatus { read, write, error }
} }
};
Ok(status)
} }
} }

View File

@ -57,7 +57,9 @@ impl Pipe {
// TODO: better way to provide default impl? // TODO: better way to provide default impl?
macro_rules! impl_inode { macro_rules! impl_inode {
() => { () => {
fn poll(&self) -> Result<PollStatus> { Err(FsError::NotSupported) }
fn metadata(&self) -> Result<Metadata> { Err(FsError::NotSupported) } fn metadata(&self) -> Result<Metadata> { Err(FsError::NotSupported) }
fn set_metadata(&self, _metadata: &Metadata) -> Result<()> { Ok(()) }
fn sync_all(&self) -> Result<()> { Ok(()) } fn sync_all(&self) -> Result<()> { Ok(()) }
fn sync_data(&self) -> Result<()> { Ok(()) } fn sync_data(&self) -> Result<()> { Ok(()) }
fn resize(&self, _len: usize) -> Result<()> { Err(FsError::NotSupported) } fn resize(&self, _len: usize) -> Result<()> { Err(FsError::NotSupported) }
@ -67,9 +69,9 @@ macro_rules! impl_inode {
fn move_(&self, _old_name: &str, _target: &Arc<INode>, _new_name: &str) -> Result<()> { Err(FsError::NotDir) } fn move_(&self, _old_name: &str, _target: &Arc<INode>, _new_name: &str) -> Result<()> { Err(FsError::NotDir) }
fn find(&self, _name: &str) -> Result<Arc<INode>> { Err(FsError::NotDir) } fn find(&self, _name: &str) -> Result<Arc<INode>> { Err(FsError::NotDir) }
fn get_entry(&self, _id: usize) -> Result<String> { Err(FsError::NotDir) } fn get_entry(&self, _id: usize) -> Result<String> { Err(FsError::NotDir) }
fn io_control(&self, _cmd: u32, _data: u32) -> Result<()> { Err(FsError::NotSupported) }
fn fs(&self) -> Arc<FileSystem> { unimplemented!() } fn fs(&self) -> Arc<FileSystem> { unimplemented!() }
fn as_any_ref(&self) -> &Any { self } fn as_any_ref(&self) -> &Any { self }
fn chmod(&self, _mode: u16) -> Result<()> { Ok(()) }
}; };
} }

View File

@ -47,6 +47,7 @@ lazy_static! {
macro_rules! impl_inode { macro_rules! impl_inode {
() => { () => {
fn metadata(&self) -> Result<Metadata> { Err(FsError::NotSupported) } fn metadata(&self) -> Result<Metadata> { Err(FsError::NotSupported) }
fn set_metadata(&self, _metadata: &Metadata) -> Result<()> { Ok(()) }
fn sync_all(&self) -> Result<()> { Ok(()) } fn sync_all(&self) -> Result<()> { Ok(()) }
fn sync_data(&self) -> Result<()> { Ok(()) } fn sync_data(&self) -> Result<()> { Ok(()) }
fn resize(&self, _len: usize) -> Result<()> { Err(FsError::NotSupported) } fn resize(&self, _len: usize) -> Result<()> { Err(FsError::NotSupported) }
@ -56,20 +57,27 @@ macro_rules! impl_inode {
fn move_(&self, _old_name: &str, _target: &Arc<INode>, _new_name: &str) -> Result<()> { Err(FsError::NotDir) } fn move_(&self, _old_name: &str, _target: &Arc<INode>, _new_name: &str) -> Result<()> { Err(FsError::NotDir) }
fn find(&self, _name: &str) -> Result<Arc<INode>> { Err(FsError::NotDir) } fn find(&self, _name: &str) -> Result<Arc<INode>> { Err(FsError::NotDir) }
fn get_entry(&self, _id: usize) -> Result<String> { Err(FsError::NotDir) } fn get_entry(&self, _id: usize) -> Result<String> { Err(FsError::NotDir) }
fn io_control(&self, _cmd: u32, _data: u32) -> Result<()> { Err(FsError::NotSupported) }
fn fs(&self) -> Arc<FileSystem> { unimplemented!() } fn fs(&self) -> Arc<FileSystem> { unimplemented!() }
fn as_any_ref(&self) -> &Any { self } fn as_any_ref(&self) -> &Any { self }
fn chmod(&self, _mode: u16) -> Result<()> { Ok(()) }
}; };
} }
impl INode for Stdin { impl INode for Stdin {
fn read_at(&self, _offset: usize, buf: &mut [u8]) -> Result<usize> { fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize> {
buf[0] = self.pop() as u8; buf[0] = self.pop() as u8;
Ok(1) Ok(1)
} }
fn write_at(&self, _offset: usize, _buf: &[u8]) -> Result<usize> { fn write_at(&self, _offset: usize, _buf: &[u8]) -> Result<usize> {
unimplemented!() unimplemented!()
} }
fn poll(&self) -> Result<PollStatus> {
Ok(PollStatus {
read: self.can_read(),
write: false,
error: false,
})
}
impl_inode!(); impl_inode!();
} }
@ -84,5 +92,12 @@ impl INode for Stdout {
print!("{}", s); print!("{}", s);
Ok(buf.len()) Ok(buf.len())
} }
fn poll(&self) -> Result<PollStatus> {
Ok(PollStatus {
read: false,
write: true,
error: false,
})
}
impl_inode!(); impl_inode!();
} }

View File

@ -88,34 +88,24 @@ pub fn sys_poll(ufds: *mut PollFd, nfds: usize, timeout_msecs: usize) -> SysResu
let proc = process(); let proc = process();
let mut events = 0; let mut events = 0;
for poll in polls.iter_mut() { for poll in polls.iter_mut() {
poll.revents = PE::NONE; poll.revents = PE::empty();
match proc.files.get(&(poll.fd as usize)) { if let Some(file_like) = proc.files.get(&(poll.fd as usize)) {
Some(FileLike::File(_)) => { let status = file_like.poll()?;
// FIXME: assume it is stdin for now if status.error {
if poll.events.contains(PE::IN) && STDIN.can_read() { poll.revents |= PE::HUP;
poll.revents = poll.revents | PE::IN; events += 1;
events = events + 1;
} }
if status.read && poll.events.contains(PE::IN) {
poll.revents |= PE::IN;
events += 1;
} }
Some(FileLike::Socket(socket)) => { if status.write && poll.events.contains(PE::OUT) {
let (input, output, err) = socket.poll(); poll.revents |= PE::OUT;
if err { events += 1;
poll.revents = poll.revents | PE::HUP;
events = events + 1;
}
if input && poll.events.contains(PE::IN) {
poll.revents = poll.revents | PE::IN;
events = events + 1;
}
if output && poll.events.contains(PE::OUT) {
poll.revents = poll.revents | PE::OUT;
events = events + 1;
}
}
None => {
poll.revents = poll.revents | PE::ERR;
events = events + 1;
} }
} else {
poll.revents |= PE::ERR;
events += 1;
} }
} }
drop(proc); drop(proc);
@ -163,33 +153,21 @@ pub fn sys_select(
let proc = process(); let proc = process();
let mut events = 0; let mut events = 0;
for (&fd, file_like) in proc.files.iter() { for (&fd, file_like) in proc.files.iter() {
if fd < nfds { if fd >= nfds {
match file_like { continue;
FileLike::File(_) => {
// FIXME: assume it is stdin for now
if STDIN.can_read() {
if read_fds.contains(fd) {
read_fds.set(fd);
events = events + 1;
} }
} let status = file_like.poll()?;
} if status.error && err_fds.contains(fd) {
FileLike::Socket(socket) => {
let (input, output, err) = socket.poll();
if err && err_fds.contains(fd) {
err_fds.set(fd); err_fds.set(fd);
events = events + 1; events += 1;
} }
if input && read_fds.contains(fd) { if status.read && read_fds.contains(fd) {
read_fds.set(fd); read_fds.set(fd);
events = events + 1; events += 1;
} }
if output && write_fds.contains(fd) { if status.write && write_fds.contains(fd) {
write_fds.set(fd); write_fds.set(fd);
events = events + 1; events += 1;
}
}
}
} }
} }
drop(proc); drop(proc);
@ -1165,8 +1143,6 @@ pub struct PollFd {
bitflags! { bitflags! {
pub struct PollEvents: u16 { pub struct PollEvents: u16 {
/// Nothing Happens
const NONE = 0x0000;
/// There is data to read. /// There is data to read.
const IN = 0x0001; const IN = 0x0001;
/// Writing is now possible. /// Writing is now possible.