Skip to content

Commit c69fafd

Browse files
Fully implement the journal type
This fills in the `Journal` struct and implements the rest of the `Journal::load` method.
1 parent ac1e217 commit c69fafd

File tree

2 files changed

+29
-8
lines changed

2 files changed

+29
-8
lines changed

src/journal.rs

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,36 +7,55 @@
77
// except according to those terms.
88

99
mod block_header;
10-
#[expect(unused)] // TODO
1110
mod block_map;
1211
mod commit_block;
1312
mod descriptor_block;
14-
#[expect(unused)] // TODO
1513
mod superblock;
1614

17-
use crate::{Ext4, Ext4Error};
15+
use crate::error::Ext4Error;
16+
use crate::inode::Inode;
17+
use crate::Ext4;
18+
use block_map::{load_block_map, BlockMap};
19+
use superblock::JournalSuperblock;
1820

1921
#[derive(Debug)]
2022
pub(crate) struct Journal {
21-
// TODO: add journal data.
23+
block_map: BlockMap,
2224
}
2325

2426
impl Journal {
2527
/// Create an empty journal.
2628
pub(crate) fn empty() -> Self {
27-
Self {}
29+
Self {
30+
block_map: BlockMap::new(),
31+
}
2832
}
2933

3034
/// Load a journal from the filesystem.
35+
///
36+
/// If the filesystem has no journal, an empty journal is returned.
37+
///
38+
/// Note: ext4 is all little-endian, except for the journal, which
39+
/// is all big-endian.
3140
pub(crate) fn load(fs: &Ext4) -> Result<Self, Ext4Error> {
32-
let Some(_journal_inode) = fs.0.superblock.journal_inode else {
41+
let Some(journal_inode) = fs.0.superblock.journal_inode else {
3342
// Return an empty journal if this filesystem does not have
3443
// a journal.
3544
return Ok(Self::empty());
3645
};
3746

38-
// TODO: actually load the journal.
47+
let journal_inode = Inode::read(fs, journal_inode)?;
48+
let superblock = JournalSuperblock::load(fs, &journal_inode)?;
49+
let block_map = load_block_map(fs, &superblock, &journal_inode)?;
3950

40-
Ok(Self {})
51+
Ok(Self { block_map })
52+
}
53+
54+
/// Map from an absolute block index to a block in the journal.
55+
///
56+
/// If the journal does not contain a replacement for the input
57+
/// block, the input block is returned.
58+
pub(crate) fn map_block_index(&self, block_index: u64) -> u64 {
59+
*self.block_map.get(&block_index).unwrap_or(&block_index)
4160
}
4261
}

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,8 @@ impl Ext4 {
303303
})
304304
};
305305

306+
let block_index = self.0.journal.map_block_index(block_index);
307+
306308
// The first 1024 bytes are reserved for non-filesystem
307309
// data. This conveniently allows for something like a null
308310
// pointer check.

0 commit comments

Comments
 (0)