fix: clear directory returned from create_dir method
Previous implementation did not zero allocated cluster so created directory could have garbage contents. Bug exists in code since version 0.2 and all code using create_dir is affected. This commit also improves tests of volume formatting so a dirty partition is used allowing to detect bugs like this.
This commit is contained in:
parent
647ca9252a
commit
cf3256bfda
@ -236,7 +236,7 @@ impl<'a, T: ReadWriteSeek + 'a> Dir<'a, T> {
|
||||
// directory does not exist - create it
|
||||
DirEntryOrShortName::ShortName(short_name) => {
|
||||
// alloc cluster for directory data
|
||||
let cluster = self.fs.alloc_cluster(None)?;
|
||||
let cluster = self.fs.alloc_cluster(None, true)?;
|
||||
// create entry in parent directory
|
||||
let sfn_entry = self.create_sfn_entry(short_name, FileAttributes::DIRECTORY, Some(cluster));
|
||||
let entry = self.write_entry(name, sfn_entry)?;
|
||||
|
13
src/file.rs
13
src/file.rs
@ -261,22 +261,11 @@ impl<'a, T: ReadWriteSeek> Write for File<'a, T> {
|
||||
Some(n) => n,
|
||||
None => {
|
||||
// end of chain reached - allocate new cluster
|
||||
let new_cluster = self.fs.alloc_cluster(self.current_cluster)?;
|
||||
let new_cluster = self.fs.alloc_cluster(self.current_cluster, self.is_dir())?;
|
||||
trace!("allocated cluser {}", new_cluster);
|
||||
if self.first_cluster.is_none() {
|
||||
self.set_first_cluster(new_cluster);
|
||||
}
|
||||
if self.is_dir() {
|
||||
// zero new directory cluster
|
||||
trace!("zeroing directory cluster {}", new_cluster);
|
||||
let abs_pos = self.fs.offset_from_cluster(new_cluster);
|
||||
let mut disk = self.fs.disk.borrow_mut();
|
||||
disk.seek(SeekFrom::Start(abs_pos))?;
|
||||
for _ in 0..cluster_size / 32 {
|
||||
let zero = [0u8; 32];
|
||||
disk.write(&zero)?;
|
||||
}
|
||||
}
|
||||
new_cluster
|
||||
},
|
||||
}
|
||||
|
13
src/fs.rs
13
src/fs.rs
@ -472,11 +472,18 @@ impl<T: ReadWriteSeek> FileSystem<T> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn alloc_cluster(&self, prev_cluster: Option<u32>) -> io::Result<u32> {
|
||||
pub(crate) fn alloc_cluster(&self, prev_cluster: Option<u32>, zero: bool) -> io::Result<u32> {
|
||||
trace!("alloc_cluster");
|
||||
let hint = self.fs_info.borrow().next_free_cluster;
|
||||
let mut fat = self.fat_slice();
|
||||
let cluster = alloc_cluster(&mut fat, self.fat_type, prev_cluster, hint, self.total_clusters)?;
|
||||
let cluster = {
|
||||
let mut fat = self.fat_slice();
|
||||
alloc_cluster(&mut fat, self.fat_type, prev_cluster, hint, self.total_clusters)?
|
||||
};
|
||||
if zero {
|
||||
let mut disk = self.disk.borrow_mut();
|
||||
disk.seek(SeekFrom::Start(self.offset_from_cluster(cluster)))?;
|
||||
write_zeros(&mut *disk, self.cluster_size() as usize)?;
|
||||
}
|
||||
let mut fs_info = self.fs_info.borrow_mut();
|
||||
fs_info.set_next_free_cluster(cluster + 1);
|
||||
fs_info.add_free_clusters(-1);
|
||||
|
@ -50,7 +50,8 @@ fn basic_fs_test(fs: &FileSystem) {
|
||||
|
||||
fn test_format_fs(opts: fatfs::FormatVolumeOptions, total_bytes: u64) -> FileSystem {
|
||||
let _ = env_logger::try_init();
|
||||
let storage_vec: Vec<u8> = Vec::with_capacity(total_bytes as usize);
|
||||
// Init storage to 0xD1 bytes (value has been choosen to be parsed as normal file)
|
||||
let storage_vec: Vec<u8> = vec![0xD1u8; total_bytes as usize];
|
||||
let storage_cur = io::Cursor::new(storage_vec);
|
||||
let mut buffered_stream = BufStream::new(storage_cur);
|
||||
fatfs::format_volume(&mut buffered_stream, opts).expect("format volume");
|
||||
@ -86,7 +87,7 @@ fn test_format_50mb() {
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_format_512mb() {
|
||||
fn test_format_512mb_512sec() {
|
||||
let total_bytes = 2 * 1024 * MB;
|
||||
let opts = fatfs::FormatVolumeOptions::new((total_bytes / 512) as u32, 512);
|
||||
let fs = test_format_fs(opts, total_bytes);
|
||||
|
Loading…
Reference in New Issue
Block a user