Skip to content

Commit

Permalink
Implement fmt::Debug for inode objects (#57)
Browse files Browse the repository at this point in the history
  • Loading branch information
nuta authored Nov 7, 2021

Verified

This commit was signed with the committer’s verified signature. The key has expired.
haxscramper haxscramper
1 parent 4620647 commit c160396
Showing 14 changed files with 158 additions and 30 deletions.
2 changes: 1 addition & 1 deletion kernel/fs/devfs/mod.rs
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ impl DevFs {
let pts_dir = root_dir.add_dir("pts");

NULL_FILE.init(|| Arc::new(NullFile::new()) as Arc<dyn FileLike>);
SERIAL_TTY.init(|| Arc::new(Tty::new()));
SERIAL_TTY.init(|| Arc::new(Tty::new("serial")));
PTMX.init(|| Arc::new(Ptmx::new(pts_dir)));

root_dir.add_file("null", NULL_FILE.clone());
8 changes: 8 additions & 0 deletions kernel/fs/devfs/null.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use core::fmt;

use crate::{
fs::{
inode::{FileLike, INodeNo},
@@ -18,6 +20,12 @@ impl NullFile {
}
}

impl fmt::Debug for NullFile {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("DevNull").finish()
}
}

impl FileLike for NullFile {
fn stat(&self) -> Result<Stat> {
Ok(Stat {
15 changes: 14 additions & 1 deletion kernel/fs/devfs/tty.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
use arrayvec::ArrayString;
use core::fmt;

use crate::{
arch::{print_str, SpinLock, UserVAddr},
ctypes::*,
@@ -15,12 +18,16 @@ use crate::{
};

pub struct Tty {
name: ArrayString<8>,
discipline: LineDiscipline,
}

impl Tty {
pub fn new() -> Tty {
pub fn new(name: &str) -> Tty {
let mut name_buf = ArrayString::new();
let _ = name_buf.try_push_str(name);
Tty {
name: name_buf,
discipline: LineDiscipline::new(),
}
}
@@ -51,6 +58,12 @@ const TIOCGPGRP: usize = 0x540f;
const TIOCSPGRP: usize = 0x5410;
const TIOCGWINSZ: usize = 0x5413;

impl fmt::Debug for Tty {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Tty").field("name", &self.name).finish()
}
}

impl FileLike for Tty {
fn ioctl(&self, cmd: usize, arg: usize) -> Result<isize> {
match cmd {
26 changes: 25 additions & 1 deletion kernel/fs/initramfs.rs
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ use crate::{
prelude::*,
user_buffer::{UserBufWriter, UserBuffer, UserBufferMut},
};
use core::str::from_utf8_unchecked;
use core::{fmt, str::from_utf8_unchecked};
use hashbrown::HashMap;
use kerla_utils::byte_size::ByteSize;
use kerla_utils::bytes_parser::BytesParser;
@@ -54,6 +54,14 @@ impl FileLike for InitramFsFile {
}
}

impl fmt::Debug for InitramFsFile {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("InitramFsFile")
.field("name", &self.filename)
.finish()
}
}

enum InitramFsINode {
File(Arc<InitramFsFile>),
Directory(Arc<InitramFsDir>),
@@ -117,6 +125,14 @@ impl Directory for InitramFsDir {
}
}

impl fmt::Debug for InitramFsDir {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("InitramFsDir")
.field("name", &self.filename)
.finish()
}
}

struct InitramFsSymlink {
filename: &'static str,
stat: Stat,
@@ -133,6 +149,14 @@ impl Symlink for InitramFsSymlink {
}
}

impl fmt::Debug for InitramFsSymlink {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("InitramFsSymlink")
.field("name", &self.filename)
.finish()
}
}

pub struct InitramFs {
root_dir: Arc<InitramFsDir>,
}
38 changes: 15 additions & 23 deletions kernel/fs/inode.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use core::fmt::{self, Debug};

use super::{opened_file::OpenOptions, path::PathBuf, stat::FileMode};
use crate::ctypes::c_short;
use crate::prelude::*;
@@ -40,27 +42,7 @@ bitflags! {
///
/// This trait represents an object which behaves like a file such as files on
/// disks (aka. regular files), UDP/TCP sockets, device files like tty, etc.
///
/// # Locking
///
/// Some `FileLike` implementation assume **the owner process's lock are not held.**
///
/// The following code would cause a dead lock if `FileLike` implementation also
/// internally tries to lock the owner process:
///
/// ```ignore
/// // DON'T DO THIS: The owner process lock is held when `FileLike::stat()` is
/// // called. It will cause a dead lock if the method tries to lock it :/
/// current_process().opened_files().lock().get(fd)?.stat()?;
/// // ^^^^^^^^^
/// // OpenedFileTable::get() returns &Arc<...>.
/// // The current process lock needs to be held.
///
/// // GOOD: The owner process is unlocked when `FileLike::stat()` is called :D
/// let opened_file: Arc<SpinLock<OpenedFile>> = current_process().get_opened_file_by_fd(fd)?;
/// opened_file.stat()?;
/// ```
pub trait FileLike: Send + Sync + Downcastable {
pub trait FileLike: Debug + Send + Sync + Downcastable {
/// `open(2)`.
fn open(&self, _options: &OpenOptions) -> Result<Option<Arc<dyn FileLike>>> {
Ok(None)
@@ -180,7 +162,7 @@ pub struct DirEntry {
}

/// Represents a directory.
pub trait Directory: Send + Sync + Downcastable {
pub trait Directory: Debug + Send + Sync + Downcastable {
/// Looks for an existing file.
fn lookup(&self, name: &str) -> Result<INode>;
/// Creates a file. Returns `EEXIST` if the it already exists.
@@ -209,7 +191,7 @@ pub trait Directory: Send + Sync + Downcastable {
/// # Locking
///
/// See [`FileLike`] documentation.
pub trait Symlink: Send + Sync + Downcastable {
pub trait Symlink: Debug + Send + Sync + Downcastable {
/// `stat(2)`.
fn stat(&self) -> Result<Stat>;
/// The path linked to.
@@ -296,6 +278,16 @@ impl INode {
}
}

impl fmt::Debug for INode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
INode::FileLike(file) => fmt::Debug::fmt(file, f),
INode::Directory(dir) => fmt::Debug::fmt(dir, f),
INode::Symlink(symlink) => fmt::Debug::fmt(symlink, f),
}
}
}

impl From<Arc<dyn FileLike>> for INode {
fn from(file: Arc<dyn FileLike>) -> Self {
INode::FileLike(file)
4 changes: 4 additions & 0 deletions kernel/fs/opened_file.rs
Original file line number Diff line number Diff line change
@@ -166,6 +166,10 @@ impl OpenedFile {
&self.path
}

pub fn inode(&self) -> &INode {
&self.path.inode
}

pub fn read(&mut self, buf: UserBufferMut<'_>) -> Result<usize> {
let read_len = self.as_file()?.read(self.pos, buf, &self.options)?;
self.pos += read_len;
17 changes: 16 additions & 1 deletion kernel/fs/tmpfs.rs
Original file line number Diff line number Diff line change
@@ -2,7 +2,10 @@ use crate::{
prelude::*,
user_buffer::{UserBufReader, UserBufWriter},
};
use core::sync::atomic::{AtomicUsize, Ordering};
use core::{
fmt,
sync::atomic::{AtomicUsize, Ordering},
};

use super::{
file_system::FileSystem,
@@ -172,6 +175,12 @@ impl Directory for Dir {
}
}

impl fmt::Debug for Dir {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("TmpFsDir").finish()
}
}

struct File {
data: SpinLock<Vec<u8>>,
stat: Stat,
@@ -213,6 +222,12 @@ impl FileLike for File {
}
}

impl fmt::Debug for File {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("TmpFsFile").finish()
}
}

pub fn init() {
TMP_FS.init(|| Arc::new(TmpFs::new()));
}
8 changes: 7 additions & 1 deletion kernel/net/tcp_socket.rs
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@ use crate::{
result::{Errno, Result},
};
use alloc::{collections::BTreeSet, sync::Arc, vec::Vec};
use core::{cmp::min, convert::TryInto};
use core::{cmp::min, convert::TryInto, fmt};
use crossbeam::atomic::AtomicCell;
use smoltcp::socket::{SocketRef, TcpSocketBuffer};
use smoltcp::wire::{IpAddress, IpEndpoint, Ipv4Address};
@@ -295,3 +295,9 @@ impl FileLike for TcpSocket {
Ok(status)
}
}

impl fmt::Debug for TcpSocket {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("TcpSocket").finish()
}
}
8 changes: 7 additions & 1 deletion kernel/net/udp_socket.rs
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ use crate::{
user_buffer::{UserBufReader, UserBufWriter, UserBufferMut},
};
use alloc::{collections::BTreeSet, sync::Arc};
use core::convert::TryInto;
use core::{convert::TryInto, fmt};
use smoltcp::socket::{UdpPacketMetadata, UdpSocketBuffer};
use smoltcp::wire::IpEndpoint;

@@ -122,3 +122,9 @@ impl FileLike for UdpSocket {
Ok(status)
}
}

impl fmt::Debug for UdpSocket {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("UdpSocket").finish()
}
}
8 changes: 8 additions & 0 deletions kernel/net/unix_socket.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use core::fmt;

use alloc::sync::Arc;

use crate::{
@@ -19,3 +21,9 @@ impl FileLike for UnixSocket {
Err(Errno::EACCES.into())
}
}

impl fmt::Debug for UnixSocket {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("UnixSocket").finish()
}
}
14 changes: 14 additions & 0 deletions kernel/pipe.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
//! Unnamed pipe (`pipe(2)`).
use core::fmt;

use kerla_utils::{once::Once, ring_buffer::RingBuffer};

use crate::{
@@ -106,6 +108,12 @@ impl FileLike for PipeWriter {
}
}

impl fmt::Debug for PipeWriter {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("PipeWriter").finish()
}
}

impl Drop for PipeWriter {
fn drop(&mut self) {
self.0.lock().closed_by_writer = true;
@@ -155,6 +163,12 @@ impl FileLike for PipeReader {
}
}

impl fmt::Debug for PipeReader {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("PipeReader").finish()
}
}

impl Drop for PipeReader {
fn drop(&mut self) {
self.0.lock().closed_by_reader = false;
8 changes: 8 additions & 0 deletions kernel/syscalls/read.rs
Original file line number Diff line number Diff line change
@@ -8,6 +8,14 @@ impl<'a> SyscallHandler<'a> {
let len = min(len, MAX_READ_WRITE_LEN);

let opened_file = current_process().get_opened_file_by_fd(fd)?;
trace!(
"[{}:{}] read(file={:?}, len={})",
current_process().pid().as_i32(),
current_process().cmdline().argv0(),
opened_file.lock().inode(),
len
);

let read_len = opened_file
.lock()
.read(UserBufferMut::from_uaddr(uaddr, len))?;
8 changes: 8 additions & 0 deletions kernel/syscalls/write.rs
Original file line number Diff line number Diff line change
@@ -9,6 +9,14 @@ impl<'a> SyscallHandler<'a> {
let len = min(len, MAX_READ_WRITE_LEN);

let opened_file = current_process().get_opened_file_by_fd(fd)?;
trace!(
"[{}:{}] write(file={:?}, len={})",
current_process().pid().as_i32(),
current_process().cmdline().argv0(),
opened_file.lock().inode(),
len
);

let written_len = opened_file
.lock()
.write(UserBuffer::from_uaddr(uaddr, len))?;
Loading

0 comments on commit c160396

Please sign in to comment.