Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,4 @@ chrono = { version = "0.4", default-features = false, features = ["clock"], opti
[dev-dependencies]
env_logger = "0.9"
fscommon = "0.1"
tempfile = "3.24.0"
20 changes: 10 additions & 10 deletions src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1173,16 +1173,6 @@ pub fn format_volume<S: ReadWriteSeek>(storage: &mut S, options: FormatVolumeOpt

let bpb = &boot.bpb;
if bpb.is_fat32() {
// FSInfo sector
let fs_info_sector = FsInfoSector {
free_cluster_count: None,
next_free_cluster: None,
dirty: false,
};
storage.seek(SeekFrom::Start(bpb.bytes_from_sectors(bpb.fs_info_sector())))?;
fs_info_sector.serialize(storage)?;
write_zeros_until_end_of_sector(storage, bytes_per_sector)?;

// backup boot sector
storage.seek(SeekFrom::Start(bpb.bytes_from_sectors(bpb.backup_boot_sector())))?;
boot.serialize(storage)?;
Expand Down Expand Up @@ -1220,6 +1210,16 @@ pub fn format_volume<S: ReadWriteSeek>(storage: &mut S, options: FormatVolumeOpt
let fat32_root_dir_pos = bpb.bytes_from_sectors(fat32_root_dir_first_sector);
storage.seek(SeekFrom::Start(fat32_root_dir_pos))?;
write_zeros(storage, u64::from(bpb.cluster_size()))?;

let free_cluster_count = bpb.total_clusters() - 1;
Comment thread
cole-h marked this conversation as resolved.
let fs_info_sector = FsInfoSector {
free_cluster_count: Some(free_cluster_count),
next_free_cluster: Some(root_dir_first_cluster + 1),
dirty: false,
};
storage.seek(SeekFrom::Start(bpb.bytes_from_sectors(bpb.fs_info_sector())))?;
fs_info_sector.serialize(storage)?;
write_zeros_until_end_of_sector(storage, bytes_per_sector)?;
}

// Create volume label directory entry if volume label is specified in options
Expand Down
51 changes: 34 additions & 17 deletions tests/fsck.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
#![cfg(target_os = "linux")]
use fatfs::Write;

use fatfs::{FatType, Write};

const KB: u32 = 1024;
const MB: u32 = KB * 1024;

#[test]
fn test_fsck_1mb() {
let _ = env_logger::builder().is_test(true).try_init();
fn create_and_fsck_image(fat_type: FatType, size: u32) {
let mut disk_img =
tempfile::NamedTempFile::with_suffix(format!("-{fat_type:?}-{size}.img")).expect("create named tempfile");
let disk_img_path = disk_img.path().display().to_string();

let mut image = std::fs::OpenOptions::new()
.write(true)
.read(true)
.create(true)
.open("/tmp/test.img")
.expect("open temporary image file");
image.set_len(MB as u64).expect("set_len on temp file");
let image = disk_img.as_file_mut();
image.set_len(size as u64).expect("set_len on temp file");

fatfs::format_volume(
&mut fatfs::StdIoWrapper::from(image.try_clone().expect("clone tempfile")),
fatfs::FormatVolumeOptions::new().total_sectors(MB / 512),
fatfs::FormatVolumeOptions::new()
.fat_type(fat_type)
.total_sectors(size / 512),
)
.expect("format volume");

let fsck_status = std::process::Command::new("fsck.vfat")
Comment thread
cole-h marked this conversation as resolved.
.args(&["-y", &disk_img_path])
.status()
.expect("get fsck.vfat status");
assert!(fsck_status.success(), "fsck was not successful ({fsck_status:?})");

let fs = fatfs::FileSystem::new(image, fatfs::FsOptions::new()).expect("open fs");
fs.root_dir().create_dir("dir1").expect("create dir1");
fs.root_dir()
Expand All @@ -39,10 +44,22 @@ fn test_fsck_1mb() {
core::mem::drop(fs);

let fsck_status = std::process::Command::new("fsck.vfat")
.args(&["-n", "/tmp/test.img"])
.spawn()
.expect("spawn fsck")
.wait()
.expect("wait on fsck");
.args(&["-y", &disk_img_path])
.status()
.expect("get fsck.vfat status");
assert!(fsck_status.success(), "fsck was not successful ({fsck_status:?})");
}

#[test]
fn test_fsck_1mb_fat12() {
let _ = env_logger::builder().is_test(true).try_init();

create_and_fsck_image(FatType::Fat12, MB);
}

#[test]
fn test_fsck_33mb_fat32() {
let _ = env_logger::builder().is_test(true).try_init();

create_and_fsck_image(FatType::Fat32, 33 * MB);
}
Loading