Skip to content
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ axtask = { git = "https://github.com/oscomp/arceos.git" }

axprocess = { git = "https://github.com/Starry-OS/axprocess.git" }
axsignal = { git = "https://github.com/Starry-OS/axsignal.git", rev = "b5b6089" }
axalloc = { git = "https://github.com/oscomp/arceos.git" }

axerrno = "0.1"
bitflags = "2.6"
Expand All @@ -51,6 +52,7 @@ linux-raw-sys = { version = "0.9.3", default-features = false, features = [
] }
memory_addr = "0.3"
spin = "0.9"
lazy_static = { version = "1.5", features = ["spin_no_std"] }

starry-core = { path = "./core" }
starry-api = { path = "./api" }
Expand Down Expand Up @@ -78,6 +80,7 @@ axtask.workspace = true

axprocess.workspace = true
axsignal.workspace = true
axalloc.workspace = true

axerrno.workspace = true
linkme.workspace = true
Expand All @@ -90,5 +93,5 @@ shlex = { version = "1.3.0", default-features = false }
syscalls = { git = "https://github.com/jasonwhite/syscalls.git", rev = "92624de", default-features = false }

[patch.crates-io]
page_table_multiarch = { git = "https://github.com/Mivik/page_table_multiarch.git", rev = "19ededd" }
page_table_entry = { git = "https://github.com/Mivik/page_table_multiarch.git", rev = "19ededd" }
page_table_multiarch = { git = "https://github.com/OrangeQi-CQ/page_table_multiarch", rev = "8bbd18a"}
page_table_entry = { git = "https://github.com/OrangeQi-CQ/page_table_multiarch", rev = "8bbd18a"}
2 changes: 2 additions & 0 deletions api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ axnet.workspace = true
axns.workspace = true
axsync.workspace = true
axtask.workspace = true
axalloc.workspace = true

axprocess.workspace = true
axsignal.workspace = true
Expand All @@ -36,6 +37,7 @@ axio = "0.1.1"
ctor_bare = "0.2.1"
flatten_objects = "0.2.3"
num_enum = { version = "0.7", default-features = false }
lazy_static = { version = "1.5", features = ["spin_no_std"] }

[target.'cfg(target_arch = "x86_64")'.dependencies]
x86 = "0.52"
157 changes: 145 additions & 12 deletions api/src/file/fs.rs
Original file line number Diff line number Diff line change
@@ -1,56 +1,189 @@
use core::{any::Any, ffi::c_int};
use core::{
any::Any,
ffi::c_int,
sync::atomic::{AtomicUsize, Ordering},
};

use alloc::{string::String, sync::Arc};
use alloc::{
string::String,
sync::{Arc, Weak},
};
use axerrno::{LinuxError, LinuxResult};
use axfs::fops::DirEntry;
use axio::PollState;
use axio::SeekFrom;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merge it with axio::PollState

use axsync::{Mutex, MutexGuard};
use linux_raw_sys::general::S_IFDIR;

use super::{FileLike, Kstat, get_file_like};
use super::{
FileLike, Kstat, get_file_like,
page_cache::{PageCache, page_cache_manager},
};

/// File wrapper for `axfs::fops::File`.
pub struct File {
inner: Mutex<axfs::fops::File>,
inner: Option<Arc<Mutex<axfs::fops::File>>>,
path: String,
is_direct: bool,
cache: Weak<PageCache>,
offset: AtomicUsize,
size: AtomicUsize,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can split the direct File and the cache into two type and use an Enum to include them.

And those methods below can use match for the Enum rather than use self.is_direct for every times

}

impl File {
pub fn new(inner: axfs::fops::File, path: String) -> Self {
pub fn new(
inner: Option<Arc<Mutex<axfs::fops::File>>>,
path: String,
is_direct: bool,
cache: Weak<PageCache>,
) -> Self {
debug!("Starry-api open file {}", path);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this log

let size = {
if is_direct {
let inner = inner.clone().unwrap();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can you judge this inner is Some(..)?

let inner = inner.lock();
let metadata = inner.get_attr().unwrap();
metadata.size() as usize
} else {
let cache = cache.upgrade().unwrap();
cache.get_file_size()
}
};
Self {
inner: Mutex::new(inner),
inner,
path,
is_direct,
cache,
offset: AtomicUsize::new(0),
size: AtomicUsize::new(size),
}
}

pub fn get_cache(&self) -> Arc<PageCache> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename it as cache()

self.cache.upgrade().unwrap()
}

pub fn get_size(&self) -> usize {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename it as size()

self.size.load(Ordering::SeqCst)
}

/// Get the path of the file.
pub fn path(&self) -> &str {
&self.path
}

/// Get the inner node of the file.
pub fn inner(&self) -> MutexGuard<axfs::fops::File> {
self.inner.lock()
fn inner(&self) -> MutexGuard<axfs::fops::File> {
self.inner.as_ref().unwrap().lock()
}

pub fn seek(&self, pos: SeekFrom) -> LinuxResult<isize> {
if self.is_direct {
match self.inner().seek(pos) {
Ok(pos) => return Ok(pos as isize),
Err(e) => {
error!("Seek failed: {}", e);
return Err(LinuxError::EINVAL);
}
}
}
let size = self.size.load(Ordering::SeqCst) as u64;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use self.size()

let offset = self.offset.load(Ordering::SeqCst) as u64;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

create a new method offset() and use self.offset()

let new_offset = match pos {
SeekFrom::Start(pos) => Some(pos),
SeekFrom::Current(off) => offset.checked_add_signed(off),
SeekFrom::End(off) => size.checked_add_signed(off),
}
.unwrap();
self.offset.store(new_offset as usize, Ordering::SeqCst);
Ok(new_offset as isize)
}

pub fn fsync(&self) -> LinuxResult<usize> {
if self.is_direct {
return Ok(0);
}
let cache = self.get_cache();
Ok(cache.sync()?)
}

pub fn read_at(&self, buf: &mut [u8], offset: usize) -> LinuxResult<usize> {
if self.is_direct {
return Ok(self.inner().read_at(offset as u64, buf)?);
}

let cache = self.get_cache();
Ok(cache.read_at(offset, buf))
}

pub fn write_at(&self, buf: &[u8], offset: usize) -> LinuxResult<usize> {
if self.is_direct {
return Ok(self.inner().write_at(offset as u64, buf)?);
}

let cache = self.get_cache();
Ok(cache.write_at(offset, buf))
}

pub fn truncate(&self, offset: usize) -> LinuxResult<usize> {
if self.is_direct {
self.inner().truncate(offset as u64)?;
return Ok(offset);
}
let cache = self.get_cache();
Ok(cache.truncate(offset) as usize)
}
}

impl Drop for File {
fn drop(&mut self) {
debug!("Starry-api drop file {}", self.path);
if !self.is_direct {
let cache_manager = page_cache_manager();
cache_manager.close_page_cache(&self.path);
}
}
}

impl FileLike for File {
fn read(&self, buf: &mut [u8]) -> LinuxResult<usize> {
Ok(self.inner().read(buf)?)
if self.is_direct {
return Ok(self.inner().read(buf)?);
}

let cache = self.get_cache();
let offset = self.offset.load(Ordering::SeqCst);
let len = cache.write_at(offset, buf);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why use write_at instead of read?

self.offset.fetch_add(len, Ordering::SeqCst);
Ok(len)
}

fn write(&self, buf: &[u8]) -> LinuxResult<usize> {
Ok(self.inner().write(buf)?)
if self.is_direct {
return Ok(self.inner().write(buf)?);
}

let cache = self.get_cache();
let offset = self.offset.load(Ordering::SeqCst);
let len = cache.write_at(offset, buf);
self.offset.fetch_add(len, Ordering::SeqCst);
self.size.fetch_max(offset + len, Ordering::SeqCst);
Ok(len)
}

fn stat(&self) -> LinuxResult<Kstat> {
if !self.is_direct {
let cache = self.get_cache();
return cache.stat();
}

let metadata = self.inner().get_attr()?;
let ty = metadata.file_type() as u8;
let perm = metadata.perm().bits() as u32;

let size = self.size.load(Ordering::SeqCst);
Ok(Kstat {
mode: ((ty as u32) << 12) | perm,
size: metadata.size(),
size: size as u64,
blocks: metadata.blocks(),
blksize: 512,
..Default::default()
Expand Down
2 changes: 2 additions & 0 deletions api/src/file/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod fs;
mod net;
mod page_cache;
mod pipe;
mod stdio;

Expand All @@ -16,6 +17,7 @@ use spin::RwLock;
pub use self::{
fs::{Directory, File},
net::Socket,
page_cache::page_cache_manager,
pipe::Pipe,
};

Expand Down
Loading
Loading