Skip to content

Commit

Permalink
ulib: call arceos_api in axstd (add fs)
Browse files Browse the repository at this point in the history
  • Loading branch information
equation314 committed Aug 5, 2023
1 parent b0ce7c0 commit ed333da
Show file tree
Hide file tree
Showing 11 changed files with 438 additions and 26 deletions.
2 changes: 0 additions & 2 deletions Cargo.lock

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

3 changes: 1 addition & 2 deletions apps/fs/shell/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ authors = ["Yuekai Jia <[email protected]>"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[features]
use-ramfs = ["axfeat/myfs", "dep:axfs_vfs", "dep:axfs_ramfs", "dep:crate_interface"]
use-ramfs = ["axstd/myfs", "dep:axfs_vfs", "dep:axfs_ramfs", "dep:crate_interface"]
default = []

[dependencies]
axfs_vfs = { path = "../../../crates/axfs_vfs", optional = true }
axfs_ramfs = { path = "../../../crates/axfs_ramfs", optional = true }
crate_interface = { path = "../../../crates/crate_interface", optional = true }
axstd = { path = "../../../ulib/axstd", features = ["alloc", "fs"], optional = true }
axfeat = { path = "../../../api/axfeat", optional = true }
4 changes: 2 additions & 2 deletions apps/fs/shell/src/ramfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ extern crate alloc;
use alloc::sync::Arc;
use axfs_ramfs::RamFileSystem;
use axfs_vfs::VfsOps;
use std::os::arceos::axfs::fops::{Disk, MyFileSystemIf};
use std::os::arceos::api::fs::{AxDisk, MyFileSystemIf};

struct MyFileSystemIfImpl;

#[crate_interface::impl_interface]
impl MyFileSystemIf for MyFileSystemIfImpl {
fn new_myfs(_disk: Disk) -> Arc<dyn VfsOps> {
fn new_myfs(_disk: AxDisk) -> Arc<dyn VfsOps> {
Arc::new(RamFileSystem::new())
}
}
22 changes: 14 additions & 8 deletions modules/axfs/src/api/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,27 +92,33 @@ impl Metadata {

/// Returns the size of the file, in bytes, this metadata is for.
#[allow(clippy::len_without_is_empty)]
pub fn len(&self) -> u64 {
pub const fn len(&self) -> u64 {
self.0.size()
}

/// Returns the permissions of the file this metadata is for.
pub fn permissions(&self) -> Permissions {
pub const fn permissions(&self) -> Permissions {
self.0.perm()
}

/// Returns the inner raw metadata [`fops::FileAttr`].
pub const fn raw_metadata(&self) -> &fops::FileAttr {
&self.0
/// Returns the total size of this file in bytes.
pub const fn size(&self) -> u64 {
self.0.size()
}

/// Returns the number of blocks allocated to the file, in 512-byte units.
pub const fn blocks(&self) -> u64 {
self.0.blocks()
}
}

impl fmt::Debug for Metadata {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Metadata")
.field("file_type", &self.0.file_type())
.field("is_dir", &self.0.is_dir())
.field("is_file", &self.0.is_file())
.field("file_type", &self.file_type())
.field("is_dir", &self.is_dir())
.field("is_file", &self.is_file())
.field("permissions", &self.permissions())
.finish_non_exhaustive()
}
}
Expand Down
3 changes: 1 addition & 2 deletions ulib/axlibc/src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,8 @@ impl FileLike for File {

fn stat(&self) -> LinuxResult<ctypes::stat> {
let metadata = self.0.lock().metadata()?;
let metadata = metadata.raw_metadata();
let ty = metadata.file_type() as u8;
let perm = metadata.perm().bits() as u32;
let perm = metadata.permissions().bits() as u32;
let st_mode = ((ty as u32) << 12) | perm;
Ok(ctypes::stat {
st_ino: 1,
Expand Down
5 changes: 2 additions & 3 deletions ulib/axstd/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ sched_rr = ["axfeat/sched_rr"]
sched_cfs = ["axfeat/sched_cfs"]

# File system
fs = ["dep:axfs", "arceos_api/fs", "axfeat/fs"]
myfs = ["axfeat/myfs"]
fs = ["arceos_api/fs", "axfeat/fs"]
myfs = ["arceos_api/myfs", "axfeat/myfs"]

# Networking
net = ["arceos_api/net", "axfeat/net"]
Expand All @@ -68,7 +68,6 @@ log-level-debug = ["axfeat/log-level-debug"]
log-level-trace = ["axfeat/log-level-trace"]

[dependencies]
axfs = { path = "../../modules/axfs", optional = true }
axfeat = { path = "../../api/axfeat" }
arceos_api = { path = "../../api/arceos_api" }
axio = { path = "../../crates/axio" }
Expand Down
5 changes: 0 additions & 5 deletions ulib/axstd/src/fs.rs

This file was deleted.

154 changes: 154 additions & 0 deletions ulib/axstd/src/fs/dir.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
extern crate alloc;

use alloc::string::String;
use core::fmt;

use super::FileType;
use crate::io::Result;

use arceos_api::fs as api;

/// Iterator over the entries in a directory.
pub struct ReadDir<'a> {
path: &'a str,
inner: api::AxDirHandle,
buf_pos: usize,
buf_end: usize,
end_of_stream: bool,
dirent_buf: [api::AxDirEntry; 31],
}

/// Entries returned by the [`ReadDir`] iterator.
pub struct DirEntry<'a> {
dir_path: &'a str,
entry_name: String,
entry_type: FileType,
}

/// A builder used to create directories in various manners.
#[derive(Default, Debug)]
pub struct DirBuilder {
recursive: bool,
}

impl<'a> ReadDir<'a> {
pub(super) fn new(path: &'a str) -> Result<Self> {
let mut opts = api::AxOpenOptions::new();
opts.read(true);
let inner = api::ax_open_dir(path, &opts)?;

const EMPTY: api::AxDirEntry = api::AxDirEntry::default();
let dirent_buf = [EMPTY; 31];
Ok(ReadDir {
path,
inner,
end_of_stream: false,
buf_pos: 0,
buf_end: 0,
dirent_buf,
})
}
}

impl<'a> Iterator for ReadDir<'a> {
type Item = Result<DirEntry<'a>>;

fn next(&mut self) -> Option<Result<DirEntry<'a>>> {
if self.end_of_stream {
return None;
}

loop {
if self.buf_pos >= self.buf_end {
match api::ax_read_dir(&mut self.inner, &mut self.dirent_buf) {
Ok(n) => {
if n == 0 {
self.end_of_stream = true;
return None;
}
self.buf_pos = 0;
self.buf_end = n;
}
Err(e) => {
self.end_of_stream = true;
return Some(Err(e));
}
}
}
let entry = &self.dirent_buf[self.buf_pos];
self.buf_pos += 1;
let name_bytes = entry.name_as_bytes();
if name_bytes == b"." || name_bytes == b".." {
continue;
}
let entry_name = unsafe { core::str::from_utf8_unchecked(name_bytes).into() };
let entry_type = entry.entry_type();

return Some(Ok(DirEntry {
dir_path: self.path,
entry_name,
entry_type,
}));
}
}
}

impl<'a> DirEntry<'a> {
/// Returns the full path to the file that this entry represents.
///
/// The full path is created by joining the original path to `read_dir`
/// with the filename of this entry.
pub fn path(&self) -> String {
String::from(self.dir_path.trim_end_matches('/')) + "/" + &self.entry_name
}

/// Returns the bare file name of this directory entry without any other
/// leading path component.
pub fn file_name(&self) -> String {
self.entry_name.clone()
}

/// Returns the file type for the file that this entry points at.
pub fn file_type(&self) -> FileType {
self.entry_type
}
}

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

impl DirBuilder {
/// Creates a new set of options with default mode/security settings for all
/// platforms and also non-recursive.
pub fn new() -> Self {
Self { recursive: false }
}

/// Indicates that directories should be created recursively, creating all
/// parent directories. Parents that do not exist are created with the same
/// security and permissions settings.
pub fn recursive(&mut self, recursive: bool) -> &mut Self {
self.recursive = recursive;
self
}

/// Creates the specified directory with the options configured in this
/// builder.
pub fn create(&self, path: &str) -> Result<()> {
if self.recursive {
self.create_dir_all(path)
} else {
api::ax_create_dir(path)
}
}

fn create_dir_all(&self, _path: &str) -> Result<()> {
axerrno::ax_err!(
Unsupported,
"Recursive directory creation is not supported yet"
)
}
}
Loading

0 comments on commit ed333da

Please sign in to comment.