-
Notifications
You must be signed in to change notification settings - Fork 179
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
Gaps in the ext vhd map seem to cause problems... #276
Comments
I have found some strange behaviors as well in the current implementation of Ext file systems, however I do remember whether I have seen this exact problem. It seems a bit related though to problems with sparse allocated files that we found a while ago. Looking at the changes that I did back then, it seems it could be related. But I am not sure if it really solves the problem you have seen here. |
PS I goofed part of the analysis -- the "high bit" bug is in the ext parser, not the vhd parser! Ext4 changed things:
For a 4KiB block size, a short can map up to 256MiB of data, and the extent size is limited to 128MiB, freeing up the high bit! The high bit is used for:
So DiscUtils.Ext\Extent.cs definitely needs to ignore this, as proposed above in ((1))! |
Yes, the vhd implementation in DiscUtils is most probably very stable and correct these days. It is after all an open format, well documented and very easy to follow the logic in the official documentation for it. Theoretically, the same should of course also apply to Ext. But it is a lot more complex and the DiscUtils implementation for it is not nearly as well tested and stable as the vhd one. |
Hi.
We're running the test program far below...
Basically ext filesystem on top of vhd...
For our ext vhd, we find that the ext vhd map has gaps in it (we are not sure if there is another bug causing this)...
There seem to be multiple bugs that cause us to end up in an infinite loop, with "toRead" value of 0, never making progress.
((1)) in DiscUtils\Library\DiscUtils.Ext\Extent.cs
The first bug is that many map entries have "NumBlocks" entries with the high bit (bit 15 of a ushort) set -- this seems very consistent and if we strip off that bit when reading data structures in from the underlying vhd, things are better. Otherwise, we totally goof the extent lengths as if we had many overlapping extents, which is impossible.
I think this code:
Needs to be:
Possibly the VHD format has changed to use this high bit for something?
((2)) in DiscUtils\Library\DiscUtils.Ext\ExtentsFileBuffer.cs
The second bug is when we return an extent from FindExtent() for a "gap" in the map, we return the previous extent (when the next extent starts after what we are looking for). Then the code in the parent function has a broken "if" that can never be true:
Inside this "if" is where we "clear" data rather than reading it from the underlying stream. I believe a quick examination of FindExtent() will show this code can never run today.
I believe this "if" should be:
Which would be an appropriate time to "clear" data rather than reading it...
((3)) in also DiscUtils\Library\DiscUtils.Ext\ExtentsFileBuffer.cs
Finally, the code that computes how much data to "clear" for a gap in the map computes an impossible (negative) number:
Given FindExtents returns the previous extent and not the next extent in the case of a gap, it is impossible to know how much is really safe to clear (without a much larger change)...
So the simplest fix here is to just iterate blocksize at a time:
Might this ring a bell for anyone???
Thank you!
-- Rich
Our test code is:
`
namespace DiscUtilsTestProject
{
using DiscUtils;
using DiscUtils.Ext;
using DiscUtils.Setup;
using System.IO;
}
`
The text was updated successfully, but these errors were encountered: