forked from M-Labs/rust-fatfs
Zero new directory clusters after allocation.
This commit is contained in:
parent
9ec23f1234
commit
21bd2a0e8d
33
src/dir.rs
33
src/dir.rs
@ -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) => {
|
||||
|
12
src/file.rs
12
src/file.rs
@ -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
|
||||
},
|
||||
}
|
||||
|
@ -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]
|
||||
|
Loading…
Reference in New Issue
Block a user