1
0

mkfs.rs 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // Copyright 2024 The ChromiumOS Authors
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. // To allow compiling this file on non-Linux platforms, main logic is
  5. // behind the `linux` module.
  6. #[cfg(target_os = "linux")]
  7. mod linux {
  8. use std::fs::OpenOptions;
  9. use std::io::Write;
  10. use std::path::PathBuf;
  11. use argh::FromArgs;
  12. use base::MappedRegion;
  13. #[derive(FromArgs)]
  14. /// Create ext2 filesystem.
  15. struct Args {
  16. /// path to the disk,
  17. #[argh(option)]
  18. output: String,
  19. /// path to the source directory to copy files from,
  20. #[argh(option)]
  21. src: Option<String>,
  22. /// number of blocks for each group
  23. #[argh(option, default = "1024")]
  24. blocks_per_group: u32,
  25. /// number of inodes for each group
  26. #[argh(option, default = "1024")]
  27. inodes_per_group: u32,
  28. /// size of memory region in bytes.
  29. /// If it's not a multiple of 4096, it will be rounded up to the next multiple of 4096.
  30. #[argh(option, default = "4194304")]
  31. size: u32,
  32. /// if sepecified, create a file systeon on RAM, but do not write to disk.
  33. #[argh(switch, short = 'j')]
  34. dry_run: bool,
  35. }
  36. pub fn main() -> anyhow::Result<()> {
  37. let args: Args = argh::from_env();
  38. let src_dir = args.src.as_ref().map(|s| PathBuf::new().join(s));
  39. let builder = ext2::Builder {
  40. blocks_per_group: args.blocks_per_group,
  41. inodes_per_group: args.inodes_per_group,
  42. size: args.size,
  43. root_dir: src_dir,
  44. };
  45. let mem = builder.allocate_memory()?.build_mmap_info()?.do_mmap()?;
  46. if args.dry_run {
  47. println!("Done!");
  48. return Ok(());
  49. }
  50. // SAFETY: `mem` has a valid pointer and its size.
  51. let buf = unsafe { std::slice::from_raw_parts(mem.as_ptr(), mem.size()) };
  52. let mut file = OpenOptions::new()
  53. .write(true)
  54. .create(true)
  55. .truncate(true)
  56. .open(&args.output)
  57. .unwrap();
  58. file.write_all(buf).unwrap();
  59. println!("{} is written!", args.output);
  60. Ok(())
  61. }
  62. }
  63. fn main() -> anyhow::Result<()> {
  64. #[cfg(target_os = "linux")]
  65. linux::main()?;
  66. #[cfg(not(target_os = "linux"))]
  67. println!("Not supported on non-Linux platforms");
  68. Ok(())
  69. }