|
7 | 7 | // except according to those terms.
|
8 | 8 |
|
9 | 9 | mod block_header;
|
10 |
| -#[expect(unused)] // TODO |
11 | 10 | mod block_map;
|
12 | 11 | mod commit_block;
|
13 | 12 | mod descriptor_block;
|
14 |
| -#[expect(unused)] // TODO |
15 | 13 | mod superblock;
|
16 | 14 |
|
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; |
18 | 20 |
|
19 | 21 | #[derive(Debug)]
|
20 | 22 | pub(crate) struct Journal {
|
21 |
| - // TODO: add journal data. |
| 23 | + block_map: BlockMap, |
22 | 24 | }
|
23 | 25 |
|
24 | 26 | impl Journal {
|
25 | 27 | /// Create an empty journal.
|
26 | 28 | pub(crate) fn empty() -> Self {
|
27 |
| - Self {} |
| 29 | + Self { |
| 30 | + block_map: BlockMap::new(), |
| 31 | + } |
28 | 32 | }
|
29 | 33 |
|
30 | 34 | /// 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. |
31 | 40 | 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 { |
33 | 42 | // Return an empty journal if this filesystem does not have
|
34 | 43 | // a journal.
|
35 | 44 | return Ok(Self::empty());
|
36 | 45 | };
|
37 | 46 |
|
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)?; |
39 | 50 |
|
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) |
41 | 60 | }
|
42 | 61 | }
|
0 commit comments