Zero new directory clusters after allocation.

This commit is contained in:
Rafał Harabień 2017-10-27 15:03:54 +02:00
parent 9ec23f1234
commit 21bd2a0e8d
3 changed files with 38 additions and 16 deletions

View File

@ -225,7 +225,15 @@ impl DirEntryData {
fn deserialize(rdr: &mut Read) -> io::Result<DirEntryData> {
let mut name = [0; 11];
rdr.read_exact(&mut name)?;
match rdr.read_exact(&mut name) {
Err(ref err) if err.kind() == io::ErrorKind::UnexpectedEof => {
return Ok(DirEntryData::File(DirFileEntryData {
..Default::default()
}));
}
Err(err) => return Err(err),
_ => {},
}
let attrs = FileAttributes::from_bits_truncate(rdr.read_u8()?);
if attrs & FileAttributes::LFN == FileAttributes::LFN {
let mut data = DirLfnEntryData {
@ -617,8 +625,14 @@ impl <'a, 'b> Dir<'a, 'b> {
let mut num_free = 0;
let mut i = 0;
loop {
let data = DirEntryData::deserialize(&mut stream)?;
if data.is_free() {
let raw_entry = DirEntryData::deserialize(&mut stream)?;
if raw_entry.is_end() {
if num_free == 0 {
first_free = i;
}
stream.seek(io::SeekFrom::Start(first_free as u64 * DIR_ENTRY_SIZE))?;
return Ok(stream);
} else if raw_entry.is_free() {
if num_free == 0 {
first_free = i;
}
@ -627,13 +641,6 @@ impl <'a, 'b> Dir<'a, 'b> {
stream.seek(io::SeekFrom::Start(first_free as u64 * DIR_ENTRY_SIZE))?;
return Ok(stream);
}
} else if data.is_end() {
if num_free == 0 {
first_free = i;
}
stream.seek(io::SeekFrom::Start(first_free as u64 * DIR_ENTRY_SIZE))?;
// FIXME: make sure new allocated cluster is zeroed
return Ok(stream);
} else {
num_free = 0;
}
@ -728,16 +735,12 @@ pub struct DirIter<'a, 'b: 'a> {
}
impl <'a, 'b> DirIter<'a, 'b> {
fn read_dir_entry_raw_data(&mut self) -> io::Result<DirEntryData> {
DirEntryData::deserialize(&mut self.stream)
}
fn read_dir_entry(&mut self) -> io::Result<Option<DirEntry<'a, 'b>>> {
let mut lfn_buf = LongNameBuilder::new();
let mut offset = self.stream.seek(SeekFrom::Current(0))?;
let mut begin_offset = offset;
loop {
let raw_entry = self.read_dir_entry_raw_data()?;
let raw_entry = DirEntryData::deserialize(&mut self.stream)?;
offset += DIR_ENTRY_SIZE;
match raw_entry {
DirEntryData::File(data) => {

View File

@ -217,9 +217,21 @@ impl<'a, 'b> Write for File<'a, 'b> {
None => {
// end of chain reached - allocate new cluster
let new_cluster = self.fs.alloc_cluster(self.current_cluster)?;
trace!("allocated cluser {}", new_cluster);
if self.first_cluster.is_none() {
self.set_first_cluster(new_cluster);
}
if self.entry.clone().map_or(true, |e| e.data.size().is_none()) {
// zero new directory cluster
trace!("zeroing directory cluser {}", 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
},
}

View File

@ -125,7 +125,7 @@ fn test_remove_fat32() {
fn test_create_file(fs: FileSystem) {
let mut root_dir = fs.root_dir();
let dir = root_dir.open_dir("very/long/path").unwrap();
let mut dir = root_dir.open_dir("very/long/path").unwrap();
let mut names = dir.iter().map(|r| r.unwrap().file_name()).collect::<Vec<String>>();
assert_eq!(names, [".", "..", "test.txt"]);
{
@ -140,6 +140,13 @@ fn test_create_file(fs: FileSystem) {
file.read_to_string(&mut content).unwrap();
assert_eq!(&content, &TEST_STR);
}
// Create enough entries to allocate next cluster
for i in 0..512/32 {
let name = format!("test{}", i);
dir.create_file(&name).unwrap();
}
names = dir.iter().map(|r| r.unwrap().file_name()).collect::<Vec<String>>();
assert_eq!(names.len(), 4 + 512/32);
}
#[test]