From 0ebf8a6000c20b56df138ad79ce16a74628bad9d Mon Sep 17 00:00:00 2001 From: Keiichi Watanabe Date: Fri, 29 Mar 2024 21:15:47 +0900 Subject: ext2: Support customized parameters Allow changing {blocks,inodes}_per_group. BUG=b:329359333 TEST=cargo test Change-Id: I1646f80dbe92dbdafbe4147a8abbd141784aff69 Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5400932 Commit-Queue: Keiichi Watanabe Reviewed-by: Takaya Saeki --- ext2/examples/mkfs.rs | 22 +++++++++++++++++----- ext2/src/fs.rs | 6 ++++-- ext2/src/lib.rs | 1 + ext2/src/superblock.rs | 14 +++++++++++--- ext2/tests/tests.rs | 22 +++++++++++++++++++--- 5 files changed, 52 insertions(+), 13 deletions(-) diff --git a/ext2/examples/mkfs.rs b/ext2/examples/mkfs.rs index 91e5ed6a1..d602fe6a9 100644 --- a/ext2/examples/mkfs.rs +++ b/ext2/examples/mkfs.rs @@ -15,16 +15,27 @@ mod linux { #[derive(FromArgs)] /// Create ext2 filesystem. - struct Config { + struct Args { /// path to the disk, #[argh(option)] path: String, + + /// number of blocks for each group + #[argh(option, default = "1024")] + blocks_per_group: u32, + + /// number of inodes for each group + #[argh(option, default = "1024")] + inodes_per_group: u32, } pub fn main() -> anyhow::Result<()> { - let cfg: Config = argh::from_env(); - let ext2 = Ext2::new()?; - println!("Create {}", cfg.path); + let args: Args = argh::from_env(); + let ext2 = Ext2::new(&ext2::Config { + blocks_per_group: args.blocks_per_group, + inodes_per_group: args.inodes_per_group, + })?; + println!("Create {}", args.path); let mem = ext2.write_to_memory()?; // SAFETY: `mem` has a valid pointer and its size. let buf = unsafe { std::slice::from_raw_parts(mem.as_ptr(), mem.size()) }; @@ -32,8 +43,9 @@ mod linux { .write(true) .create(true) .truncate(true) - .open(&cfg.path) + .open(&args.path) .unwrap(); + file.write_all(buf).unwrap(); Ok(()) diff --git a/ext2/src/fs.rs b/ext2/src/fs.rs index e98a2f840..bd8e0e803 100644 --- a/ext2/src/fs.rs +++ b/ext2/src/fs.rs @@ -11,6 +11,7 @@ use base::MemoryMapping; use base::MemoryMappingBuilder; use zerocopy::AsBytes; +use crate::superblock::Config; use crate::superblock::SuperBlock; /// A struct to represent an ext2 filesystem. @@ -20,8 +21,9 @@ pub struct Ext2 { impl Ext2 { /// Create a new ext2 filesystem. - pub fn new() -> Result { - let sb = SuperBlock::new()?; + + pub fn new(cfg: &Config) -> Result { + let sb = SuperBlock::new(cfg)?; Ok(Ext2 { sb }) } diff --git a/ext2/src/lib.rs b/ext2/src/lib.rs index b88a1f17a..85a536e5b 100644 --- a/ext2/src/lib.rs +++ b/ext2/src/lib.rs @@ -11,3 +11,4 @@ mod fs; mod superblock; pub use fs::Ext2; +pub use superblock::Config; diff --git a/ext2/src/superblock.rs b/ext2/src/superblock.rs index ca2eb872c..c5bd6e7ea 100644 --- a/ext2/src/superblock.rs +++ b/ext2/src/superblock.rs @@ -9,6 +9,14 @@ use zerocopy::AsBytes; use zerocopy_derive::FromBytes; use zerocopy_derive::FromZeroes; +/// A struct to represent the configuration of an ext2 filesystem. +pub struct Config { + /// The number of blocks per group. + pub blocks_per_group: u32, + /// The number of inodes per group. + pub inodes_per_group: u32, +} + /// The ext2 superblock. /// /// The field names are based on [the specification](https://www.nongnu.org/ext2-doc/ext2.html#superblock). @@ -53,13 +61,13 @@ pub(crate) struct SuperBlock { } impl SuperBlock { - pub fn new() -> Result { + pub fn new(cfg: &Config) -> Result { const EXT2_MAGIC_NUMBER: u16 = 0xEF53; // TODO(b/329359333): Support more than 1 groups for larger data. let block_group_nr = 1u16; - let blocks_per_group = 1024; - let inodes_per_group = 1024; + let blocks_per_group = cfg.blocks_per_group; + let inodes_per_group = cfg.inodes_per_group; let log_block_size = 2; // (1024 << log_block_size) = 4K bytes diff --git a/ext2/tests/tests.rs b/ext2/tests/tests.rs index 963ea8512..3ab9fdc89 100644 --- a/ext2/tests/tests.rs +++ b/ext2/tests/tests.rs @@ -10,6 +10,7 @@ use std::path::PathBuf; use std::process::Command; use base::MappedRegion; +use ext2::Config; use ext2::Ext2; use tempfile::tempdir; @@ -44,11 +45,10 @@ fn do_autofix(path: &PathBuf, fix_count: usize) { println!("output={:?}", output); } -#[test] -fn mkfs_empty() { +fn mkfs_empty(cfg: &Config) { let td = tempdir().unwrap(); let path = td.path().join("empty.ext2"); - let ext2 = Ext2::new().unwrap(); + let ext2 = Ext2::new(cfg).unwrap(); let mem = ext2.write_to_memory().unwrap(); // SAFETY: `mem` has a valid pointer and its size. let buf = unsafe { std::slice::from_raw_parts(mem.as_ptr(), mem.size()) }; @@ -67,3 +67,19 @@ fn mkfs_empty() { run_fsck(&path); } + +#[test] +fn test_mkfs_empty() { + mkfs_empty(&Config { + blocks_per_group: 1024, + inodes_per_group: 1024, + }); +} + +#[test] +fn test_mkfs_empty_more_blocks() { + mkfs_empty(&Config { + blocks_per_group: 2048, + inodes_per_group: 4096, + }); +} -- cgit v1.2.3