File Descriptor syncing in FSDirectory.cs:
Robert Jordan :
So the real question is: does MS.NET's FileStream.Flush() call
FlushFileBuffers() as well? If yes, the code above can be replaced
with a simple fs.Flush ().
Unfortunately FileStream.Flush() does not call FlushFileBuffers(), see :
- MS source code for FileStream
- an article at
http://research.microsoft.com/pubs/64538/tr-2004-136.pdf. It states:
"/The Flush() stream method returns when all that stream's .NET buffers
have been written to the file system. To force the file system write to
disk controller, you must call the FlushFileBuffers() Windows API . It
is likely that Flush()// will be overloaded to have a full-flush option
in the future/."
So, I think Sync method shoud call fs.Flush() *AND* FlushFileBuffers() :
public static void Sync(FileStream fs) {
fs.Flush(); // flush FileStream internal buffers
if (FlushFileBuffers(fs.SafeFileHandle) == 0) // force the
file system write to disk controller
{
throw new SyncFailedException();
}
}
=========
Andrei Iliev
Robert Jordan :
Digy wrote:
1) File Descriptor syncing in FSDirectory.cs
[System.Runtime.InteropServices.DllImport("kernel32")]
public static extern int
FlushFileBuffers(Microsoft.Win32.SafeHandles.SafeFileHandle
SafeFileHandle);
public static void Sync(FileStream fs)
{
if (FlushFileBuffers(fs.SafeFileHandle) == 0)
{
throw new SyncFailedException();
}
}
public class SyncFailedException : Exception
{
}
I am not sure about committing this patch. Since it uses
InteropServices,
It may cause problems on Mono.
When using Mono under Unix, calling FileStream.Flush() is sufficient
because this method eventually calls fsync(2)..
When using Mono under Windows, FileStream.Flush() will call
the FlushFileBuffers() Win32 API.
So the real question is: does MS.NET's FileStream.Flush() call
FlushFileBuffers() as well? If yes, the code above can be replaced
with a simple fs.Flush ().
Robert