Skip to content

Commit 406b2b9

Browse files
committed
Init the ch8
1 parent 0815ae9 commit 406b2b9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1946
-945
lines changed

.github/workflows/build.yml

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,23 @@ env:
77
rust_toolchain: nightly
88

99
jobs:
10+
build-doc:
11+
if: github.repository == 'LearningOS/rCore-Tutorial-Code'
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
- name: Build doc
16+
run: |
17+
git clone https://github.com/LearningOS/rCore-Tutorial-Test.git user
18+
cd os
19+
make
20+
cargo doc --no-deps --verbose
21+
- name: Push to gh-pages
22+
uses: peaceiris/actions-gh-pages@v3
23+
with:
24+
github_token: ${{ secrets.GITHUB_TOKEN }}
25+
publish_dir: ./os/target/riscv64gc-unknown-none-elf/doc
26+
destination_dir: ${{ github.ref_name }}
1027
basic-test:
1128
runs-on: ubuntu-latest
1229
outputs:
@@ -25,11 +42,11 @@ jobs:
2542
ID=`git rev-parse --abbrev-ref HEAD | grep -oP 'ch\K[0-9]'`
2643
cd ci-user && make test CHAPTER=$ID passwd=${{ secrets.BASE_TEST_TOKEN }} > ../output.txt
2744
cat ../output.txt
28-
- name: end
45+
- name: end
2946
id: end
3047
run: |
31-
cat output.txt | grep "Test passed" | grep -oP "\d{1,}/\d{1,}" | xargs -i echo "points={}"
32-
cat output.txt | grep "Test passed" | grep -oP "\d{1,}/\d{1,}" | xargs -i echo "points={}" >> $GITHUB_OUTPUT
48+
cat output.txt | grep -a "Test passed" | grep -oP "\d{1,}/\d{1,}" | xargs -i echo "points={}"
49+
cat output.txt | grep -a "Test passed" | grep -oP "\d{1,}/\d{1,}" | xargs -i echo "points={}" >> $GITHUB_OUTPUT
3350
deploy:
3451
if: github.repository != 'LearningOS/rCore-Tutorial-Code'
3552
name: Deploy to pages

.gitignore

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
.*/*
22
!.github/*
33
!.vscode/settings.json
4-
.idea
5-
Cargo.lock
6-
target
4+
.idea/*
5+
os/target/*
6+
os/.idea/*
77
os/src/link_app.S
88
os/last-*
99
os/Cargo.lock
1010
os/.gdb_history
11+
user/target/*
12+
user/.idea/*
13+
user/Cargo.lock
1114
easy-fs/Cargo.lock
1215
easy-fs/target/*
1316
easy-fs-fuse/Cargo.lock
1417
easy-fs-fuse/target/*
1518
tools/
1619
pushall.sh
20+
.vscode/*.log
1721
*.bak
1822
ci-user/
1923
user/

easy-fs/src/bitmap.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,34 @@
1+
//! Disk layout & data structure layer: about bitmaps
2+
//!
3+
//! There are two different types of [`Bitmap`] in the easy-fs layout that manage inodes and blocks, respectively. Each bitmap consists of several blocks, each of which is 512 bytes, or 4096 bits. Each bit represents the allocation status of an inode/data block, 0 means unallocated, and 1 means allocated. What the bitmap does is allocate and de-allocate inodes/data blocks via bit-based allocation (looking for a bit of 0 and setting it to 1) and de-allocation (clearing the bit).
14
use super::{get_block_cache, BlockDevice, BLOCK_SZ};
25
use alloc::sync::Arc;
3-
6+
/// A bitmap block
47
type BitmapBlock = [u64; 64];
5-
8+
/// Number of bits in a block
69
const BLOCK_BITS: usize = BLOCK_SZ * 8;
7-
10+
/// bitmap struct for disk block management
811
pub struct Bitmap {
912
start_block_id: usize,
1013
blocks: usize,
1114
}
1215

13-
/// Return (block_pos, bits64_pos, inner_pos)
16+
/// Decompose bits into (block_pos, bits64_pos, inner_pos)
1417
fn decomposition(mut bit: usize) -> (usize, usize, usize) {
1518
let block_pos = bit / BLOCK_BITS;
1619
bit %= BLOCK_BITS;
1720
(block_pos, bit / 64, bit % 64)
1821
}
1922

2023
impl Bitmap {
24+
/// Create new bitmap blocks
2125
pub fn new(start_block_id: usize, blocks: usize) -> Self {
2226
Self {
2327
start_block_id,
2428
blocks,
2529
}
2630
}
27-
31+
/// Allocate a block according to the bitmap info
2832
pub fn alloc(&self, block_device: &Arc<dyn BlockDevice>) -> Option<usize> {
2933
for block_id in 0..self.blocks {
3034
let pos = get_block_cache(
@@ -52,7 +56,7 @@ impl Bitmap {
5256
}
5357
None
5458
}
55-
59+
/// Deallocate a block according to the bitmap info
5660
pub fn dealloc(&self, block_device: &Arc<dyn BlockDevice>, bit: usize) {
5761
let (block_pos, bits64_pos, inner_pos) = decomposition(bit);
5862
get_block_cache(block_pos + self.start_block_id, Arc::clone(block_device))
@@ -62,7 +66,7 @@ impl Bitmap {
6266
bitmap_block[bits64_pos] -= 1u64 << inner_pos;
6367
});
6468
}
65-
69+
/// bitmap max size in bits(the max number of blocks according to the bitmap size)
6670
pub fn maximum(&self) -> usize {
6771
self.blocks * BLOCK_BITS
6872
}

easy-fs/src/block_cache.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
//! Block Cache Layer
2+
//! Implements about the disk block cache functionality
13
use super::{BlockDevice, BLOCK_SZ};
24
use alloc::collections::VecDeque;
35
use alloc::sync::Arc;
46
use alloc::vec;
57
use alloc::vec::Vec;
68
use lazy_static::*;
79
use spin::Mutex;
8-
10+
/// BlockCache is a cache for a block in disk.
911
pub struct BlockCache {
1012
cache: Vec<u8>,
1113
block_id: usize,
@@ -26,11 +28,11 @@ impl BlockCache {
2628
modified: false,
2729
}
2830
}
29-
31+
/// Get the slice in the block cache according to the offset.
3032
fn addr_of_offset(&self, offset: usize) -> usize {
3133
&self.cache[offset] as *const _ as usize
3234
}
33-
35+
/// Get a immutable reference to the data in the block cache according to the offset.
3436
pub fn get_ref<T>(&self, offset: usize) -> &T
3537
where
3638
T: Sized,
@@ -40,7 +42,7 @@ impl BlockCache {
4042
let addr = self.addr_of_offset(offset);
4143
unsafe { &*(addr as *const T) }
4244
}
43-
45+
/// Get a mutable reference to the data in the block cache according to the offset.
4446
pub fn get_mut<T>(&mut self, offset: usize) -> &mut T
4547
where
4648
T: Sized,
@@ -51,15 +53,15 @@ impl BlockCache {
5153
let addr = self.addr_of_offset(offset);
5254
unsafe { &mut *(addr as *mut T) }
5355
}
54-
56+
/// Read the data from the block cache according to the offset.
5557
pub fn read<T, V>(&self, offset: usize, f: impl FnOnce(&T) -> V) -> V {
5658
f(self.get_ref(offset))
5759
}
58-
60+
/// Write the data into the block cache according to the offset.
5961
pub fn modify<T, V>(&mut self, offset: usize, f: impl FnOnce(&mut T) -> V) -> V {
6062
f(self.get_mut(offset))
6163
}
62-
64+
/// Sync(write) the block cache to disk.
6365
pub fn sync(&mut self) {
6466
if self.modified {
6567
self.modified = false;
@@ -76,17 +78,20 @@ impl Drop for BlockCache {
7678

7779
const BLOCK_CACHE_SIZE: usize = 16;
7880

81+
/// BlockCacheManager is a manager for BlockCache.
7982
pub struct BlockCacheManager {
83+
/// (block_id, block_cache)
8084
queue: VecDeque<(usize, Arc<Mutex<BlockCache>>)>,
8185
}
8286

8387
impl BlockCacheManager {
88+
/// Create a new BlockCacheManager with an empty queue (block_id, block_cache)
8489
pub fn new() -> Self {
8590
Self {
8691
queue: VecDeque::new(),
8792
}
8893
}
89-
94+
/// Get a block cache from the queue. according to the block_id.
9095
pub fn get_block_cache(
9196
&mut self,
9297
block_id: usize,
@@ -121,10 +126,11 @@ impl BlockCacheManager {
121126
}
122127

123128
lazy_static! {
129+
/// BLOCK_CACHE_MANAGER: Glocal instance of BlockCacheManager.
124130
pub static ref BLOCK_CACHE_MANAGER: Mutex<BlockCacheManager> =
125131
Mutex::new(BlockCacheManager::new());
126132
}
127-
133+
/// Get a block cache from the queue. according to the block_id.
128134
pub fn get_block_cache(
129135
block_id: usize,
130136
block_device: Arc<dyn BlockDevice>,
@@ -133,7 +139,7 @@ pub fn get_block_cache(
133139
.lock()
134140
.get_block_cache(block_id, block_device)
135141
}
136-
142+
/// Sync(write) all the block cache to disk.
137143
pub fn block_cache_sync_all() {
138144
let manager = BLOCK_CACHE_MANAGER.lock();
139145
for (_, cache) in manager.queue.iter() {

easy-fs/src/block_dev.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1+
//! Block device interface.
2+
//!
3+
//! Define the block read-write interface [BlockDevice] that the device driver needs to implement
4+
15
use core::any::Any;
26

37
pub trait BlockDevice: Send + Sync + Any {
8+
/// Read a block from the block device.
49
fn read_block(&self, block_id: usize, buf: &mut [u8]);
10+
/// Write a block to the block device.
511
fn write_block(&self, block_id: usize, buf: &[u8]);
612
}

easy-fs/src/efs.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
//! Disk block manager layer
2+
//!
3+
//! Disk block manager knows the disk location of each layout area, and the allocation and reclamation of disk blocks need to be completed through it.
4+
//!
5+
//! NOTICE: from this level, all data structures are in memory.
16
use super::{
27
block_cache_sync_all, get_block_cache, Bitmap, BlockDevice, DiskInode, DiskInodeType, Inode,
38
SuperBlock,
@@ -6,17 +11,24 @@ use crate::BLOCK_SZ;
611
use alloc::sync::Arc;
712
use spin::Mutex;
813

14+
/// EasyFileSystem struct
915
pub struct EasyFileSystem {
16+
/// The block device
1017
pub block_device: Arc<dyn BlockDevice>,
18+
/// The bitmap of inode blocks
1119
pub inode_bitmap: Bitmap,
20+
/// The bitmap of data blocks
1221
pub data_bitmap: Bitmap,
22+
/// The start block id of inode area
1323
inode_area_start_block: u32,
24+
/// The start block id of data area
1425
data_area_start_block: u32,
1526
}
1627

1728
type DataBlock = [u8; BLOCK_SZ];
1829

1930
impl EasyFileSystem {
31+
/// Create a new EasyFileSystem
2032
pub fn create(
2133
block_device: Arc<dyn BlockDevice>,
2234
total_blocks: u32,
@@ -35,6 +47,7 @@ impl EasyFileSystem {
3547
(1 + inode_bitmap_blocks + inode_area_blocks) as usize,
3648
data_bitmap_blocks as usize,
3749
);
50+
//
3851
let mut efs = Self {
3952
block_device: Arc::clone(&block_device),
4053
inode_bitmap,
@@ -77,7 +90,7 @@ impl EasyFileSystem {
7790
block_cache_sync_all();
7891
Arc::new(Mutex::new(efs))
7992
}
80-
93+
/// Open an existing EasyFileSystem
8194
pub fn open(block_device: Arc<dyn BlockDevice>) -> Arc<Mutex<Self>> {
8295
// read SuperBlock
8396
get_block_cache(0, Arc::clone(&block_device))
@@ -99,15 +112,15 @@ impl EasyFileSystem {
99112
Arc::new(Mutex::new(efs))
100113
})
101114
}
102-
115+
/// Get the root inode
103116
pub fn root_inode(efs: &Arc<Mutex<Self>>) -> Inode {
104117
let block_device = Arc::clone(&efs.lock().block_device);
105118
// acquire efs lock temporarily
106119
let (block_id, block_offset) = efs.lock().get_disk_inode_pos(0);
107120
// release efs lock
108121
Inode::new(block_id, block_offset, Arc::clone(efs), block_device)
109122
}
110-
123+
/// Get inode block position (the block id and offset in this block) according to the inode id
111124
pub fn get_disk_inode_pos(&self, inode_id: u32) -> (u32, usize) {
112125
let inode_size = core::mem::size_of::<DiskInode>();
113126
let inodes_per_block = (BLOCK_SZ / inode_size) as u32;
@@ -117,20 +130,20 @@ impl EasyFileSystem {
117130
(inode_id % inodes_per_block) as usize * inode_size,
118131
)
119132
}
120-
133+
/// Get data block position according to the data block id
121134
pub fn get_data_block_id(&self, data_block_id: u32) -> u32 {
122135
self.data_area_start_block + data_block_id
123136
}
124-
137+
/// allocate a new inode, return its inode_id
125138
pub fn alloc_inode(&mut self) -> u32 {
126139
self.inode_bitmap.alloc(&self.block_device).unwrap() as u32
127140
}
128141

129-
/// Return a block ID not ID in the data area.
142+
/// allocate a new data block, return its block position (block_id)
130143
pub fn alloc_data(&mut self) -> u32 {
131144
self.data_bitmap.alloc(&self.block_device).unwrap() as u32 + self.data_area_start_block
132145
}
133-
146+
/// deallocate a data block according to its block id
134147
pub fn dealloc_data(&mut self, block_id: u32) {
135148
get_block_cache(block_id as usize, Arc::clone(&self.block_device))
136149
.lock()

0 commit comments

Comments
 (0)