Fix 2GB image/snapshot save limits; add disk throughput chart - #116
Merged
Conversation
DiskImageSerializer.Save buffered the entire node region into a MemoryStream before compressing/encrypting it, which throws "Stream was too long" once a disk's actual content approaches the ~2GB int32 length limit -- including on the final save during unmount/app-exit/OS-shutdown, silently losing unsaved changes. Unencrypted saves/loads now stream directly to/from the file instead of buffering. Encrypted saves/loads switch to chunked AES-256-GCM (new image format version 4) so no single AES-GCM call or buffer needs to hold the whole node region; version 3's whole-blob encrypted format is still read for backward compatibility.
Individual snapshot file blobs had the same class of bug fixed for DiskImageSerializer: EnsureBlobWritten/ReadBlob materialized the full compressed/encrypted payload as a single buffer, and WriteNode truncated file size to int before that -- both breaking for single files approaching/exceeding ~2GB. Extracted the chunked AES-256-GCM stream pair used by DiskImageSerializer into a shared ChunkedGcm helper and reused it here so encrypted blobs are written/read chunk-by-chunk. Unencrypted blobs now stream straight through FileContent/GZipStream instead of via MemoryStream. Old whole-blob encrypted blobs are still read via a legacy branch for backward compatibility.
Tracks cumulative bytes read/written per mounted disk (MemoryFileSystem, RamDisk), derives an instantaneous rate via ThroughputTracker, and surfaces it on the tray icon tooltip and a new SpeedHistoryChart control on the disk card.
- SnapshotStore.ReadBlob: restore the corrupted-length check that was dropped when the blob read path was rewritten to stream via FillFromStream; FillFromStream now returns the actual byte count read so callers can detect truncated/corrupt sources. - DiskImageSerializer.LoadCurrent: dispatch encrypted-region loading on an explicit version switch (3/4) instead of a boolean version == 3 check, so an unexpected version value fails loudly instead of silently falling into the chunked path. - TrayIconController.SetHighUsageWarningActive: record the active state before bailing out on missing tray icons, so a call that arrives before icon generation finishes doesn't get silently dropped and desync future calls from the real state. - MainWindow: resolve the speed-history popup via an explicit Tag binding instead of FrameworkElement.Parent, which is not a reliable way to reach a Popup from its hosted content.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
.mdrdisk image save/load failing withIOException: Stream was too longonce a disk's content approaches ~2GB, by streaming the node region instead of buffering it whole, and switching encrypted saves to chunked AES-256-GCM (new image format version 4; version 3 still readable).SnapshotStore's individual content-addressed file blobs (write/read now stream viaFileContent, encrypted blobs use the same shared chunked-AES-GCM helper, extracted intoChunkedGcm). Also fixes aninttruncation of file size in the snapshot writer.ThroughputTracker) with aSpeedHistoryChartpopup on the disk card and tray tooltip./code-reviewon the above: restored a dropped corrupted-blob-length check, fixed a tray high-usage-warning state bug, made image version dispatch explicit instead of implicit, and made the speed-history popup lookup robust instead of relying on WPF logical-tree parentage.Test plan
dotnet build— solution builds with 0 warnings/errors introduceddotnet test tests/ManagedDrive.Tests— 236/236 pass, including new chunked round-trip, legacy-format-compat, and corrupted-blob regression tests