diff --git a/kernel/src/file/buffer/mod.rs b/kernel/src/file/buffer/mod.rs index ad262005..06d4c12c 100644 --- a/kernel/src/file/buffer/mod.rs +++ b/kernel/src/file/buffer/mod.rs @@ -27,7 +27,6 @@ use crate::{ }; use core::{alloc::AllocError, any::Any, ffi::c_void}; use utils::{ - boxed::Box, collections::hashmap::HashMap, errno::{AllocResult, EResult}, lock::Mutex, @@ -54,7 +53,7 @@ pub trait BufferOps: Any + NodeOps { /// A buffer. #[derive(Clone, Debug)] -pub struct Buffer(Arc); +pub struct Buffer(pub Arc); impl Buffer { /// Creates a new instance with the given buffer type. @@ -91,20 +90,3 @@ impl NodeOps for Buffer { /// /// The key is the location of the file associated with the entry. pub static BUFFERS: Mutex> = Mutex::new(HashMap::new()); - -/// Returns the buffer associated with the file at location `loc`. -/// -/// If the buffer does not exist, the function registers a new default buffer. -pub fn get_or_default + 'static>( - loc: &FileLocation, -) -> AllocResult> { - let mut buffers = BUFFERS.lock(); - match buffers.get(loc).cloned() { - Some(buf) => Box::new(buf.clone()), - None => { - let buf = Buffer::new(B::try_default()?)?; - buffers.insert(loc.clone(), buf.clone())?; - Ok(buf) - } - } -} diff --git a/kernel/src/file/fs/tmp/mod.rs b/kernel/src/file/fs/tmp/mod.rs index 4cd66a1d..f30505fb 100644 --- a/kernel/src/file/fs/tmp/mod.rs +++ b/kernel/src/file/fs/tmp/mod.rs @@ -141,7 +141,7 @@ impl Node { inode: Option, parent_inode: Option, ) -> AllocResult { - let file_type = stat.get_type().ok_or_else(|| errno!(EINVAL))?; + let file_type = stat.get_type().unwrap(); let content = match file_type { FileType::Regular => NodeContent::Regular(Vec::new()), FileType::Directory => { @@ -371,7 +371,7 @@ impl NodeOps for Node { // Get node let node = fs.nodes.lock().get_node(inode)?.clone(); let mut inner = node.0.lock(); - let entry_type = FileType::from_mode(inner.as_stat().mode).unwrap(); + let entry_type = inner.as_stat().get_type().unwrap(); let mut parent_inner = self.0.lock(); // Get parent entries let NodeContent::Directory(parent_entries) = &mut parent_inner.content else { diff --git a/kernel/src/file/mod.rs b/kernel/src/file/mod.rs index 4c280608..28b89b18 100644 --- a/kernel/src/file/mod.rs +++ b/kernel/src/file/mod.rs @@ -39,6 +39,7 @@ use crate::{ device, device::{DeviceID, DeviceType}, file::{ + buffer::{Buffer, BufferOps}, fs::{Filesystem, NodeOps}, path::{Path, PathBuf}, perm::{Gid, Uid}, @@ -50,7 +51,7 @@ use crate::{ unit::{Timestamp, TimestampScale}, }, }; -use core::{ffi::c_void, ops::Deref}; +use core::{any::Any, ffi::c_void, ops::Deref}; use mountpoint::{MountPoint, MountSource}; use perm::AccessProfile; use utils::{ @@ -436,6 +437,14 @@ impl File { FileType::from_mode(stat.mode).ok_or_else(|| errno!(EUCLEAN)) } + /// Returns the file's associated buffer. + /// + /// If the file does not have a buffer of type `B`, the function returns `None`. + pub fn get_buffer(&self) -> Option<&B> { + let buf = (&self.ops as &dyn Any).downcast_ref::()?; + (buf.0.deref() as &dyn Any).downcast_ref() + } + /// Reads the whole content of a file into a buffer. /// /// This function does not change the file's offset. diff --git a/kernel/src/process/mod.rs b/kernel/src/process/mod.rs index 07f20332..e8791036 100644 --- a/kernel/src/process/mod.rs +++ b/kernel/src/process/mod.rs @@ -432,8 +432,7 @@ impl Process { let mut fds_table = FileDescriptorTable::default(); let tty_path = PathBuf::try_from(TTY_DEVICE_PATH.as_bytes())?; let tty_file = vfs::get_file_from_path(&tty_path, &rs)?; - let file = File::open(tty_file, Some(tty_path), file::O_RDWR)?; - let (stdin_fd_id, _) = fds_table.create_fd(0, file)?; + let (stdin_fd_id, _) = fds_table.create_fd(0, tty_file)?; assert_eq!(stdin_fd_id, STDIN_FILENO); fds_table.duplicate_fd( STDIN_FILENO as _, diff --git a/kernel/src/syscall/bind.rs b/kernel/src/syscall/bind.rs index 73336bdb..1a96d089 100644 --- a/kernel/src/syscall/bind.rs +++ b/kernel/src/syscall/bind.rs @@ -40,17 +40,9 @@ pub fn bind( return Err(errno!(EINVAL)); } // Get socket - let loc = fds - .lock() - .get_fd(sockfd)? - .get_file() - .lock() - .get_location() - .clone(); - let sock = buffer::get(&loc).ok_or_else(|| errno!(ENOENT))?; - let sock = (&*sock as &dyn Any) - .downcast_ref::() - .ok_or_else(|| errno!(ENOTSOCK))?; + let file_mutex = fds.lock().get_fd(sockfd)?.get_file().clone(); + let file = file_mutex.lock(); + let sock: &Socket = file.get_buffer().ok_or_else(|| errno!(ENOTSOCK))?; let addr = addr .copy_from_user(..(addrlen as usize))? .ok_or_else(|| errno!(EFAULT))?; diff --git a/kernel/src/syscall/connect.rs b/kernel/src/syscall/connect.rs index 64d74921..dde64c42 100644 --- a/kernel/src/syscall/connect.rs +++ b/kernel/src/syscall/connect.rs @@ -41,17 +41,9 @@ pub fn connect( return Err(errno!(EINVAL)); } // Get socket - let loc = fds - .lock() - .get_fd(sockfd)? - .get_file() - .lock() - .get_location() - .clone(); - let sock = buffer::get(&loc).ok_or_else(|| errno!(ENOENT))?; - let _sock = (&*sock as &dyn Any) - .downcast_ref::() - .ok_or_else(|| errno!(ENOTSOCK))?; + let file_mutex = fds.lock().get_fd(sockfd)?.get_file().clone(); + let file = file_mutex.lock(); + let _sock: &Socket = file.get_buffer().ok_or_else(|| errno!(ENOTSOCK))?; let _addr = addr .copy_from_user(..(addrlen as usize))? .ok_or_else(|| errno!(EFAULT))?; diff --git a/kernel/src/syscall/fcntl.rs b/kernel/src/syscall/fcntl.rs index 0427a382..4343bb84 100644 --- a/kernel/src/syscall/fcntl.rs +++ b/kernel/src/syscall/fcntl.rs @@ -253,12 +253,8 @@ pub fn do_fcntl( F_GETPIPE_SZ => { let file_mutex = fds.get_fd(fd)?.get_file(); let file = file_mutex.lock(); - match file.get_type()? { - FileType::Fifo => { - let buf = buffer::get_or_default::(&file.get_location())?; - let buf: &PipeBuffer = (&*buf as &dyn Any).downcast_ref().unwrap(); - Ok(buf.get_capacity() as _) - } + match file.get_buffer::() { + Some(fifo) => Ok(fifo.get_capacity() as _), _ => Ok(0), } } diff --git a/kernel/src/syscall/getsockname.rs b/kernel/src/syscall/getsockname.rs index b0342876..97b21fd5 100644 --- a/kernel/src/syscall/getsockname.rs +++ b/kernel/src/syscall/getsockname.rs @@ -39,17 +39,9 @@ pub fn getsockname( fds: Arc>, ) -> EResult { // Get socket - let loc = fds - .lock() - .get_fd(sockfd)? - .get_file() - .lock() - .get_location() - .clone(); - let sock = buffer::get(&loc).ok_or_else(|| errno!(ENOENT))?; - let sock = (&*sock as &dyn Any) - .downcast_ref::() - .ok_or_else(|| errno!(ENOTSOCK))?; + let file_mutex = fds.lock().get_fd(sockfd)?.get_file().clone(); + let file = file_mutex.lock(); + let sock: &Socket = file.get_buffer().ok_or_else(|| errno!(ENOTSOCK))?; // Read and check buffer length let addrlen_val = addrlen.copy_from_user()?.ok_or_else(|| errno!(EFAULT))?; if addrlen_val < 0 { diff --git a/kernel/src/syscall/getsockopt.rs b/kernel/src/syscall/getsockopt.rs index 78596d7d..c37914d5 100644 --- a/kernel/src/syscall/getsockopt.rs +++ b/kernel/src/syscall/getsockopt.rs @@ -42,17 +42,9 @@ pub fn getsockopt( fds: Arc>, ) -> EResult { // Get socket - let loc = fds - .lock() - .get_fd(sockfd)? - .get_file() - .lock() - .get_location() - .clone(); - let sock = buffer::get(&loc).ok_or_else(|| errno!(ENOENT))?; - let sock = (&*sock as &dyn Any) - .downcast_ref::() - .ok_or_else(|| errno!(ENOTSOCK))?; + let file_mutex = fds.lock().get_fd(sockfd)?.get_file().clone(); + let file = file_mutex.lock(); + let sock: &Socket = file.get_buffer().ok_or_else(|| errno!(ENOTSOCK))?; let val = sock.get_opt(level, optname)?; // Write back let len = min(val.len(), optlen); diff --git a/kernel/src/syscall/sendto.rs b/kernel/src/syscall/sendto.rs index c8013a18..da596a76 100644 --- a/kernel/src/syscall/sendto.rs +++ b/kernel/src/syscall/sendto.rs @@ -49,17 +49,9 @@ pub fn sendto( return Err(errno!(EINVAL)); } // Get socket - let loc = fds - .lock() - .get_fd(sockfd)? - .get_file() - .lock() - .get_location() - .clone(); - let sock = buffer::get(&loc).ok_or_else(|| errno!(ENOENT))?; - let _sock = (&*sock as &dyn Any) - .downcast_ref::() - .ok_or_else(|| errno!(ENOTSOCK))?; + let file_mutex = fds.lock().get_fd(sockfd)?.get_file().clone(); + let file = file_mutex.lock(); + let _sock: &Socket = file.get_buffer().ok_or_else(|| errno!(ENOTSOCK))?; // Get slices let _buf_slice = buf.copy_from_user(..len)?.ok_or(errno!(EFAULT))?; let _dest_addr_slice = dest_addr diff --git a/kernel/src/syscall/setsockopt.rs b/kernel/src/syscall/setsockopt.rs index 59cf5034..ad98779e 100644 --- a/kernel/src/syscall/setsockopt.rs +++ b/kernel/src/syscall/setsockopt.rs @@ -42,17 +42,9 @@ pub fn setsockopt( fds: Arc>, ) -> EResult { // Get socket - let loc = fds - .lock() - .get_fd(sockfd)? - .get_file() - .lock() - .get_location() - .clone(); - let sock = buffer::get(&loc).ok_or_else(|| errno!(ENOENT))?; - let sock = (&*sock as &dyn Any) - .downcast_ref::() - .ok_or_else(|| errno!(ENOTSOCK))?; + let file_mutex = fds.lock().get_fd(sockfd)?.get_file().clone(); + let file = file_mutex.lock(); + let sock: &Socket = file.get_buffer().ok_or_else(|| errno!(ENOTSOCK))?; // Set opt let optval_slice = optval.copy_from_user(..optlen)?.ok_or(errno!(EFAULT))?; sock.set_opt(level, optname, &optval_slice) diff --git a/kernel/src/syscall/shutdown.rs b/kernel/src/syscall/shutdown.rs index 09f4f04f..543be6fe 100644 --- a/kernel/src/syscall/shutdown.rs +++ b/kernel/src/syscall/shutdown.rs @@ -43,17 +43,9 @@ pub fn shutdown( fds: Arc>, ) -> EResult { // Get socket - let loc = fds - .lock() - .get_fd(sockfd)? - .get_file() - .lock() - .get_location() - .clone(); - let sock = buffer::get(&loc).ok_or_else(|| errno!(ENOENT))?; - let sock = (&*sock as &dyn Any) - .downcast_ref::() - .ok_or_else(|| errno!(ENOTSOCK))?; + let file_mutex = fds.lock().get_fd(sockfd)?.get_file().clone(); + let file = file_mutex.lock(); + let sock: &Socket = file.get_buffer().ok_or_else(|| errno!(ENOTSOCK))?; // Do shutdown match how { SHUT_RD => sock.shutdown_reception(),