main.rs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. use ext4_rs::{Block, BlockDevice, Ext4, BLOCK_SIZE};
  2. use log::warn;
  3. use simple_logger::SimpleLogger;
  4. use std::fs::{File, OpenOptions};
  5. use std::io::{Read, Seek, SeekFrom, Write};
  6. use std::sync::Arc;
  7. #[derive(Debug)]
  8. pub struct BlockFile(File);
  9. impl BlockFile {
  10. pub fn new(path: &str) -> Self {
  11. let file = OpenOptions::new()
  12. .read(true)
  13. .write(true)
  14. .open(path)
  15. .unwrap();
  16. Self(file)
  17. }
  18. }
  19. impl BlockDevice for BlockFile {
  20. fn read_block(&self, block_id: u64) -> Block {
  21. let mut file = &self.0;
  22. let mut buffer = [0u8; BLOCK_SIZE];
  23. // warn!("read_block {}", block_id);
  24. let _r = file.seek(SeekFrom::Start(block_id * BLOCK_SIZE as u64));
  25. let _r = file.read_exact(&mut buffer);
  26. Block::new(block_id, buffer)
  27. }
  28. fn write_block(&self, block: &Block) {
  29. let mut file = &self.0;
  30. // warn!("write_block {}", block.block_id);
  31. let _r = file.seek(SeekFrom::Start(block.block_id * BLOCK_SIZE as u64));
  32. let _r = file.write_all(&block.data);
  33. }
  34. }
  35. fn logger_init() {
  36. SimpleLogger::new().init().unwrap();
  37. log::set_max_level(log::LevelFilter::Debug);
  38. }
  39. fn make_ext4() {
  40. let _ = std::process::Command::new("rm")
  41. .args(["-rf", "ext4.img"])
  42. .status();
  43. let _ = std::process::Command::new("dd")
  44. .args(["if=/dev/zero", "of=ext4.img", "bs=1M", "count=512"])
  45. .status();
  46. let _ = std::process::Command::new("mkfs.ext4")
  47. .args(["ext4.img"])
  48. .output();
  49. }
  50. fn open_ext4() -> Ext4 {
  51. let file = BlockFile::new("ext4.img");
  52. println!("creating ext4");
  53. Ext4::load(Arc::new(file)).expect("open ext4 failed")
  54. }
  55. fn mkdir_test(ext4: &mut Ext4) {
  56. ext4.mkdir("d1").expect("mkdir failed");
  57. ext4.mkdir("d1/d2").expect("mkdir failed");
  58. ext4.mkdir("d1/d2/d3").expect("mkdir failed");
  59. ext4.mkdir("d1/d2/d3/d4").expect("mkdir failed");
  60. ext4.mkdir("d2").expect("mkdir failed");
  61. ext4.mkdir("d2/d3").expect("mkdir failed");
  62. ext4.mkdir("d2/d3/d4").expect("mkdir failed");
  63. ext4.mkdir("d3").expect("mkdir failed");
  64. }
  65. fn open_test(ext4: &mut Ext4) {
  66. ext4.open("d1/d2/d3/d4/f1", "w+", true)
  67. .expect("open failed");
  68. ext4.open("d1/d2/d3/d4/f1", "r", true).expect("open failed");
  69. ext4.open("d1/d2/d3/d4/f5", "a", true).expect("open failed");
  70. ext4.open("d2/f4", "w+", true).expect("open failed");
  71. ext4.open("f1", "w+", true).expect("open failed");
  72. }
  73. fn read_write_test(ext4: &mut Ext4) {
  74. let wbuffer = "hello world".as_bytes();
  75. let mut wfile = ext4.open("d3/f0", "w+", true).expect("open failed");
  76. ext4.write(&mut wfile, wbuffer).expect("write failed");
  77. let mut rbuffer = vec![0u8; wbuffer.len()];
  78. let mut rfile = ext4.open("d3/f0", "r", true).expect("open failed");
  79. ext4.read(&mut rfile, &mut rbuffer, wbuffer.len())
  80. .expect("read failed");
  81. assert_eq!(wbuffer, rbuffer);
  82. }
  83. fn large_read_write_test(ext4: &mut Ext4) {
  84. let wbuffer = vec![99u8; 1024 * 1024 * 16];
  85. let mut wfile = ext4.open("d3/f2", "w+", true).expect("open failed");
  86. ext4.write(&mut wfile, &wbuffer).expect("write failed");
  87. let mut rfile = ext4.open("d3/f2", "r", true).expect("open failed");
  88. let mut rbuffer = vec![0u8; wbuffer.len()];
  89. ext4.read(&mut rfile, &mut rbuffer, wbuffer.len())
  90. .expect("read failed");
  91. assert_eq!(wbuffer, rbuffer);
  92. }
  93. fn main() {
  94. logger_init();
  95. make_ext4();
  96. println!("ext4.img created");
  97. let mut ext4 = open_ext4();
  98. println!("ext4 opened");
  99. mkdir_test(&mut ext4);
  100. println!("mkdir test done");
  101. open_test(&mut ext4);
  102. println!("open test done");
  103. read_write_test(&mut ext4);
  104. println!("read write test done");
  105. large_read_write_test(&mut ext4);
  106. println!("large read write test done");
  107. }