From e96db7db0fa4521bdd13b648caa8f03eaea1d799 Mon Sep 17 00:00:00 2001 From: EunsuKim03 Date: Thu, 20 Jun 2024 15:25:01 +0900 Subject: [PATCH 1/4] Dependency version updated --- Cargo.lock | 69 ++++++++++++++++++++++-------------------------------- 1 file changed, 28 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c463924..3f8b48f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "ahash" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e" +checksum = "0453232ace82dee0dd0b4c87a59bd90f7b53b314f3e0f61fe2ee7c8a16482289" [[package]] name = "bitflags" @@ -22,12 +22,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "crossbeam-utils" -version = "0.8.5" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" -dependencies = [ - "cfg-if", -] +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "ext4" @@ -53,9 +50,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -73,24 +70,24 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.112" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "num_enum" -version = "0.5.7" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.5.7" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" dependencies = [ "proc-macro2", "quote", @@ -103,38 +100,37 @@ version = "0.1.0" [[package]] name = "ppv-lite86" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] [[package]] name = "rand" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", "rand_core", - "rand_hc", ] [[package]] @@ -149,27 +145,18 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] -[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core", -] - [[package]] name = "syn" -version = "1.0.103" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", @@ -182,12 +169,12 @@ version = "0.1.0" [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" From f2a60eb1f287109a4bc81dba71c47bc216d2cb5d Mon Sep 17 00:00:00 2001 From: EunsuKim03 Date: Tue, 2 Jul 2024 13:46:39 +0900 Subject: [PATCH 2/4] Update Upstream --- Cargo.lock | 5 +++++ src/directory/mod.rs | 2 +- src/file.rs | 2 +- src/format.rs | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4a76b7b..0804957 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,6 +44,7 @@ name = "fs_core" version = "0.1.0" dependencies = [ "bitflags", + "path", ] [[package]] @@ -92,6 +93,10 @@ dependencies = [ "syn", ] +[[package]] +name = "path" +version = "0.1.0" + [[package]] name = "ppv-lite86" version = "0.2.17" diff --git a/src/directory/mod.rs b/src/directory/mod.rs index e30fc31..3819028 100644 --- a/src/directory/mod.rs +++ b/src/directory/mod.rs @@ -244,7 +244,7 @@ impl Directory { #[cfg(test)] mod tests { - use crate::tests::run_test; + use crate::std::tests::run_test; use crate::FileType; #[test] diff --git a/src/file.rs b/src/file.rs index 48ddf99..f5e2209 100644 --- a/src/file.rs +++ b/src/file.rs @@ -204,7 +204,7 @@ impl File { #[cfg(test)] mod tests { - use crate::tests::run_test; + use crate::std::tests::run_test; use crate::FileType; #[test] diff --git a/src/format.rs b/src/format.rs index 93949ef..4be2cc5 100644 --- a/src/format.rs +++ b/src/format.rs @@ -325,7 +325,7 @@ pub fn format( #[cfg(test)] mod tests { - use crate::tests::{make_disk, test_oracle}; + use crate::std::tests::{make_disk, test_oracle}; const M: u64 = 1024 * 1024; const G: u64 = 1024 * 1024 * 1024; From 63ca7af4f89fb868d3ff0804bdb4e3ce1a447064 Mon Sep 17 00:00:00 2001 From: EunsuKim03 Date: Wed, 21 Aug 2024 15:02:22 +0900 Subject: [PATCH 3/4] Extent logging & Minor bug fixed --- src/block/allocator.rs | 2 +- src/block/mod.rs | 10 ++- src/block_group/mod.rs | 6 +- src/cache.rs | 2 +- src/directory/htree/node.rs | 6 +- src/file.rs | 5 +- src/filesystem.rs | 2 +- src/format.rs | 6 +- src/inode/allocator.rs | 4 +- src/inode/extent/cursor.rs | 6 +- src/inode/extent/mod.rs | 113 +++++++++++++++++++++-- src/inode/extent/path.rs | 172 +++++++++++++++++++++++++++++++++--- src/inode/mod.rs | 6 +- src/lib.rs | 5 +- src/std.rs | 13 +-- src/transaction/event.rs | 123 ++++++++++++++++++++++++++ src/transaction/mod.rs | 77 +++++++++++++++- src/types.rs | 2 +- 18 files changed, 498 insertions(+), 62 deletions(-) diff --git a/src/block/allocator.rs b/src/block/allocator.rs index 8f87fce..7c31fdc 100644 --- a/src/block/allocator.rs +++ b/src/block/allocator.rs @@ -206,7 +206,7 @@ where let count = core::cmp::min(bg.blocks_count as usize - ofs, size); trans.block_deallocation_on_bg(ino, bgid, bg.block_bitmap_lba, ofs, count); size -= count; - lba = lba + (count as u64); + lba += count as u64; } Ok(()) } diff --git a/src/block/mod.rs b/src/block/mod.rs index 0d9f750..2835938 100644 --- a/src/block/mod.rs +++ b/src/block/mod.rs @@ -21,8 +21,8 @@ use crate::superblock::SuperBlock; use crate::transaction::{Collector, Transaction}; use crate::types::Zero; use crate::{ - BlockGroupId, Config, FsError, InodeNumber, LogicalBlockNumber, RwLock, RwLockReadGuard, - RwLockWriteGuard, + std::RwLock, std::RwLockReadGuard, std::RwLockWriteGuard, BlockGroupId, Config, FsError, + InodeNumber, LogicalBlockNumber, }; use alloc::sync::Arc; @@ -224,13 +224,15 @@ impl Manager { pub(crate) fn get_mut_noload<'l, 'j>( &'l self, lba: LogicalBlockNumber, - collector: &'j Collector, + collector: Option<&'j Collector>, ) -> Result, FsError> where 'l: 'j, { let mut created = false; - collector.track(lba); + if let Some(collector) = collector { + collector.track(lba); + } Ok(self .blocks .get_or_insert_arc::<_, ()>(lba, |_| { diff --git a/src/block_group/mod.rs b/src/block_group/mod.rs index 202821c..3544841 100644 --- a/src/block_group/mod.rs +++ b/src/block_group/mod.rs @@ -181,7 +181,7 @@ impl BlockGroup { if flags.contains(BlockGroupFlag::BLOCK_UNINIT) { let bref = fs .blocks - .get_mut_noload(self.block_bitmap_lba, &tx.collector)?; + .get_mut_noload(self.block_bitmap_lba, Some(&tx.collector))?; let mut guard = bref.write(); let mut block_bitmap = ByteRw::new(guard.as_mut()); let mut base = (fs.sb.first_data_block as u64 + desc_blocks) as usize + 1; @@ -204,7 +204,7 @@ impl BlockGroup { if flags.contains(BlockGroupFlag::INODE_UNINIT) { let bref = fs .blocks - .get_mut_noload(self.inode_bitmap_lba, &tx.collector)?; + .get_mut_noload(self.inode_bitmap_lba, Some(&tx.collector))?; let mut guard = bref.write(); ByteRw::new(guard.as_mut()).set_bitmap(fs.sb.inodes_per_group as usize..BLK_SIZE * 8); @@ -214,7 +214,7 @@ impl BlockGroup { ..self.inode_table_first_block.0 + inode_blocks) .map(LogicalBlockNumber) { - let _ = fs.blocks.get_mut_noload(lba, &tx.collector)?; + let _ = fs.blocks.get_mut_noload(lba, Some(&tx.collector))?; } nflags.insert(BlockGroupFlag::ITABLE_ZEROED); } diff --git a/src/cache.rs b/src/cache.rs index bf3ea8a..3369389 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{RwDreamer, RwLock}; +use crate::{std::RwLock, RwDreamer}; use alloc::sync::{Arc, Weak}; use hashbrown::{hash_map::Entry, HashMap}; diff --git a/src/directory/htree/node.rs b/src/directory/htree/node.rs index 511e531..b0e88e5 100644 --- a/src/directory/htree/node.rs +++ b/src/directory/htree/node.rs @@ -440,7 +440,7 @@ impl< // Allocate new block. let (dx_fba, new_blk) = dispatch_cursor_last_mut!(inode, fs, tx, |mut c| { let lba = c.or_allocated(false).unwrap(); - (c.fba(), fs.blocks.get_mut_noload(lba, &tx.collector)?) + (c.fba(), fs.blocks.get_mut_noload(lba, Some(&tx.collector))?) }); let size = inode.get_size(); @@ -637,7 +637,9 @@ impl< DirectoryBlock::new(&mut **blk.write(), fs).clear(); } inode.set_size(BLK_SIZE as u64 * 2, tx); - let raw = fs.blocks.get_mut_noload(root_block_addr, &tx.collector)?; + let raw = fs + .blocks + .get_mut_noload(root_block_addr, Some(&tx.collector))?; { let mut guard = raw.write(); diff --git a/src/file.rs b/src/file.rs index f5e2209..8db7c0f 100644 --- a/src/file.rs +++ b/src/file.rs @@ -231,8 +231,9 @@ mod tests { #[test] fn write_big() { - // const SIZE: usize = 4 * 1024 *1024 * 1024; + // const SIZE: usize = 4 * 1024 * 1024 * 1024; const SIZE: usize = 256 * 1024 * 1024; + // const SIZE: usize = 16 * 1024 * 1024 * 1024; run_test( |fs| { let buf = Box::new([0; 4096]); @@ -251,7 +252,7 @@ mod tests { println!("wb"); tx.done(&fs).unwrap(); }, - (SIZE as u64) / 1024 / 1024 + 100, + (SIZE as u64) / 1024 / 1024 + 1000, ); } } diff --git a/src/filesystem.rs b/src/filesystem.rs index 044c728..eb35788 100644 --- a/src/filesystem.rs +++ b/src/filesystem.rs @@ -19,7 +19,7 @@ use crate::inode; use crate::superblock::SuperBlock; use crate::transaction::{Events, Transaction}; use crate::types::BlockGroupId; -use crate::{Config, FileType, FsError, FsObject, InodeNumber, RwLock, RwLockReadGuard}; +use crate::{std::RwLock, std::RwLockReadGuard, Config, FileType, FsError, FsObject, InodeNumber}; use alloc::collections::LinkedList; use alloc::sync::Arc; use alloc::vec::Vec; diff --git a/src/format.rs b/src/format.rs index 4be2cc5..dbb44b8 100644 --- a/src/format.rs +++ b/src/format.rs @@ -317,7 +317,11 @@ pub fn format( ); let mut sb = make_sb::(aux); fill_bg(&dev, &mut sb)?; - dev.write_bytes(1024, &sb.manipulator.lock().rw.inner().0)?; + const BUFSIZE: usize = 1024; + let mut buf = C::Buffer::::zeroed(); + buf.as_mut()[0..BUFSIZE] + .copy_from_slice(sb.manipulator.lock().rw.inner().0[0..BUFSIZE].as_ref()); + dev.write_bytes(1024, &buf)?; let fs = FileSystem::::new(dev, sb); make_root(&fs)?; Ok(fs) diff --git a/src/inode/allocator.rs b/src/inode/allocator.rs index 42c5433..b005100 100644 --- a/src/inode/allocator.rs +++ b/src/inode/allocator.rs @@ -15,7 +15,7 @@ use crate::filesystem::FileSystem; use crate::transaction::Transaction; use crate::types::BlockGroupId; -use crate::{Config, FileType, FsError, InodeNumber, RwLock, RwLockReadGuard}; +use crate::{std::RwLock, std::RwLockReadGuard, Config, FileType, FsError, InodeNumber}; use alloc::boxed::Box; use alloc::vec::Vec; use core::sync::atomic::{AtomicU32, AtomicU8, Ordering}; @@ -85,7 +85,7 @@ impl Allocator { loop { // CAS to get bits. let val = bits.load(Ordering::Relaxed); - let x = val ^ core::u8::MAX; + let x = val ^ u8::MAX; if x != 0 { // toggle all bits. let (mask, ret) = { diff --git a/src/inode/extent/cursor.rs b/src/inode/extent/cursor.rs index c14005c..9cdf1ce 100644 --- a/src/inode/extent/cursor.rs +++ b/src/inode/extent/cursor.rs @@ -136,7 +136,9 @@ where (true, true) => return Ok((start + ((self.fba.0 - block.0) as u64), 1)), (_, false) => todo!("Uninitialized extent"), (false, true) if block > self.fba => start + (self.fba.0 as u64 - start.0), - (false, true) => start - (self.fba.0 as u64 - block.0 as u64), + (false, true) => { + LogicalBlockNumber(start.0.saturating_sub(self.fba.0 as u64 - block.0 as u64)) + } // if start==0, overflow } } else if self.path.leafs.is_empty() { // tree is empty. @@ -166,7 +168,7 @@ where for i in 0..len { self.fs .blocks - .get_mut_noload(n + (i as u64), &self.tx.collector)?; + .get_mut_noload(n + (i as u64), Some(&self.tx.collector))?; } } diff --git a/src/inode/extent/mod.rs b/src/inode/extent/mod.rs index 06f2dba..73ec479 100644 --- a/src/inode/extent/mod.rs +++ b/src/inode/extent/mod.rs @@ -190,7 +190,7 @@ pub struct ExtentTree { pub(super) depth: u16, pub(super) b: [u8; 48], #[cfg(feature = "extent_cache")] - pub(super) cache: crate::RwLock, C::D>, + pub(super) cache: crate::std::RwLock, C::D>, #[cfg(not(feature = "extent_cache"))] pub(super) _l: core::marker::PhantomData, } @@ -331,7 +331,7 @@ impl Default for ExtentTree { depth: 0, b: [0; 48], #[cfg(feature = "extent_cache")] - cache: crate::RwLock::new(None), + cache: crate::std::RwLock::new(None), #[cfg(not(feature = "extent_cache"))] _l: core::marker::PhantomData, } @@ -544,7 +544,7 @@ impl<'a, 'b, C: Config, const BLK_SIZE: usize> ExtentHeaderMut for Node<'a, 'b, impl ExtentTree { #[inline] - fn insert_at(&mut self, ext: Entry, at: usize) -> Result<(), Entry> { + fn insert_at(&mut self, ext: Entry, at: usize, _tx: &Transaction) -> Result<(), Entry> { let (max_entries_cnt, entries_cnt, depth) = ( self.get_max_entries_cnt(), self.get_entries_cnt(), @@ -556,7 +556,7 @@ impl ExtentTree { .map(|_| self.set_entries_cnt(self.get_entries_cnt() + 1)) } #[inline] - fn replace_at(&mut self, ext: Entry, at: usize) -> Result<(), Entry> { + fn replace_at(&mut self, ext: Entry, at: usize, _tx: &Transaction) -> Result<(), Entry> { let (entries_cnt, depth) = (self.get_entries_cnt(), self.get_depth()); replace_at(entries_cnt, depth, ext, at, || ByteRw::new(&mut self.b)) @@ -565,7 +565,7 @@ impl ExtentTree { impl<'a, 'b, C: Config, const BLK_SIZE: usize> Node<'a, 'b, C, BLK_SIZE, true> { #[inline] - fn insert_at(&mut self, ext: Entry, at: usize) -> Result<(), Entry> { + fn insert_at(&mut self, ext: Entry, at: usize, tx: &Transaction) -> Result<(), Entry> { let (max_entries_cnt, entries_cnt, depth) = ( self.get_max_entries_cnt(), self.get_entries_cnt(), @@ -574,19 +574,114 @@ impl<'a, 'b, C: Config, const BLK_SIZE: usize> Node<'a, 'b, C, BLK_SIZE, true> { { let mut guard = self.b.write(); - insert_at(max_entries_cnt, entries_cnt, depth, ext, at, || { + insert_at(max_entries_cnt, entries_cnt, depth, ext.clone(), at, || { ByteRw::new(&mut guard[12..]) }) } - .map(|_| self.set_entries_cnt(self.get_entries_cnt() + 1)) + .map(|_| { + tx.extent_update_node_insert_at(self.b.lba(), ext, at); + self.set_entries_cnt(self.get_entries_cnt() + 1) + }) } #[inline] - fn replace_at(&mut self, ext: Entry, at: usize) -> Result<(), Entry> { + fn replace_at(&mut self, ext: Entry, at: usize, tx: &Transaction) -> Result<(), Entry> { let (entries_cnt, depth) = (self.get_entries_cnt(), self.get_depth()); let mut guard = self.b.write(); - replace_at(entries_cnt, depth, ext, at, || { + replace_at(entries_cnt, depth, ext.clone(), at, || { ByteRw::new(&mut guard[12..]) }) + .map(|_| tx.extent_update_node_replace_at(self.b.lba(), ext, at)) + } +} + +pub struct RawNode { + rw: ByteRw<[u8; BLK_SIZE]>, +} + +impl RawNode { + pub fn from_raw(rw: [u8; BLK_SIZE]) -> Self { + Self { + rw: ByteRw::new(rw), + } + } + + pub fn init(&mut self, depth: u16) { + self.rw.write_u16(0, 0xF30A); + self.rw.write_u16(2, 0); + self.rw.write_u16(4, ((BLK_SIZE - 16) / 12) as u16); + self.rw.write_u16(6, depth); + } + + pub fn get_entries_cnt(&self) -> u16 { + self.rw.read_u16(2) + } + + pub fn get_max_entries_cnt(&self) -> u16 { + self.rw.read_u16(4) + } + + pub fn get_depth(&self) -> u16 { + self.rw.read_u16(6) + } + + pub fn get(&self, index: usize) -> Option { + if index < self.get_entries_cnt() as usize { + if self.get_depth() == 0 { + let (len, is_init) = { + let v = self.rw.read_u16(12 + 12 * index + 4); + let is_init = v <= 0x8000; + (if is_init { v } else { v - 0x8000 }, is_init) + }; + Some(Entry::Leaf(Leaf { + block: FileBlockNumber(self.rw.read_u32(12 + 12 * index)), + start: LogicalBlockNumber(merge_u32( + self.rw.read_u16(12 + 12 * index + 6) as u32, + self.rw.read_u32(12 + 12 * index + 8), + )), + len, + is_init, + })) + } else { + Some(Entry::Internal(Internal { + block: FileBlockNumber(self.rw.read_u32(12 + 12 * index)), + next_node: LogicalBlockNumber(merge_u32( + self.rw.read_u16(12 + 12 * index + 8) as u32, + self.rw.read_u32(12 + 12 * index + 4), + )), + })) + } + } else { + None + } + } + + pub fn set_entries_cnt(&mut self, v: u16) { + self.rw.write_u16(2, v); + } + + pub fn insert_at(&mut self, ext: Entry, at: usize) -> Result<(), Entry> { + let (max_entries_cnt, entries_cnt, depth) = ( + self.get_max_entries_cnt(), + self.get_entries_cnt(), + self.get_depth(), + ); + { + insert_at(max_entries_cnt, entries_cnt, depth, ext, at, || { + ByteRw::new(&mut self.rw.b[12..]) + }) + } + .map(|_| self.set_entries_cnt(self.get_entries_cnt() + 1)) + } + + pub fn replace_at(&mut self, ext: Entry, at: usize) -> Result<(), Entry> { + let (entries_cnt, depth) = (self.get_entries_cnt(), self.get_depth()); + replace_at(entries_cnt, depth, ext, at, || { + ByteRw::new(&mut self.rw.b[12..]) + }) + } + + pub fn to_raw(self) -> [u8; BLK_SIZE] { + self.rw.b } } diff --git a/src/inode/extent/path.rs b/src/inode/extent/path.rs index c566cb5..dfcbe7f 100644 --- a/src/inode/extent/path.rs +++ b/src/inode/extent/path.rs @@ -15,6 +15,7 @@ use super::{Entry, ExtentHeader, ExtentHeaderMut, ExtentTree, Internal, Leaf, Node}; use crate::block::BlockRef; use crate::filesystem::FileSystem; +use crate::inode::RawInodeAddressingMode; use crate::transaction::Transaction; use crate::utils::ByteRw; use crate::{Config, FileBlockNumber, FsError, InodeNumber, LogicalBlockNumber}; @@ -353,7 +354,11 @@ where } } - fn insert_leaf(&mut self, new: Leaf) -> Result, FsError> { + // ### Extent Tree Logging + // ### Root modificiation -> process at path level + // ### Node modification -> if only Node::set_entries_cnt is called, process at path level, otherwise process at node level + + fn insert_leaf(&mut self, new: Leaf, tx: &Transaction) -> Result, FsError> { let leaf = self.get_leaf(); if leaf.as_ref().map(|l| l.block == new.block).unwrap_or(false) { @@ -381,8 +386,22 @@ where is_init, }), index.unwrap(), + tx, ) .unwrap_or_else(|_| unreachable!()); + + if let PathEntry::Root((updated, _)) = self.last() { + tx.inode_update_root( + self.ino, + RawInodeAddressingMode::Extent { + entries_cnt: updated.entries_cnt, + max_entries_cnt: updated.max_entries_cnt, + depth: updated.depth, + b: updated.b, + }, + ); + } + return Ok(None); } } @@ -399,15 +418,26 @@ where let mut pos = index.unwrap(); let updated_start = new.block; - if let Err(_en) = node.insert_at(Entry::Leaf(new), pos) { + if let Err(_en) = node.insert_at(Entry::Leaf(new.clone()), pos, tx) { todo!() } + if let PathEntry::Root((updated, _)) = self.last() { + tx.inode_update_root( + self.ino, + RawInodeAddressingMode::Extent { + entries_cnt: updated.entries_cnt, + max_entries_cnt: updated.max_entries_cnt, + depth: updated.depth, + b: updated.b, + }, + ); + } - for idx in (0..self.len() - 1).rev() { + for i in (0..self.len() - 1).rev() { if pos != 0 { break; } - dispatch_entry_mut!(self.get_mut(idx).unwrap(), |node, idx| { + dispatch_entry_mut!(self.get_mut(i).unwrap(), |node, idx| { pos = idx.unwrap(); let prev = node.get(pos).unwrap().get_internal().unwrap(); node.replace_at( @@ -416,8 +446,25 @@ where next_node: prev.next_node, }), pos, + tx, ) .unwrap_or_else(|_| unreachable!()); + + if i == 0 { + if let PathEntry::Root((updated, _)) = self.get(0).unwrap() { + tx.inode_update_root( + self.ino, + RawInodeAddressingMode::Extent { + entries_cnt: updated.entries_cnt, + max_entries_cnt: updated.max_entries_cnt, + depth: updated.depth, + b: updated.b, + }, + ); + } else { + unreachable!(); + } + } }); } @@ -441,7 +488,10 @@ where (ino.0 as u64 - 1) / fs.sb.inodes_per_group as u64, )); let lba = fs.blocks.allocate(self.ino, 1, hope, fs, tx)?.0; - let b = fs.blocks.get_mut_noload(lba, &tx.collector)?; + + // let b = fs.blocks.get_mut_noload(lba, Some(&tx.collector))?; + // ### To prevent the collector from tracking the extent node block. + let b = fs.blocks.get_mut_noload(lba, None)?; { // Initialize the node. let mut guard = b.write(); @@ -453,8 +503,11 @@ where } let mut node = Node::from_bytes(b).unwrap(); + tx.extent_init_node(lba, root.get_depth()); + for i in 0..root.get_entries_cnt() as usize { - node.insert_at(root.get(i).unwrap(), i) + let entry = root.get(i).unwrap(); + node.insert_at(entry.clone(), i, tx) .unwrap_or_else(|_| unreachable!()); } @@ -466,12 +519,24 @@ where next_node: lba, }), 0, + tx, ) .unwrap_or_else(|_| unreachable!()); + if let PathEntry::Root((updated, _)) = self.get(0).unwrap() { + tx.inode_update_root( + self.ino, + RawInodeAddressingMode::Extent { + entries_cnt: updated.entries_cnt, + max_entries_cnt: updated.max_entries_cnt, + depth: updated.depth, + b: updated.b, + }, + ); + } Ok(()) } - fn insert_internal(&mut self, ext: Internal, at: usize) -> bool { + fn insert_internal(&mut self, ext: Internal, at: usize, tx: &Transaction) -> bool { // Find location for insertion. dispatch_entry_mut!(self.get_mut(at).unwrap(), |node, idx| { let loc = if node.is_full() { @@ -483,8 +548,22 @@ where } else { idx.unwrap() }; - node.insert_at(Entry::Internal(ext), loc) + node.insert_at(Entry::Internal(ext), loc, tx) .unwrap_or_else(|_| unreachable!()); + if at == 0 { + if let PathEntry::Root((updated, _)) = self.get(0).unwrap() { + tx.inode_update_root( + self.ino, + RawInodeAddressingMode::Extent { + entries_cnt: updated.entries_cnt, + max_entries_cnt: updated.max_entries_cnt, + depth: updated.depth, + b: updated.b, + }, + ); + } + } + true }) } @@ -511,7 +590,7 @@ where let (lba, _) = fs .blocks .allocate(self.ino, 1, LogicalBlockNumber(0), fs, tx)?; - let e = fs.blocks.get_mut_noload(lba, &tx.collector)?; + let e = fs.blocks.get_mut_noload(lba, None)?; blocks.push(e); } @@ -521,6 +600,12 @@ where .enumerate() .map(|(d, hdr_b)| { // Leaf. + let node_lba = if let Some(PathEntry::Leaf((node, _))) = self.get(d + at) { + Some(node.b.lba()) + } else { + None + }; + dispatch_entry_mut!(self.get_mut(d + at).unwrap(), |ext, idx| { // Leaf node. if d + at == depth { @@ -549,13 +634,17 @@ where // To insert here. let mut node = Node::from_bytes(hdr_b).unwrap(); + tx.extent_init_node(node.b.lba(), ext.get_depth()); + let base = idx.unwrap(); let move_amount = ext.get_entries_cnt() as usize - base - 1; for i in 0..move_amount { - node.insert_at(ext.get(base + i + 1).unwrap(), i) + node.insert_at(ext.get(base + i + 1).unwrap(), i, tx) .unwrap_or_else(|_| unreachable!()); } ext.set_entries_cnt(base as u16 + 1); + tx.extent_update_node_set_entries_cnt(node_lba.unwrap(), base as u16 + 1); + node.into_inner() } else { todo!() @@ -570,6 +659,7 @@ where block: insert_idx, }, at - 1, + tx, ) .then(|| (new.block >= insert_idx, blocks)) .ok_or(FsError::InvalidFs("Extent Tree is corrupted.")) @@ -583,7 +673,7 @@ where fs: &'a FileSystem, ) -> Result, FsError> { loop { - if let Some(l) = self.insert_leaf(new)? { + if let Some(l) = self.insert_leaf(new, tx)? { new = l; } else { break Ok(None); @@ -601,7 +691,7 @@ where }; let (need_fix, blks) = self - .split_at(&new, self.len() - level - 1, tx, fs) + .split_at(&new, level + 1, tx, fs) .map_err(|_| FsError::IoError)?; if need_fix { @@ -692,6 +782,11 @@ where tx, )?; } + let node_lba = if let Some((node, _)) = self.leafs.last() { + Some(node.b.lba()) + } else { + None + }; dispatch_entry_mut!(self.last_mut(), |node, idx| { if new_len != 0 { let idx = idx.unwrap(); @@ -701,10 +796,33 @@ where ..leaf }), idx, + tx, ) .unwrap(); } else { - node.set_entries_cnt(node.get_entries_cnt().checked_sub(1).unwrap_or_default()); + let cnt = node.get_entries_cnt().checked_sub(1).unwrap_or_default(); + node.set_entries_cnt(cnt); + match node_lba { + Some(lba) => { + // Node + tx.extent_update_node_set_entries_cnt(lba, cnt); + } + None => { + // Root + if let PathEntry::Root((updated, _)) = self.get(0).unwrap() { + assert_eq!(updated.entries_cnt, cnt); + tx.inode_update_root( + self.ino, + RawInodeAddressingMode::Extent { + entries_cnt: updated.entries_cnt, + max_entries_cnt: updated.max_entries_cnt, + depth: updated.depth, + b: updated.b, + }, + ); + } + } + } self.move_prev_with_cleanup(tx, fs)?; } }); @@ -725,6 +843,11 @@ where Some(0) if len != 1 => { len -= 1; let (p_node, _) = self.leafs.pop().unwrap(); + let node_lba = if let PathEntry::Leaf((node, _)) = self.last() { + Some(node.b.lba()) + } else { + None + }; dispatch_entry_mut!(self.last_mut(), |node, idx| { // cleanup if p_node.get_entries_cnt() == 0 { @@ -739,6 +862,29 @@ where fs.blocks.deallocate(ino, lba, 1, fs, tx)?; node.set_entries_cnt(new_count); + match node_lba { + Some(node_lba) => { + // Node + tx.extent_update_node_set_entries_cnt(node_lba, new_count); + } + None => { + // Root + // assert_eq!(self.len(), 1); + if let PathEntry::Root((updated, _)) = self.get(0).unwrap() { + // assert_eq!(updated.entries_cnt, new_count); + tx.inode_update_root( + ino, + RawInodeAddressingMode::Extent { + entries_cnt: updated.entries_cnt, + max_entries_cnt: updated.max_entries_cnt, + depth: updated.depth, + b: updated.b, + }, + ); + } + } + } + if new_count != 0 { break; } diff --git a/src/inode/mod.rs b/src/inode/mod.rs index 5fefdc8..9040e40 100644 --- a/src/inode/mod.rs +++ b/src/inode/mod.rs @@ -13,7 +13,7 @@ // limitations under the License. mod allocator; -mod extent; +pub(crate) mod extent; mod legacy; mod manager; mod raw; @@ -25,8 +25,8 @@ use crate::superblock::Ext4FeatureIncompatible; use crate::symlink::Symlink; use crate::transaction::Transaction; use crate::{ - Config, FileBlockNumber, FileType, FsError, FsObject, InodeMode, InodeNumber, - LogicalBlockNumber, RwLock, + std::RwLock, Config, FileBlockNumber, FileType, FsError, FsObject, InodeMode, InodeNumber, + LogicalBlockNumber, }; use alloc::sync::{Arc, Weak}; use bitflags::bitflags; diff --git a/src/lib.rs b/src/lib.rs index 60f9a4a..dbe954e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,10 +24,7 @@ mod std; pub use synchronizations::rwlock::{ - Dreamer as RwDreamer, - RwLock, - RwLockReadGuard, - RwLockWriteGuard + Dreamer as RwDreamer, RwLock, RwLockReadGuard, RwLockWriteGuard, }; pub use synchronizations::ticket_lock::{Dreamer, TicketLock, TicketLockGuard}; diff --git a/src/std.rs b/src/std.rs index 424b0d6..8a479f3 100644 --- a/src/std.rs +++ b/src/std.rs @@ -124,7 +124,6 @@ impl synchronizations::ticket_lock::Dreamer for SpinningDreamer { fn release_hook(&self) {} } - /// A Opaque dreamer for RwLock. /// /// We will not use the implementation of synchromization::RwLock on std. @@ -150,18 +149,11 @@ impl synchronizations::rwlock::Dreamer for OpaqueDreamer { unreachable!() } #[inline] - fn acquire_hook( - &self, - _h: synchronizations::rwlock::Hint, - _d: bool, - ) { + fn acquire_hook(&self, _h: synchronizations::rwlock::Hint, _d: bool) { unreachable!() } #[inline] - fn release_hook( - &self, - _h: synchronizations::rwlock::Hint, - ) { + fn release_hook(&self, _h: synchronizations::rwlock::Hint) { unreachable!() } } @@ -230,7 +222,6 @@ impl Config for std::fs::File { } } - #[cfg(test)] pub(crate) mod tests { use crate::format; diff --git a/src/transaction/event.rs b/src/transaction/event.rs index 33be40e..13d304e 100644 --- a/src/transaction/event.rs +++ b/src/transaction/event.rs @@ -16,6 +16,7 @@ use super::collector::{Collector, PostludeOps}; use crate::block::BlockRef; use crate::block_group; use crate::filesystem::FileSystem; +use crate::inode::extent::{Entry, RawNode}; use crate::inode::{self, RawInodeAddressingMode}; use crate::superblock; use crate::{ @@ -92,6 +93,12 @@ impl core::fmt::Debug for InodeSetSize { } } +#[derive(Debug)] +pub struct InodeUpdateRoot { + pub(super) ino: InodeNumber, + pub(super) address: RawInodeAddressingMode, +} + #[derive(Debug)] pub enum Event { BlockAllocationOnBg(BlockAllocationOnBg), @@ -104,6 +111,8 @@ pub enum Event { InodeUpdateOrphanLink(InodeUpdateOrphanLink), FreeInodesCountDecOnSb, FreeInodesCountIncOnSb, + InodeUpdateRoot(InodeUpdateRoot), + ExtentUpdateNode(ExtentNodeOps), } #[derive(Debug)] @@ -206,6 +215,8 @@ impl Events { Event::InodeSetSize(op) => { wb_grp.inode_ops.push(InodeOps::SetSize(op)); } + Event::InodeUpdateRoot(ext) => wb_grp.inode_ops.push(InodeOps::UpdateRoot(ext)), + Event::ExtentUpdateNode(op) => wb_grp.extent_node_ops.push(op), } } wb_grp @@ -244,6 +255,7 @@ pub enum InodeOps { SetSize(InodeSetSize), UpdateOrphanLink(InodeUpdateOrphanLink), SetBlock { ino: InodeNumber, cnt: i64 }, + UpdateRoot(InodeUpdateRoot), } fn get_inode<'a, 'b, C: Config + 'a, const BLK_SIZE: usize>( @@ -300,6 +312,7 @@ struct WritebackGroup { bg_deltas: HashMap, sb_delta: Option, inode_ops: Vec, + extent_node_ops: Vec, _ty: core::marker::PhantomData, } @@ -309,6 +322,7 @@ impl WritebackGroup { bg_deltas: HashMap::new(), sb_delta: None, inode_ops: Vec::new(), + extent_node_ops: Vec::new(), _ty: core::marker::PhantomData, } } @@ -408,6 +422,7 @@ impl WritebackGroup { bg_deltas, sb_delta, inode_ops, + extent_node_ops, .. } = self; @@ -420,6 +435,9 @@ impl WritebackGroup { for op in inode_ops.into_iter() { Self::submit_inode_ops(fs, op, &mut raw_sb, collector)?; } + + Self::submit_extent_node_ops(fs, extent_node_ops, collector)?; + Self::submit_sb(sb_delta, raw_sb, collector)?; Ok(()) } @@ -542,7 +560,67 @@ impl WritebackGroup { .0, ); } + InodeOps::UpdateRoot(ext) => { + let InodeUpdateRoot { ino, address } = ext; + // println!("Commit Root Update - Ino: {}, Inode - {:?}\n", ino.0, address); + let (raw, range) = get_inode(fs, ino, collector)?; + let mut guard = raw.write(); + let mut inode = inode::Manipulator::new(&mut guard[range]); + inode.set_addresses(fs, address); + } + } + Ok(()) + } + + fn submit_extent_node_ops( + fs: &FileSystem, + ops: Vec, + collector: &Collector, + ) -> Result<(), FsError> { + let mut op_map = HashMap::new(); // Map: lba -> Vec + + ops.iter().for_each(|op| { + let lba = op.lba(); + op_map.entry(lba).or_insert(Vec::new()).push(op); + }); + + for (lba, op_vec) in op_map { + let raw_conf: [u8; BLK_SIZE] = fs + .blocks + .get_mut(lba, collector)? + .read() + .as_slice() + .try_into() + .expect("Invalid block size"); + let mut raw_node = RawNode::from_raw(raw_conf); + + for op in op_vec.into_iter() { + match op { + ExtentNodeOps::InsertAt(InsertAt { at, entry, .. }) => { + raw_node.insert_at(entry.clone(), *at).unwrap(); + // println!("Commit Node Insert - lba: {}, at: {}", lba.0, at); + } + ExtentNodeOps::ReplaceAt(ReplaceAt { at, entry, .. }) => { + raw_node.replace_at(entry.clone(), *at).unwrap(); + // println!("Commit Node Replace - lba: {}, at: {}", lba.0, at); + } + ExtentNodeOps::SetEntriesCnt(SetEntriesCnt { v, .. }) => { + raw_node.set_entries_cnt(*v); + // println!("Commit Node SetEntriesCnt - lba: {}, v: {}", lba.0, v); + } + ExtentNodeOps::Init(Init { depth, .. }) => { + raw_node.init(*depth); + // println!("Commit Node Init - lba: {}, depth: {}", lba.0, depth); + } + } + } + + let raw_conf = raw_node.to_raw(); + let b_ref = fs.blocks.get_mut(lba, collector)?; + let mut guard = b_ref.write(); + guard.copy_from_slice(&raw_conf); } + Ok(()) } @@ -572,3 +650,48 @@ impl WritebackGroup { Ok(()) } } + +#[derive(Debug)] +pub struct InsertAt { + pub(super) node_lba: LogicalBlockNumber, + pub(super) at: usize, + pub(super) entry: Entry, +} + +#[derive(Debug)] +pub struct ReplaceAt { + pub(super) node_lba: LogicalBlockNumber, + pub(super) at: usize, + pub(super) entry: Entry, +} + +#[derive(Debug)] +pub struct SetEntriesCnt { + pub(super) node_lba: LogicalBlockNumber, + pub(super) v: u16, +} + +#[derive(Debug)] +pub struct Init { + pub(super) node_lba: LogicalBlockNumber, + pub(super) depth: u16, +} + +#[derive(Debug)] +pub(crate) enum ExtentNodeOps { + InsertAt(InsertAt), + ReplaceAt(ReplaceAt), + SetEntriesCnt(SetEntriesCnt), + Init(Init), +} + +impl ExtentNodeOps { + fn lba(&self) -> LogicalBlockNumber { + match self { + ExtentNodeOps::InsertAt(InsertAt { node_lba, .. }) => *node_lba, + ExtentNodeOps::ReplaceAt(ReplaceAt { node_lba, .. }) => *node_lba, + ExtentNodeOps::SetEntriesCnt(SetEntriesCnt { node_lba, .. }) => *node_lba, + ExtentNodeOps::Init(Init { node_lba, .. }) => *node_lba, + } + } +} diff --git a/src/transaction/mod.rs b/src/transaction/mod.rs index 0044abd..bffdb44 100644 --- a/src/transaction/mod.rs +++ b/src/transaction/mod.rs @@ -17,13 +17,15 @@ mod collector; mod event; use crate::filesystem::FileSystem; +use crate::inode::extent::Entry; use crate::inode::RawInodeAddressingMode; use crate::{BlockGroupId, Config, FileType, FsError, InodeNumber, LogicalBlockNumber}; use alloc::collections::LinkedList; use core::cell::RefCell; use event::{ - BlockAllocationOnBg, BlockDeallocationOnBg, InodeAddLink, InodeAllocationOnBg, - InodeDeallocationOnBg, InodeRmLink, InodeSetSize, InodeUpdateOrphanLink, + BlockAllocationOnBg, BlockDeallocationOnBg, ExtentNodeOps, Init, InodeAddLink, + InodeAllocationOnBg, InodeDeallocationOnBg, InodeRmLink, InodeSetSize, InodeUpdateOrphanLink, + InodeUpdateRoot, InsertAt, ReplaceAt, SetEntriesCnt, }; pub use collector::Collector; @@ -213,6 +215,77 @@ impl Transaction { })) } + #[inline] + pub fn inode_update_root(&self, ino: InodeNumber, address: RawInodeAddressingMode) { + self.events + .inner + .as_ref() + .unwrap() + .borrow_mut() + .push_back(Event::InodeUpdateRoot(InodeUpdateRoot { ino, address })) + } + + pub(crate) fn extent_update_node_insert_at( + &self, + node_lba: LogicalBlockNumber, + entry: Entry, + at: usize, + ) { + self.events + .inner + .as_ref() + .unwrap() + .borrow_mut() + .push_back(Event::ExtentUpdateNode(ExtentNodeOps::InsertAt(InsertAt { + node_lba, + at, + entry, + }))); + } + + pub(crate) fn extent_update_node_replace_at( + &self, + node_lba: LogicalBlockNumber, + entry: Entry, + at: usize, + ) { + self.events + .inner + .as_ref() + .unwrap() + .borrow_mut() + .push_back(Event::ExtentUpdateNode(ExtentNodeOps::ReplaceAt( + ReplaceAt { + node_lba, + at, + entry, + }, + ))); + } + + pub(crate) fn extent_update_node_set_entries_cnt(&self, node_lba: LogicalBlockNumber, v: u16) { + self.events + .inner + .as_ref() + .unwrap() + .borrow_mut() + .push_back(Event::ExtentUpdateNode(ExtentNodeOps::SetEntriesCnt( + SetEntriesCnt { node_lba, v }, + ))); + } + + pub(crate) fn extent_init_node(&self, node_lba: LogicalBlockNumber, depth: u16) { + self.events + .inner + .as_ref() + .unwrap() + .borrow_mut() + .push_back(Event::ExtentUpdateNode(ExtentNodeOps::Init(Init { + node_lba, + depth, + }))); + } + #[inline] pub fn done( self, diff --git a/src/types.rs b/src/types.rs index 032e3a1..083275d 100644 --- a/src/types.rs +++ b/src/types.rs @@ -241,4 +241,4 @@ where } fn total_size(&self) -> usize; -} \ No newline at end of file +} From 2336be754db72affcaaf918144b803a9c6d3fd7f Mon Sep 17 00:00:00 2001 From: EunsuKim03 Date: Wed, 28 Aug 2024 14:04:40 +0900 Subject: [PATCH 4/4] fix std import --- src/block/mod.rs | 4 +-- src/cache.rs | 2 +- src/filesystem.rs | 2 +- src/format.rs | 55 +++++++++++++++++++++++++++++++++++--- src/inode/allocator.rs | 2 +- src/inode/extent/cursor.rs | 4 +-- src/inode/extent/mod.rs | 5 ++-- src/inode/mod.rs | 4 +-- src/std.rs | 10 +++---- src/superblock/raw.rs | 2 ++ 10 files changed, 70 insertions(+), 20 deletions(-) diff --git a/src/block/mod.rs b/src/block/mod.rs index 2835938..f3a2b59 100644 --- a/src/block/mod.rs +++ b/src/block/mod.rs @@ -21,8 +21,8 @@ use crate::superblock::SuperBlock; use crate::transaction::{Collector, Transaction}; use crate::types::Zero; use crate::{ - std::RwLock, std::RwLockReadGuard, std::RwLockWriteGuard, BlockGroupId, Config, FsError, - InodeNumber, LogicalBlockNumber, + BlockGroupId, Config, FsError, InodeNumber, LogicalBlockNumber, RwLock, RwLockReadGuard, + RwLockWriteGuard, }; use alloc::sync::Arc; diff --git a/src/cache.rs b/src/cache.rs index 3369389..bf3ea8a 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{std::RwLock, RwDreamer}; +use crate::{RwDreamer, RwLock}; use alloc::sync::{Arc, Weak}; use hashbrown::{hash_map::Entry, HashMap}; diff --git a/src/filesystem.rs b/src/filesystem.rs index eb35788..044c728 100644 --- a/src/filesystem.rs +++ b/src/filesystem.rs @@ -19,7 +19,7 @@ use crate::inode; use crate::superblock::SuperBlock; use crate::transaction::{Events, Transaction}; use crate::types::BlockGroupId; -use crate::{std::RwLock, std::RwLockReadGuard, Config, FileType, FsError, FsObject, InodeNumber}; +use crate::{Config, FileType, FsError, FsObject, InodeNumber, RwLock, RwLockReadGuard}; use alloc::collections::LinkedList; use alloc::sync::Arc; use alloc::vec::Vec; diff --git a/src/format.rs b/src/format.rs index dbb44b8..036ac60 100644 --- a/src/format.rs +++ b/src/format.rs @@ -65,7 +65,8 @@ impl<'a> FormatAux<'a> { feat_ro: Ext4FeatureReadOnly::SPARSE_SUPER | Ext4FeatureReadOnly::LARGE_FILE | Ext4FeatureReadOnly::GDT_CSUM, - feat_com: Ext4FeatureCompatible::DIR_INDEX, + feat_com: Ext4FeatureCompatible::DIR_INDEX, // ### No journal disk + // feat_com: Ext4FeatureCompatible::DIR_INDEX | Ext4FeatureCompatible::HAS_JOURNAL, // ### Has journal disk feat_incom: Ext4FeatureIncompatible::FILETYPE | Ext4FeatureIncompatible::EXTENTS, uuid, volumn_name, @@ -117,6 +118,10 @@ fn make_sb( sb.first_inode().set(11); sb.inode_size().set(256); + if feat_com.contains(Ext4FeatureCompatible::HAS_JOURNAL) { + sb.journal_inum().set(8); // ### Journal inode number = 8 + } + sb.rw.b.as_mut()[0x68..0x78].copy_from_slice(uuid); sb.rw.b.as_mut()[0x78..0x88].copy_from_slice(volumn_name); sb.rw.b.as_mut()[0xEC..0xFC].copy_from_slice(hash_seed); @@ -183,9 +188,19 @@ fn fill_bg( .as_mut(), ); if bgid.0 == 0 { + // ino 2 -> Root, ino 8 -> Journal inode_bitmap.set_bitmap(0..1); - inode_bitmap.set_bitmap(2..10); - free_inodes -= 9; + if sb + .features_compatible + .contains(Ext4FeatureCompatible::HAS_JOURNAL) + { + inode_bitmap.set_bitmap(2..7); + inode_bitmap.set_bitmap(8..10); + free_inodes -= 8; + } else { + inode_bitmap.set_bitmap(2..10); + free_inodes -= 9; + } } // Set end of inode bitmap. kill 1) unusable 2) padding. inode_bitmap.set_bitmap(sb.inodes_per_group as usize..BLK_SIZE * 8); @@ -267,6 +282,39 @@ fn fill_bg( Ok(()) } +pub fn make_journal_disk( + fs: &Arc>, +) -> Result<(), FsError> { + if !fs + .sb + .features_compatible + .contains(Ext4FeatureCompatible::HAS_JOURNAL) + { + // No journal disk + return Ok(()); + } + let journal_inum = 8; + let ino = fs + .inodes + .allocator + .try_allocate_at(journal_inum, fs)? + .unwrap(); + let tx = fs.open_transaction(); + let guard = fs.get_block_group(BlockGroupId(0))?; + let bg = guard.as_ref().unwrap(); + let de = FileType::Directory; + + bg.allocate_inode_on_bg(journal_inum - 1, &tx, de); + fs.sb.dec_free_inodes_count(&tx); + let _inode = fs + .inodes + .inodes + .get_or_insert::<_, ()>(ino, |ino| Ok(Inode::new(fs, ino, de))) + .unwrap(); + + tx.done(fs) +} + fn make_root( fs: &Arc>, ) -> Result<(), FsError> { @@ -323,6 +371,7 @@ pub fn format( .copy_from_slice(sb.manipulator.lock().rw.inner().0[0..BUFSIZE].as_ref()); dev.write_bytes(1024, &buf)?; let fs = FileSystem::::new(dev, sb); + make_journal_disk(&fs)?; make_root(&fs)?; Ok(fs) } diff --git a/src/inode/allocator.rs b/src/inode/allocator.rs index b005100..6856423 100644 --- a/src/inode/allocator.rs +++ b/src/inode/allocator.rs @@ -15,7 +15,7 @@ use crate::filesystem::FileSystem; use crate::transaction::Transaction; use crate::types::BlockGroupId; -use crate::{std::RwLock, std::RwLockReadGuard, Config, FileType, FsError, InodeNumber}; +use crate::{Config, FileType, FsError, InodeNumber, RwLock, RwLockReadGuard}; use alloc::boxed::Box; use alloc::vec::Vec; use core::sync::atomic::{AtomicU32, AtomicU8, Ordering}; diff --git a/src/inode/extent/cursor.rs b/src/inode/extent/cursor.rs index 9cdf1ce..1c8b8fc 100644 --- a/src/inode/extent/cursor.rs +++ b/src/inode/extent/cursor.rs @@ -136,9 +136,7 @@ where (true, true) => return Ok((start + ((self.fba.0 - block.0) as u64), 1)), (_, false) => todo!("Uninitialized extent"), (false, true) if block > self.fba => start + (self.fba.0 as u64 - start.0), - (false, true) => { - LogicalBlockNumber(start.0.saturating_sub(self.fba.0 as u64 - block.0 as u64)) - } // if start==0, overflow + (false, true) => start - (self.fba.0 as u64 - block.0 as u64), } } else if self.path.leafs.is_empty() { // tree is empty. diff --git a/src/inode/extent/mod.rs b/src/inode/extent/mod.rs index 73ec479..17ee8f7 100644 --- a/src/inode/extent/mod.rs +++ b/src/inode/extent/mod.rs @@ -24,6 +24,7 @@ use crate::{Config, FileBlockNumber, FsError, InodeNumber, LogicalBlockNumber}; use self::path::Path; pub(crate) use cursor::{Cursor, CursorMut}; +use synchronizations::rwlock::RwLock; #[derive(Clone, Debug)] pub(crate) struct Internal { @@ -190,7 +191,7 @@ pub struct ExtentTree { pub(super) depth: u16, pub(super) b: [u8; 48], #[cfg(feature = "extent_cache")] - pub(super) cache: crate::std::RwLock, C::D>, + pub(super) cache: RwLock, C::D>, #[cfg(not(feature = "extent_cache"))] pub(super) _l: core::marker::PhantomData, } @@ -331,7 +332,7 @@ impl Default for ExtentTree { depth: 0, b: [0; 48], #[cfg(feature = "extent_cache")] - cache: crate::std::RwLock::new(None), + cache: RwLock::new(None), #[cfg(not(feature = "extent_cache"))] _l: core::marker::PhantomData, } diff --git a/src/inode/mod.rs b/src/inode/mod.rs index 9040e40..d4594ba 100644 --- a/src/inode/mod.rs +++ b/src/inode/mod.rs @@ -25,8 +25,8 @@ use crate::superblock::Ext4FeatureIncompatible; use crate::symlink::Symlink; use crate::transaction::Transaction; use crate::{ - std::RwLock, Config, FileBlockNumber, FileType, FsError, FsObject, InodeMode, InodeNumber, - LogicalBlockNumber, + Config, FileBlockNumber, FileType, FsError, FsObject, InodeMode, InodeNumber, + LogicalBlockNumber, RwLock, }; use alloc::sync::{Arc, Weak}; use bitflags::bitflags; diff --git a/src/std.rs b/src/std.rs index 8a479f3..9552937 100644 --- a/src/std.rs +++ b/src/std.rs @@ -138,23 +138,23 @@ impl synchronizations::rwlock::Dreamer for OpaqueDreamer { #[inline] fn sleeping(&self, _s: &core::sync::atomic::AtomicUsize, _h: synchronizations::rwlock::Hint) { - unreachable!() + () } #[inline] fn waking_up(&self) { - unreachable!() + () } #[inline] fn prehook(&self) -> Self::HookAux { - unreachable!() + () } #[inline] fn acquire_hook(&self, _h: synchronizations::rwlock::Hint, _d: bool) { - unreachable!() + () } #[inline] fn release_hook(&self, _h: synchronizations::rwlock::Hint) { - unreachable!() + () } } diff --git a/src/superblock/raw.rs b/src/superblock/raw.rs index f992481..0cb1a8a 100644 --- a/src/superblock/raw.rs +++ b/src/superblock/raw.rs @@ -155,6 +155,8 @@ impl Manipulator { feature_ro_compat: @0x64, u32; /// Number of reserved GDT entries for future filesystem expansion. reserverd_gdt_blocks: @0xCE, u16; + /// Inode number of journal file + journal_inum: @0xE0, u32; /// Start of list of orphaned inodes to delete. last_orphan: @0xE8, u32; /// Default hash algorithm to use for directory hashes.