Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release/v0.8.0 #137

Merged
merged 27 commits into from
Jul 12, 2024
Merged
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
ec01477
Merge pull request #118 from rust-embedded-community/main
thejpster Feb 9, 2024
f880b51
Upgrade to heapless ^0.8
bsodmike Feb 25, 2024
ba27644
Merge pull request #120 from bsodmike/upgrade_heapless_0.8
thejpster Feb 25, 2024
3cdb6cb
Add ability to flush written data
peterkrull Mar 25, 2024
55c77ce
Merge pull request #121 from peterkrull/flush-written-file
thejpster Mar 25, 2024
86c20e0
Do not panic on errors during drop, add optional manual closing to no…
peterkrull Mar 29, 2024
710bd34
Merge pull request #123 from peterkrull/always-closing
thejpster Mar 30, 2024
1e89779
split FatVolume.iterate_dir into 2 subfunctions
orsinium Apr 3, 2024
f26de60
FIx some docs
orsinium Apr 3, 2024
44b63de
Merge pull request #127 from orsinium-forks/fat-iterate-dir-refactor
thejpster Apr 4, 2024
83128a3
Add new test.
thejpster Jun 1, 2024
07d7bd2
Bug fix for #131
thejpster Jun 1, 2024
a3c895b
Fix read_file_backwards.
thejpster Jun 1, 2024
a04e5f0
Fix seek_from_end.
thejpster Jun 1, 2024
0de58d3
Move new test into read_file.
thejpster Jun 1, 2024
59e4c2f
Code cleanups.
thejpster Jun 1, 2024
7b5b876
Appease clippy.
thejpster Jun 1, 2024
6b1ef4c
Update README example
thejpster Jun 1, 2024
ee72ddc
Merge pull request #134 from rust-embedded-community/fix-warnings
eldruin Jun 6, 2024
92c8ca9
Merge branch 'develop' into fix-seeking
eldruin Jun 6, 2024
860e072
Merge pull request #133 from rust-embedded-community/fix-seeking
eldruin Jun 10, 2024
510d50e
Use SpiDevice to control the chip select.
thejpster Jul 6, 2024
44a5736
Merge pull request #136 from rust-embedded-community/use-spidevice-pr…
thejpster Jul 12, 2024
c828250
Minor clean-ups of docs.
jonathanpallant Jul 12, 2024
4e4e084
Merge pull request #138 from rust-embedded-community/clean-up-docs
thejpster Jul 12, 2024
b178599
Update CHANGELOG.
jonathanpallant Jul 12, 2024
a1cc455
Update version to 0.8.0
jonathanpallant Jul 12, 2024
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
Prev Previous commit
Next Next commit
Add ability to flush written data
  • Loading branch information
peterkrull authored and jonathanpallant committed Mar 25, 2024
commit 3cdb6cb3b5dfab590739de5682c4cbab9cd3c5ee
7 changes: 6 additions & 1 deletion src/filesystem/files.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
filesystem::{ClusterId, DirEntry, SearchId},
RawVolume, VolumeManager,
Error, RawVolume, VolumeManager,
};

/// Represents an open file on disk.
@@ -123,6 +123,11 @@ where
core::mem::forget(self);
f
}

/// Flush any written data by updating the directory entry.
pub fn flush(&mut self) -> Result<(), Error<D::Error>> {
self.volume_mgr.flush_file(self.raw_file)
}
}

impl<'a, D, T, const MAX_DIRS: usize, const MAX_FILES: usize, const MAX_VOLUMES: usize> Drop
66 changes: 39 additions & 27 deletions src/volume_mgr.rs
Original file line number Diff line number Diff line change
@@ -773,38 +773,18 @@ where
Ok(())
}

/// Close a file with the given full path.
/// Close a file with the given raw file handle.
pub fn close_file(&mut self, file: RawFile) -> Result<(), Error<D::Error>> {
let mut found_idx = None;
for (idx, info) in self.open_files.iter().enumerate() {
if file == info.file_id {
found_idx = Some((info, idx));
break;
}
}

let (file_info, file_idx) = found_idx.ok_or(Error::BadHandle)?;

if file_info.dirty {
let volume_idx = self.get_volume_by_id(file_info.volume_id)?;
match self.open_volumes[volume_idx].volume_type {
VolumeType::Fat(ref mut fat) => {
debug!("Updating FAT info sector");
fat.update_info_sector(&self.block_device)?;
debug!("Updating dir entry {:?}", file_info.entry);
if file_info.entry.size != 0 {
// If you have a length, you must have a cluster
assert!(file_info.entry.cluster.0 != 0);
}
fat.write_entry_to_disk(&self.block_device, &file_info.entry)?;
}
};
}

let file_idx = self.flush_file_get_index(file)?;
self.open_files.swap_remove(file_idx);
Ok(())
}

/// Flush (update the entry) for a file with the given raw file handle.
pub fn flush_file(&mut self, file: RawFile) -> Result<(), Error<D::Error>> {
self.flush_file_get_index(file).map(|_| ())
}

/// Check if any files or folders are open.
pub fn has_open_handles(&self) -> bool {
!(self.open_dirs.is_empty() || self.open_files.is_empty())
@@ -1074,6 +1054,38 @@ where
let available = Block::LEN - block_offset;
Ok((block_idx, block_offset, available))
}

/// Flush (update the entry) for a file with the given raw file handle and
/// get its index.
fn flush_file_get_index(&mut self, file: RawFile) -> Result<usize, Error<D::Error>> {
let mut found_idx = None;
for (idx, info) in self.open_files.iter().enumerate() {
if file == info.file_id {
found_idx = Some((info, idx));
break;
}
}

let (file_info, file_idx) = found_idx.ok_or(Error::BadHandle)?;

if file_info.dirty {
let volume_idx = self.get_volume_by_id(file_info.volume_id)?;
match self.open_volumes[volume_idx].volume_type {
VolumeType::Fat(ref mut fat) => {
debug!("Updating FAT info sector");
fat.update_info_sector(&self.block_device)?;
debug!("Updating dir entry {:?}", file_info.entry);
if file_info.entry.size != 0 {
// If you have a length, you must have a cluster
assert!(file_info.entry.cluster.0 != 0);
}
fat.write_entry_to_disk(&self.block_device, &file_info.entry)?;
}
};
}

Ok(file_idx)
}
}

/// Transform mode variants (ReadWriteCreate_Or_Append) to simple modes ReadWriteAppend or
47 changes: 47 additions & 0 deletions tests/write_file.rs
Original file line number Diff line number Diff line change
@@ -55,6 +55,53 @@ fn append_file() {
volume_mgr.close_volume(volume).expect("close volume");
}

#[test]
fn flush_file() {
let time_source = utils::make_time_source();
let disk = utils::make_block_device(utils::DISK_SOURCE).unwrap();
let mut volume_mgr: VolumeManager<utils::RamDisk<Vec<u8>>, utils::TestTimeSource, 4, 2, 1> =
VolumeManager::new_with_limits(disk, time_source, 0xAA00_0000);
let volume = volume_mgr
.open_raw_volume(VolumeIdx(0))
.expect("open volume");
let root_dir = volume_mgr.open_root_dir(volume).expect("open root dir");

// Open with string
let f = volume_mgr
.open_file_in_dir(root_dir, "README.TXT", Mode::ReadWriteTruncate)
.expect("open file");

// Write some data to the file
let test_data = vec![0xCC; 64];
volume_mgr.write(f, &test_data).expect("file write");

// Check that the file length is zero in the directory entry, as we haven't
// flushed yet
let entry = volume_mgr
.find_directory_entry(root_dir, "README.TXT")
.expect("find entry");
assert_eq!(entry.size, 0);

volume_mgr.flush_file(f).expect("flush");

// Now check the file length again after flushing
let entry = volume_mgr
.find_directory_entry(root_dir, "README.TXT")
.expect("find entry");
assert_eq!(entry.size, 64);

// Flush more writes
volume_mgr.write(f, &test_data).expect("file write");
volume_mgr.write(f, &test_data).expect("file write");
volume_mgr.flush_file(f).expect("flush");

// Now check the file length again, again
let entry = volume_mgr
.find_directory_entry(root_dir, "README.TXT")
.expect("find entry");
assert_eq!(entry.size, 64 * 3);
}

// ****************************************************************************
//
// End Of File