forked from M-Labs/rust-fatfs
Fix file-system corruption when creating directory entries
Corruption happens if: * files are created in non-root directory * directory size becomes greater or equal to cluster size Creating last directory entry in the directory cluster corrupts the cluster directly preceding the directory cluster. For 512 bytes long cluster creating 8th directory entry (counted from 1) will cause first corruption. Directory entry that causes the corruption will not be updated correctly. Fixes #42
This commit is contained in:
parent
7b18222941
commit
e4b72836f0
@ -1,6 +1,12 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
0.3.5 (not released yet)
|
||||
------------------------
|
||||
Bug fixes:
|
||||
* Fix file-system corruption when creating multiple directory entries in non-root directory (directory size must
|
||||
be greater or equal to cluster size for corruption to happen)
|
||||
|
||||
0.3.4 (2020-07-20)
|
||||
------------------
|
||||
Bug fixes:
|
||||
|
11
src/file.rs
11
src/file.rs
@ -76,8 +76,15 @@ impl<'a, T: ReadWriteSeek> File<'a, T> {
|
||||
match self.current_cluster {
|
||||
Some(n) => {
|
||||
let cluster_size = self.fs.cluster_size();
|
||||
let offset_in_cluster = self.offset % cluster_size;
|
||||
let offset_in_fs = self.fs.offset_from_cluster(n) + (offset_in_cluster as u64);
|
||||
let offset_mod_cluster_size = self.offset % cluster_size;
|
||||
let offset_in_cluster = if offset_mod_cluster_size == 0 {
|
||||
// position points between clusters - we are returning previous cluster so
|
||||
// offset must be set to the cluster size
|
||||
cluster_size
|
||||
} else {
|
||||
offset_mod_cluster_size
|
||||
};
|
||||
let offset_in_fs = self.fs.offset_from_cluster(n) + u64::from(offset_in_cluster);
|
||||
Some(offset_in_fs)
|
||||
},
|
||||
None => None,
|
||||
|
@ -349,3 +349,36 @@ fn test_dirty_flag_fat16() {
|
||||
fn test_dirty_flag_fat32() {
|
||||
call_with_tmp_img(&test_dirty_flag, FAT32_IMG, 7)
|
||||
}
|
||||
|
||||
fn test_multiple_files_in_directory(fs: FileSystem) {
|
||||
let dir = fs.root_dir().create_dir("/TMP").unwrap();
|
||||
for i in 0..8 {
|
||||
let name = format!("T{}.TXT", i);
|
||||
let mut file = dir.create_file(&name).unwrap();
|
||||
file.write_all(TEST_STR.as_bytes()).unwrap();
|
||||
file.flush().unwrap();
|
||||
|
||||
let file = dir.iter()
|
||||
.map(|r| r.unwrap())
|
||||
.filter(|e| e.file_name() == name)
|
||||
.next()
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(TEST_STR.len() as u64, file.len(), "Wrong file len on iteration {}", i);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_files_in_directory_fat12() {
|
||||
call_with_fs(&test_multiple_files_in_directory, FAT12_IMG, 8)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_files_in_directory_fat16() {
|
||||
call_with_fs(&test_multiple_files_in_directory, FAT16_IMG, 8)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_files_in_directory_fat32() {
|
||||
call_with_fs(&test_multiple_files_in_directory, FAT32_IMG, 8)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user