picrap / ExFat

exFAT read/write
MIT License
8 stars 5 forks source link

disk corruption issues #6

Open chrisrob5349 opened 7 years ago

chrisrob5349 commented 7 years ago

Hello,

A couple of problems I encountered while using ExFat.DiscUtils with a vmdk virtual disk formatted ExFat:

  1. The below code was used to copy files placed in a host directory to an empty directory in a VM. Then, we power on the VM ,delete the files from the VM manually via file explorer, then power off the VM. Doing this a couple of times (copying files to VM then deleting them and re-copying) with lots of files or directories causes disk corruption. Specifically, fill the host directory with 300-400 files, execute the given code, then delete the files copied into the VM (manually). After repeating this a couple of times the file system becomes corrupted. This has been reproduced a couple of times but seems a bit random.

  2. Copying an empty file (can be done with the below code) causes disk corruption. It seems this happens every time we copy empty files.

Code used:

private static void Test(string vmdkPath, int partitionNumber, string pathInHost, string pathInVm)
{
    using (VirtualDisk disk = new DiscUtils.Vmdk.Disk(vmdkPath,FileAccess.ReadWrite))
    using (ExFatFileSystem fs = new ExFatFileSystem(disk.partitions[partitionNumber].Open()))
    {
        string[] hostDirFilePaths= Directory.GetFiles(pathInHost, "*.*", SearchOption.TopDirectoryOnly);

        foreach (string hostFilePath in hostDirFilePaths)
        {
            string vmFilePath = Path.Combine(pathInVm, Path.GetFileName(hostFilePath));

            string dst = Path.Combine(fs.Root.FullName, vmFilePath);

            using (Stream dstStream = fs.OpenFile(dst, FileMode.Create, FileAccess.ReadWrite))
            using (Stream sourceStream = File.Open(hostFilePath, FileMode.Open, FileAccess.Read))
            {
                CoptStream(sourceStream, dstStream);
            }
        }
    }
}

private static void CopyStream(Stream srcStream, Stream dstStream)
{
    int bufferLength = (int)Math.Min(srcStream.Length, 4*1024*1024);
    byte[] buffer = new byte[bufferLength];
    int bytesRead= 0;

    while((bytesRead = srcStream.Read(buffer,0,bufferLength))>0)
    {
        dstStream.Write(buffer,0,bytesRead);
        if(bytesRead < bufferLength)
        {
            break;
        }
    }
}

Thanks, Chris

picrap commented 7 years ago

It sure looks like a bug. I'll take a look at it.

picrap commented 7 years ago

I guess that creating an empty file causes the same problem too.

picrap commented 7 years ago

Regarding problem 1. If you find a way to reproduce it all the time, I'm interested. Also, if you have a chkdsk log explaining it, I'm also interested.

picrap commented 7 years ago

@chrisrob5349 a version 0.9.9 was released and fixes empty files error. However I need to search more regarding your random error, so any reproductible code is very welcome 😄

picrap commented 7 years ago

I added a test named RandomReadWriteTest in class EntryFilesystemWriteTests: it randomly adds and removes files, but does not seem to fail (the .vhdx in checked by chkdsk after test). So if you find something to help, it will help 😉

chrisrob5349 commented 6 years ago

Hi, Appreciate the fast response!

I've looked into it again, and it seems creating files does work fine. It seems the corruption happened because the following two lines from my code snippet: using (VirtualDisk disk = new DiscUtils.Vmdk.Disk(vmdkPath,FileAccess.ReadWrite)) using (ExFatFileSystem fs = new ExFatFileSystem(disk.partitions[partitionNumber].Open()))

were originally (same but without the using statements): VirtualDisk disk = new DiscUtils.Vmdk.Disk(vmdkPath,FileAccess.ReadWrite) ExFatFileSystem fs = new ExFatFileSystem(disk.partitions[partitionNumber].Open())

So it seems that not properly disposing the VirtualDisk, ExFatFileSystem objects causes corruptions.

In addition, I am getting corruptions when copying directories from host to VM. I am getting these when copying simple directories like empty directories or directories with only a few files inside. Chkdsk results arent informative, typically being "Corruption was found while examining files and directories". If you could test moving\creating directories, It would be great. Anyways, I will try to pinpoint my errors and find reproducible code.

Thanks!

picrap commented 6 years ago

That's the opposite: not disposing the disk will cause corruption. There is a new version 0.9.10 released, you can already use it. Now I am going to implement move tests.