Skip to content

Commit 165b19c

Browse files
committed
fix: resolve cargo feature dependencies and compilation issues
1 parent 99fd643 commit 165b19c

File tree

33 files changed

+6360
-984
lines changed

33 files changed

+6360
-984
lines changed

Cargo.lock

Lines changed: 3489 additions & 826 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ axdriver_pci = "0.1.4-preview.3"
8080
axdriver_virtio = "0.1.4-preview.3"
8181
axdriver_vsock = "0.1.4-preview.3"
8282
axerrno = "0.1"
83+
axfs-ng-vfs = "0.1"
8384
axio = "0.2"
8485
axklib = "0.2"
8586
axplat = ">=0.3.0-preview.2, <0.3.0"

api/arceos_api/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ fs = ["dep:axfs", "dep:axdriver", "axfeat/fs"]
2222
net = ["dep:axnet", "dep:axdriver", "axfeat/net"]
2323
display = ["dep:axdisplay", "dep:axdriver", "axfeat/display"]
2424

25-
myfs = ["axfeat/myfs"]
25+
myfs = ["axfeat/fs"]
2626

2727
# Use dummy functions if the feature is not enabled
2828
dummy-if-not-enabled = []

api/axfeat/Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ page-alloc-64g = ["axalloc/page-alloc-64g"] # up to 64G memory
3939
page-alloc-4g = ["axalloc/page-alloc-4g"] # up to 4G memory capacity
4040
paging = ["alloc", "axhal/paging", "axruntime/paging"]
4141
tls = ["alloc", "axhal/tls", "axruntime/tls", "axtask?/tls"]
42-
dma = ["alloc", "paging"]
42+
dma = ["alloc", "paging", "axruntime/dma"]
4343

4444
# Multi-threading and scheduler
4545
multitask = [
@@ -61,9 +61,9 @@ fs = [
6161
"dep:axfs",
6262
"axruntime/fs",
6363
] # TODO: try to remove "paging"
64-
myfs = ["axfs?/myfs"]
65-
ext4fs = ["axfs?/ext4fs"]
66-
fatfs = ["axfs?/fatfs"]
64+
fs-ext4 = ["fs", "axfs/ext4"]
65+
fs-fat = ["fs", "axfs/fat"]
66+
fs-times = ["fs", "axfs/times"]
6767

6868
# Networking
6969
net = ["alloc", "paging", "axdriver/virtio-net", "dep:axnet", "axruntime/net"]

modules/axfs/Cargo.toml

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,71 @@
11
[package]
2-
name = "axfs"
3-
description = "Axvisor filesystem module"
2+
authors = ["Mivik <mivikq@gmail.com>"]
3+
description = "ArceOS filesystem module"
44
edition.workspace = true
5+
homepage.workspace = true
56
license.workspace = true
7+
name = "axfs"
68
version.workspace = true
79

810
[features]
9-
use-ramdisk = []
11+
default = []
12+
monolitic = []
13+
fat = ["dep:fatfs"]
14+
ext4 = ["dep:lwext4_rust"]
15+
std = ["lwext4_rust?/std"]
16+
times = []
17+
use-ramdisk = [] # TODO: init ramdisk
1018

1119
[dependencies]
20+
axalloc = {workspace = true}
1221
axdriver = {workspace = true, features = ["block"]}
1322
axdriver_block = "0.1.4-preview.3"
14-
axerrno = "0.1"
23+
axerrno = {workspace = true}
24+
axfs-ng-vfs = {workspace = true}
1525
axfs_ramfs = {version = "0.1"}
1626
axfs_vfs = "0.1"
17-
axio = {version = "0.2", features = ["alloc"]}
27+
axhal = {workspace = true}
28+
axio = {workspace = true, features = ["alloc"]}
29+
axpoll = {workspace = true}
30+
axsync = {workspace = true}
31+
bitflags = "2.10"
1832
cap_access = "0.1"
33+
cfg-if = {workspace = true}
34+
chrono = {workspace = true}
35+
intrusive-collections = "0.9.7"
36+
kspin = {workspace = true}
1937
lazyinit = "0.2"
20-
spin = "0.9"
21-
log = "0.4"
38+
log = {workspace = true}
39+
lru = "0.16.0"
2240
rsext4 = "0.1.0-pre.0"
41+
scope-local = {workspace = true}
42+
slab = {version = "0.4.9", default-features = false}
43+
spin = {workspace = true}
2344

2445
[dependencies.axfatfs]
2546
version = "0.1.0-pre.0"
2647
default-features = false
2748
features = [
49+
# no std
2850
"alloc",
2951
"lfn",
3052
"log_level_trace",
3153
"unicode",
3254
]
3355

56+
[dependencies.lwext4_rust]
57+
version = "0.3.1-preview.1"
58+
default-features = false
59+
optional = true
60+
61+
[dependencies.fatfs]
62+
version = "0.4.1-preview.2"
63+
package = "starry-fatfs"
64+
default-features = false
65+
optional = true
66+
features = ["alloc", "lfn", "log_level_trace", "unicode"]
67+
3468
[dev-dependencies]
3569
axdriver = {workspace = true, features = ["block", "ramdisk"]}
36-
axdriver_block = {version = "0.1.4-preview.3", features = ["ramdisk"]}
70+
axdriver_block = {version = "0.1.4-preview.3", features = ["ramdisk"]}
71+
env_logger = "0.11.8"

modules/axfs/resources/make_fs.sh

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/bin/bash
2+
3+
CUR_DIR=$(dirname $0)
4+
5+
write_fs() {
6+
for i in $(seq 1 1000); do
7+
echo "Rust is cool!" >>long.txt
8+
done
9+
echo "Rust is cool!" >short.txt
10+
mkdir -p a/long/path
11+
echo "Rust is cool!" >a/long/path/test.txt
12+
mkdir -p very-long-dir-name
13+
echo "Rust is cool!" >>very-long-dir-name/very-long-file-name.txt
14+
}
15+
init_fs() {
16+
local name=$1
17+
local options=$2
18+
mkdir -p mnt
19+
sudo mount -o loop "$name" mnt -o "$options"
20+
21+
sudo chmod 777 mnt
22+
23+
cd mnt
24+
write_fs
25+
cd ..
26+
27+
sudo umount mnt
28+
rm -r mnt
29+
}
30+
create_fat_img() {
31+
local name=$1
32+
local kb=$2
33+
local fatSize=$3
34+
dd if=/dev/zero of="$name" bs=1K count=$kb
35+
mkfs.vfat -s 1 -F $fatSize "$name"
36+
37+
init_fs "$name" rw,uid=$USER,gid=$USER
38+
}
39+
create_ext4_img() {
40+
local name=$1
41+
local kb=$2
42+
dd if=/dev/zero of="$name" bs=1K count=$kb
43+
mkfs.ext4 -O ^metadata_csum "$name"
44+
45+
init_fs "$name" rw
46+
}
47+
48+
create_fat_img "$CUR_DIR/fat16.img" 2500 16
49+
create_fat_img "$CUR_DIR/fat32.img" 34000 32
50+
51+
create_ext4_img "$CUR_DIR/ext4.img" 30000

modules/axfs/src/api/dir.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,6 @@ impl DirBuilder {
156156
}
157157

158158
fn create_dir_all(&self, _path: &str) -> Result<()> {
159-
axerrno::ax_err!(
160-
Unsupported,
161-
"Recursive directory creation is not supported yet"
162-
)
159+
Err(axerrno::AxError::Unsupported.into())
163160
}
164161
}

modules/axfs/src/disk.rs

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
use alloc::{boxed::Box, vec};
2+
use core::mem;
3+
4+
use axdriver::prelude::*;
5+
6+
fn take<'a>(buf: &mut &'a [u8], cnt: usize) -> &'a [u8] {
7+
let (first, rem) = buf.split_at(cnt);
8+
*buf = rem;
9+
first
10+
}
11+
12+
fn take_mut<'a>(buf: &mut &'a mut [u8], cnt: usize) -> &'a mut [u8] {
13+
// use mem::take to circumvent lifetime issues
14+
let (first, rem) = mem::take(buf).split_at_mut(cnt);
15+
*buf = rem;
16+
first
17+
}
18+
19+
/// A disk device with a cursor.
20+
pub struct SeekableDisk {
21+
dev: AxBlockDevice,
22+
23+
block_id: u64,
24+
offset: usize,
25+
block_size_log2: u8,
26+
27+
read_buffer: Box<[u8]>,
28+
write_buffer: Box<[u8]>,
29+
/// Whether we have unsaved changes in the write buffer.
30+
///
31+
/// It's guaranteed that when `offset == 0`, write_buffer_dirty is false.
32+
write_buffer_dirty: bool,
33+
}
34+
35+
impl SeekableDisk {
36+
/// Create a new disk.
37+
pub fn new(dev: AxBlockDevice) -> Self {
38+
assert!(dev.block_size().is_power_of_two());
39+
let block_size_log2 = dev.block_size().trailing_zeros() as u8;
40+
let read_buffer = vec![0u8; dev.block_size()].into_boxed_slice();
41+
let write_buffer = vec![0u8; dev.block_size()].into_boxed_slice();
42+
Self {
43+
dev,
44+
block_id: 0,
45+
offset: 0,
46+
block_size_log2,
47+
read_buffer,
48+
write_buffer,
49+
write_buffer_dirty: false,
50+
}
51+
}
52+
53+
/// Get the size of the disk.
54+
pub fn size(&self) -> u64 {
55+
self.dev.num_blocks() << self.block_size_log2
56+
}
57+
58+
/// Get the block size.
59+
pub fn block_size(&self) -> usize {
60+
1 << self.block_size_log2
61+
}
62+
63+
/// Get the position of the cursor.
64+
pub fn position(&self) -> u64 {
65+
(self.block_id << self.block_size_log2) + self.offset as u64
66+
}
67+
68+
/// Set the position of the cursor.
69+
pub fn set_position(&mut self, pos: u64) -> DevResult<()> {
70+
self.flush()?;
71+
self.block_id = pos >> self.block_size_log2;
72+
self.offset = pos as usize & (self.block_size() - 1);
73+
Ok(())
74+
}
75+
76+
/// Write all pending changes to the disk.
77+
pub fn flush(&mut self) -> DevResult<()> {
78+
if self.write_buffer_dirty {
79+
self.dev.write_block(self.block_id, &self.write_buffer)?;
80+
self.write_buffer_dirty = false;
81+
}
82+
Ok(())
83+
}
84+
85+
fn read_partial(&mut self, buf: &mut &mut [u8]) -> DevResult<usize> {
86+
self.flush()?;
87+
self.dev.read_block(self.block_id, &mut self.read_buffer)?;
88+
89+
let data = &self.read_buffer[self.offset..];
90+
let length = buf.len().min(data.len());
91+
take_mut(buf, length).copy_from_slice(&data[..length]);
92+
93+
self.offset += length;
94+
if self.offset == self.block_size() {
95+
self.block_id += 1;
96+
self.offset = 0;
97+
}
98+
99+
Ok(length)
100+
}
101+
102+
/// Read from the disk, returns the number of bytes read.
103+
pub fn read(&mut self, mut buf: &mut [u8]) -> DevResult<usize> {
104+
let mut read = 0;
105+
if self.offset != 0 {
106+
read += self.read_partial(&mut buf)?;
107+
}
108+
if buf.len() >= self.block_size() {
109+
let blocks = buf.len() >> self.block_size_log2;
110+
let length = blocks << self.block_size_log2;
111+
self.dev
112+
.read_block(self.block_id, take_mut(&mut buf, length))?;
113+
read += length;
114+
115+
self.block_id += blocks as u64;
116+
}
117+
if !buf.is_empty() {
118+
read += self.read_partial(&mut buf)?;
119+
}
120+
121+
Ok(read)
122+
}
123+
124+
fn write_partial(&mut self, buf: &mut &[u8]) -> DevResult<usize> {
125+
if !self.write_buffer_dirty {
126+
self.dev.read_block(self.block_id, &mut self.write_buffer)?;
127+
self.write_buffer_dirty = true;
128+
}
129+
130+
let data = &mut self.write_buffer[self.offset..];
131+
let length = buf.len().min(data.len());
132+
data[..length].copy_from_slice(take(buf, length));
133+
134+
self.offset += length;
135+
if self.offset == self.block_size() {
136+
self.flush()?;
137+
self.block_id += 1;
138+
self.offset = 0;
139+
}
140+
141+
Ok(length)
142+
}
143+
144+
/// Write to the disk, returns the number of bytes written.
145+
pub fn write(&mut self, mut buf: &[u8]) -> DevResult<usize> {
146+
let mut written = 0;
147+
if self.offset != 0 {
148+
written += self.write_partial(&mut buf)?;
149+
}
150+
if buf.len() >= self.block_size() {
151+
let blocks = buf.len() >> self.block_size_log2;
152+
let length = blocks << self.block_size_log2;
153+
self.dev
154+
.write_block(self.block_id, take(&mut buf, length))?;
155+
written += length;
156+
157+
self.block_id += blocks as u64;
158+
}
159+
if !buf.is_empty() {
160+
written += self.write_partial(&mut buf)?;
161+
}
162+
163+
Ok(written)
164+
}
165+
}

0 commit comments

Comments
 (0)