use fs_ext4::block_io::FileDevice;
use fs_ext4::jbd2::{self, JBD2_SUPERBLOCK_V1, JBD2_SUPERBLOCK_V2};
use fs_ext4::Filesystem;
use std::sync::Arc;
fn mount_fixture(image: &str) -> Filesystem {
let path = fs_ext4_test_support::fixture(env!("CARGO_MANIFEST_DIR"), image);
let dev = FileDevice::open(&path).unwrap_or_else(|e| panic!("open {path}: {e:?}"));
Filesystem::mount(Arc::new(dev)).unwrap_or_else(|e| panic!("mount {path}: {e:?}"))
}
#[test]
fn journal_sb_round_trips_on_basic_image() {
let fs = mount_fixture("ext4-basic.img");
let sb = jbd2::read_superblock(&fs).expect("read_superblock");
match sb {
Some(jsb) => {
assert!(
matches!(jsb.block_type, JBD2_SUPERBLOCK_V1 | JBD2_SUPERBLOCK_V2),
"bad block_type {}",
jsb.block_type
);
assert_eq!(
jsb.block_size,
fs.sb.block_size(),
"journal block_size {} != fs block_size {}",
jsb.block_size,
fs.sb.block_size()
);
assert!(jsb.max_len > 0, "max_len == 0");
assert!(jsb.first >= 1, "first block < 1: {}", jsb.first);
assert_eq!(jsb.errno, 0, "journal errno = {}", jsb.errno);
assert!(
jsb.is_clean(),
"expected clean journal (start=0), got start={}",
jsb.start
);
}
None => {
assert_eq!(fs.sb.journal_inode, 0, "journal_inode != 0 but got None");
}
}
}
#[test]
fn journal_sb_on_csum_seed_image() {
let fs = mount_fixture("ext4-csum-seed.img");
let jsb = jbd2::read_superblock(&fs)
.expect("read_superblock")
.expect("ext4-csum-seed.img has no journal superblock");
assert!(matches!(
jsb.block_type,
JBD2_SUPERBLOCK_V1 | JBD2_SUPERBLOCK_V2
));
assert_eq!(jsb.block_size, fs.sb.block_size());
assert!(jsb.is_clean());
}
#[test]
fn journal_sb_on_htree_image() {
let fs = mount_fixture("ext4-htree.img");
let jsb = jbd2::read_superblock(&fs)
.expect("read_superblock")
.expect("ext4-htree.img has no journal superblock");
assert!(matches!(
jsb.block_type,
JBD2_SUPERBLOCK_V1 | JBD2_SUPERBLOCK_V2
));
assert!(jsb.max_len > 0);
assert!(jsb.is_clean());
}