diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d242671..04b9fb82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,12 @@ The format is based on [Keep a Changelog] and this project adheres to [Semantic - None +## [Version 0.8.2] - 2025-06-07 + +### Changed + +* Fixed writing at block start mid-file (previously overwrote subsequent file data with zeros up to the end of the block) + ## [Version 0.8.1] - 2024-11-03 ### Changed @@ -174,13 +180,15 @@ The format is based on [Keep a Changelog] and this project adheres to [Semantic [Keep a Changelog]: http://keepachangelog.com/en/1.0.0/ [Semantic Versioning]: http://semver.org/spec/v2.0.0.html -[Unreleased]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.8.0...develop -[Version 0.8.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.8.0...v0.7.0 -[Version 0.7.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.7.0...v0.6.0 -[Version 0.6.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.6.0...v0.5.0 -[Version 0.5.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.5.0...v0.4.0 -[Version 0.4.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.4.0...v0.3.0 -[Version 0.3.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.3.0...v0.2.1 -[Version 0.2.1]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.2.1...v0.2.0 -[Version 0.2.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.2.0...v0.1.1 +[Unreleased]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.8.2...develop +[Version 0.8.2]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.8.1...v0.8.2 +[Version 0.8.1]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.8.0...v0.8.1 +[Version 0.8.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.7.0...v0.8.0 +[Version 0.7.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.6.0...v0.7.0 +[Version 0.6.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.5.0...v0.6.0 +[Version 0.5.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.4.0...v0.5.0 +[Version 0.4.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.3.0...v0.4.0 +[Version 0.3.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.2.1...v0.3.0 +[Version 0.2.1]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.2.0...v0.2.1 +[Version 0.2.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.1.1...v0.2.0 [Version 0.1.1]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/releases/tag/v0.1.1 diff --git a/Cargo.toml b/Cargo.toml index 53f6dfa0..6ddcc1d5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" name = "embedded-sdmmc" readme = "README.md" repository = "https://github.com/rust-embedded-community/embedded-sdmmc-rs" -version = "0.8.1" +version = "0.8.2" [dependencies] byteorder = {version = "1", default-features = false} diff --git a/src/volume_mgr.rs b/src/volume_mgr.rs index c4fffd38..ef659eef 100644 --- a/src/volume_mgr.rs +++ b/src/volume_mgr.rs @@ -753,8 +753,8 @@ where }; let mut blocks = [Block::new()]; let to_copy = core::cmp::min(block_avail, bytes_to_write - written); - if block_offset != 0 { - debug!("Partial block write"); + if block_offset != 0 || to_copy != block_avail { + debug!("Partial block read/modify/write"); self.block_device .read(&mut blocks, block_idx, "read") .map_err(Error::DeviceError)?; diff --git a/tests/write_file.rs b/tests/write_file.rs index 97e7bcdc..6fd4d059 100644 --- a/tests/write_file.rs +++ b/tests/write_file.rs @@ -102,6 +102,65 @@ fn flush_file() { assert_eq!(entry.size, 64 * 3); } +#[test] +fn random_access_write_file() { + let time_source = utils::make_time_source(); + let disk = utils::make_block_device(utils::DISK_SOURCE).unwrap(); + let mut volume_mgr: VolumeManager>, 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"); + + let test_data = vec![0xCC; 1024]; + volume_mgr.write(f, &test_data).expect("file write"); + + let length = volume_mgr.file_length(f).expect("get length"); + assert_eq!(length, 1024); + + for seek_offset in [100, 0] { + let mut expected_buffer = [0u8; 4]; + + // fetch some data at offset seek_offset + volume_mgr + .file_seek_from_start(f, seek_offset) + .expect("Seeking"); + volume_mgr.read(f, &mut expected_buffer).expect("read file"); + + // modify first byte + expected_buffer[0] ^= 0xff; + + // write only first byte, expecting the rest to not change + volume_mgr + .file_seek_from_start(f, seek_offset) + .expect("Seeking"); + volume_mgr + .write(f, &expected_buffer[0..1]) + .expect("file write"); + volume_mgr.flush_file(f).expect("file flush"); + + // read and verify + volume_mgr + .file_seek_from_start(f, seek_offset) + .expect("file seek"); + let mut read_buffer = [0xffu8, 0xff, 0xff, 0xff]; + volume_mgr.read(f, &mut read_buffer).expect("file read"); + assert_eq!( + read_buffer, expected_buffer, + "mismatch seek+write at offset {seek_offset} from start" + ); + } + + volume_mgr.close_file(f).expect("close file"); + volume_mgr.close_dir(root_dir).expect("close dir"); + volume_mgr.close_volume(volume).expect("close volume"); +} // **************************************************************************** // // End Of File