Skip to content

Commit 5a67cfb

Browse files
authored
Merge pull request #189 from yanshay/yanshay_fix_seek_write_block_start
fix seek and write to block start zeros rest of block after written data (#188)
2 parents 7e98d11 + 97b2471 commit 5a67cfb

File tree

3 files changed

+65
-3
lines changed

3 files changed

+65
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ The format is based on [Keep a Changelog] and this project adheres to [Semantic
1414
- __Breaking Change__: The `VolumeManager::device` method now takes a callback rather than giving you a reference to the underlying `BlockDevice`
1515
- __Breaking Change__: `Error:LockError` variant added.
1616
- __Breaking Change__: `SearchId` was renamed to `Handle`
17+
- Fixed writing at block start mid-file (previously overwrote subsequent file data with zeros up to the end of the block)
1718

1819
### Added
1920

src/volume_mgr.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -878,13 +878,15 @@ where
878878
Err(e) => return Err(e),
879879
};
880880
let to_copy = core::cmp::min(block_avail, bytes_to_write - written);
881-
let block = if block_offset != 0 {
881+
let block = if (block_offset == 0) && (to_copy == block_avail) {
882+
// we're replacing the whole Block, so the previous contents
883+
// are irrelevant
884+
data.block_cache.blank_mut(block_idx)
885+
} else {
882886
debug!("Reading for partial block write");
883887
data.block_cache
884888
.read_mut(block_idx)
885889
.map_err(Error::DeviceError)?
886-
} else {
887-
data.block_cache.blank_mut(block_idx)
888890
};
889891
block[block_offset..block_offset + to_copy]
890892
.copy_from_slice(&buffer[written..written + to_copy]);

tests/write_file.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,65 @@ fn flush_file() {
102102
assert_eq!(entry.size, 64 * 3);
103103
}
104104

105+
#[test]
106+
fn random_access_write_file() {
107+
let time_source = utils::make_time_source();
108+
let disk = utils::make_block_device(utils::DISK_SOURCE).unwrap();
109+
let volume_mgr: VolumeManager<utils::RamDisk<Vec<u8>>, utils::TestTimeSource, 4, 2, 1> =
110+
VolumeManager::new_with_limits(disk, time_source, 0xAA00_0000);
111+
let volume = volume_mgr
112+
.open_raw_volume(VolumeIdx(0))
113+
.expect("open volume");
114+
let root_dir = volume_mgr.open_root_dir(volume).expect("open root dir");
115+
116+
// Open with string
117+
let f = volume_mgr
118+
.open_file_in_dir(root_dir, "README.TXT", Mode::ReadWriteTruncate)
119+
.expect("open file");
120+
121+
let test_data = vec![0xCC; 1024];
122+
volume_mgr.write(f, &test_data).expect("file write");
123+
124+
let length = volume_mgr.file_length(f).expect("get length");
125+
assert_eq!(length, 1024);
126+
127+
for seek_offset in [100, 0] {
128+
let mut expected_buffer = [0u8; 4];
129+
130+
// fetch some data at offset seek_offset
131+
volume_mgr
132+
.file_seek_from_start(f, seek_offset)
133+
.expect("Seeking");
134+
volume_mgr.read(f, &mut expected_buffer).expect("read file");
135+
136+
// modify first byte
137+
expected_buffer[0] ^= 0xff;
138+
139+
// write only first byte, expecting the rest to not change
140+
volume_mgr
141+
.file_seek_from_start(f, seek_offset)
142+
.expect("Seeking");
143+
volume_mgr
144+
.write(f, &expected_buffer[0..1])
145+
.expect("file write");
146+
volume_mgr.flush_file(f).expect("file flush");
147+
148+
// read and verify
149+
volume_mgr
150+
.file_seek_from_start(f, seek_offset)
151+
.expect("file seek");
152+
let mut read_buffer = [0xffu8, 0xff, 0xff, 0xff];
153+
volume_mgr.read(f, &mut read_buffer).expect("file read");
154+
assert_eq!(
155+
read_buffer, expected_buffer,
156+
"mismatch seek+write at offset {seek_offset} from start"
157+
);
158+
}
159+
160+
volume_mgr.close_file(f).expect("close file");
161+
volume_mgr.close_dir(root_dir).expect("close dir");
162+
volume_mgr.close_volume(volume).expect("close volume");
163+
}
105164
// ****************************************************************************
106165
//
107166
// End Of File

0 commit comments

Comments
 (0)