Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

FlushFileBuffers to commit file creation and/or move ?

609 views
Skip to first unread message

Xavier Roche

unread,
Mar 8, 2013, 2:41:10 AM3/8/13
to
Hi folks,

FlushFileBuffers() allows to flush pending write buffers to disk
[assuming that no write-through cache is enabled], similarly as
fdatasync() would do on POSIX platforms.

Is it sufficient to ensure that a file entry has been committed too ?

Ie. on a more general case, if the file is renamed (MoveFile() and
MoveFileEx()) afterwards, what guarantee that the actual move operation
has been commited ?

I am wondering between these three possibilities:
- Do nothing (if MoveFile() is waiting for the data to be committed)
- Reopen the file and execute FlushFileBuffers()
- Open the directory container and execute a FlushFileBuffers() on it
(does it require specific access rights ?)

I could not find any clear answer digging into the MSDN.

Thanks in advance for any hint!

Deanna Earley

unread,
Mar 8, 2013, 4:40:31 AM3/8/13
to
On 08/03/2013 07:41, Xavier Roche wrote:
> Hi folks,
>
> FlushFileBuffers() allows to flush pending write buffers to disk
> [assuming that no write-through cache is enabled], similarly as
> fdatasync() would do on POSIX platforms.
>
> Is it sufficient to ensure that a file entry has been committed too ?
>
> Ie. on a more general case, if the file is renamed (MoveFile() and
> MoveFileEx()) afterwards, what guarantee that the actual move operation
> has been commited ?

There is no guarantee.
There are multiple levels of buffering, but Windows/NTFS will try its
best to make sure everything is committed or at least written to the
journal.

It's best not to second guess Windows and just tell it to do the file
operation and leave it.

--
Deanna Earley (dee.e...@icode.co.uk)
iCatcher Development Team
http://www.icode.co.uk/icatcher/

iCode Systems

(Replies direct to my email address will be ignored. Please reply to the
group.)

Rick C. Hodgin

unread,
Mar 8, 2013, 1:22:39 PM3/8/13
to
Hi Xavier.

The operating system will guarantee that from the order in which you request things, they have (logically) happened in that order. However, there is no guarantee that the mechanics of actually executing the thing has yet occurred.

As the other poster indicates, these are controlled by multiple levels of buffering and you cannot know for sure that anything has been done, even if all outward signs indicate it has been done.

The easiest way to recognize this limitation is the caching hard drive controller. Even to Windows at this point it may seem as though the data has been thoroughly and completely flushed to disk (all writes written, all directories updated, all buffers flushed) ... yet the hard drive itself has not written them to disk yet.

There are no guarantees.

Bottom line: Do your utmost to follow protocol, and rely on the system to do its job for you. The safest assurance you have is to use all of these methods along with a UPS on local resources. And for network requests, to store all such communications in a private cache until such time as (through your own response protocol) you receive confirmation of the equivalent levels of hardware commit on the remote resource.

It's all we can do (hope, basically... :-))

Best regards,
Rick C. Hodgin

Xavier Roche

unread,
Mar 8, 2013, 1:37:44 PM3/8/13
to
Le 08/03/2013 19:22, Rick C. Hodgin a écrit :
> The operating system will guarantee that from the order in which you request things, they have (logically) happened in that order. However, there is no guarantee that the mechanics of actually executing the thing has yet occurred.

Does it means that CreateFile+WriteFile+FlushFileBuffers+CloseHandle
actually guarantee that the file creation will be committed before the
data sync is fulfilled ? I could not find any clear answer in MSDN
library pages for that, unfortunately.

> As the other poster indicates, these are controlled by multiple levels of buffering and you cannot know for sure that anything has been done, even if all outward signs indicate it has been done.

Modern disks/controllers should be able to expose proper barrier flushes
; so the caching issue *should* not be a problem.
http://monolight.cc/2011/06/barriers-caches-filesystems/

An operating system is supposed to know how to properly sync data
permanently on disk, whatever the situation is (multiple caches, RAID
with or without battery, etc.)

> The easiest way to recognize this limitation is the caching hard drive controller. Even to Windows at this point it may seem as though t

Yes, but in this case:
* the RAID controller is battery-backed, and can safely delay disk write
* the RAID controller is NOT battery-backed, and must fulfill sync requests

As far as I understand, the FlushFileBuffers WIN32 function guarantee
that for the data - but there is no indication whether or not this is
also valid for filenames (ie. directory entries).


Charlie Gibbs

unread,
Mar 8, 2013, 2:27:13 PM3/8/13
to
In article <khcbmd$532$1...@speranza.aioe.org>, dee.e...@icode.co.uk
(Deanna Earley) writes:

> On 08/03/2013 07:41, Xavier Roche wrote:
>
>> Hi folks,
>>
>> FlushFileBuffers() allows to flush pending write buffers to disk
>> [assuming that no write-through cache is enabled], similarly as
>> fdatasync() would do on POSIX platforms.
>>
>> Is it sufficient to ensure that a file entry has been committed too ?
>>
>> Ie. on a more general case, if the file is renamed (MoveFile()
>> and MoveFileEx()) afterwards, what guarantee that the actual move
>> operation has been commited ?
>
> There is no guarantee.
> There are multiple levels of buffering, but Windows/NTFS will try its
> best to make sure everything is committed or at least written to the
> journal.
>
> It's best not to second guess Windows and just tell it to do the file
> operation and leave it.

I don't know whether it's related, but I've occasionally run into
problems when deleting and renaming files. When updating a file
I'll often copy it to a work file, making changes as I go. At end
of file I close the files, unlink the original file, and rename
the work file to the original file. Once in a while, the process
fails. I suspect that the original file doesn't get deleted in
time, causing the rename to fail. It doesn't happen often, but
when you have software running daily in a couple of thousand sites,
even a 0.01% failure rate results in one anguished customer a week
complaining that he's lost a critical configuration file.

I did a bit of reading on what Microsoft calls "file system tunneling"
and almost lost my lunch. I've concluded that under Windows, any
delete/rename process is inherently unreliable; I've replaced all
such code in all of my software with a straight copying of the
work file back over the original file. It's less efficient,
but at least it's reliable.

--
/~\ cgi...@kltpzyxm.invalid (Charlie Gibbs)
\ / I'm really at ac.dekanfrus if you read it the right way.
X Top-posted messages will probably be ignored. See RFC1855.
/ \ HTML will DEFINITELY be ignored. Join the ASCII ribbon campaign!

Rick C. Hodgin

unread,
Mar 8, 2013, 3:22:58 PM3/8/13
to
On Friday, March 8, 2013 1:37:44 PM UTC-5, Xavier Roche wrote:
> Le 08/03/2013 19:22, Rick C. Hodgin a écrit :
> > The operating system will guarantee that from the order in which you request things, they have (logically) happened in that order. However, there is no guarantee that the mechanics of actually executing the thing has yet occurred.
>
>
>
> Does it means that CreateFile+WriteFile+FlushFileBuffers+CloseHandle
> actually guarantee that the file creation will be committed before the
> data sync is fulfilled ? I could not find any clear answer in MSDN
> library pages for that, unfortunately.

No. It means that any process which was actively reading that file handle could not retrieve all of the data (it's been made public and is not in internal buffers), but it does not guarantee that it is on the disk.

> > As the other poster indicates, these are controlled by multiple levels of buffering and you cannot know for sure that anything has been done, even if all outward signs indicate it has been done.
>
> Modern disks/controllers should be able to expose proper barrier flushes
> ; so the caching issue *should* not be a problem.
> http://monolight.cc/2011/06/barriers-caches-filesystems/

There is no guarantee of this. Users have the option of setting up their hard drives to any type of cache setting for their own personal reasons. If you are dealing with a server machine, then you have more control over its settings. But if you're dealing with users ... out there ... somewhere ... running your apps ... they you cannot take anything for granted.

They make controllers that write to entire RAM disks, for example, that have no permanent storage outside of power being supplied to them (battery backups usually, but no guarantee even then).

> An operating system is supposed to know how to properly sync data
> permanently on disk, whatever the situation is (multiple caches, RAID
> with or without battery, etc.)

When you communicate across a wire you go through a protocol. So long as the remote device responds appropriately to that protocol, you can make assumptions. But the question then becomes: Did the remote device actually do what it said? In the case of caching disk controllers, or physical disks themselves ... you'll never know for sure unless you can query them directly through their driver ... and even then you'll never know for sure.

> > The easiest way to recognize this limitation is the caching hard drive controller. Even to Windows at this point it may seem as though t
>
>
> Yes, but in this case:
> * the RAID controller is battery-backed, and can safely delay disk write
> * the RAID controller is NOT battery-backed, and must fulfill sync requests
>
> As far as I understand, the FlushFileBuffers WIN32 function guarantee
> that for the data - but there is no indication whether or not this is
> also valid for filenames (ie. directory entries).

There is no guarantee at any time that the files have actually been written to disk. The OS can report that everything has been flushed, and it may have actually flushed them, but you cannot categorically assume that condition is true because of many variables which exists between your request and the physical bit layer on the drive.

Follow protocol. Go UPS. Do everything you can ... and then you've done everything you can.

Rick C. Hodgin

unread,
Mar 8, 2013, 3:25:27 PM3/8/13
to
> > Does it means that CreateFile+WriteFile+FlushFileBuffers+CloseHandle
> > actually guarantee that the file creation will be committed before the
> > data sync is fulfilled ? I could not find any clear answer in MSDN
> > library pages for that, unfortunately.
>

Should be:

No. It means that any process which was actively reading that file handle could ___NOW___ retrieve all of the data (it's been made public and is not in internal buffers), but it does not guarantee that it is on the disk.

Deanna Earley

unread,
Mar 11, 2013, 5:10:11 AM3/11/13
to
On 08/03/2013 19:27, Charlie Gibbs wrote:
> I don't know whether it's related, but I've occasionally run into
> problems when deleting and renaming files. When updating a file
> I'll often copy it to a work file, making changes as I go. At end
> of file I close the files, unlink the original file, and rename
> the work file to the original file. Once in a while, the process
> fails. I suspect that the original file doesn't get deleted in
> time, causing the rename to fail.

Have you ruled out anythign else trying to access the file?
Antivirus applications are notorious for getting in the way of other
applications.

Xavier Roche

unread,
Mar 11, 2013, 5:51:00 AM3/11/13
to
On 03/11/2013 10:10 AM, Deanna Earley wrote:
> Have you ruled out anythign else trying to access the file?
> Antivirus applications are notorious for getting in the way of other
> applications.

Yep. Basically, if MoveFileEx() fails with errors (GetLastError()) such
as ERROR_FILE_EXISTS, ERROR_ALREADY_EXISTS or ERROR_SHARING_VIOLATION,
you probably want to sleep a little (!), and retry. (ie. even when using
MOVEFILE_REPLACE_EXISTING and MOVEFILE_WRITE_THROUGH flags)

[ But I have seen really strange bugs around move operations (sometimes
when a directory is involves) and not obviously related to any
antivirus. I strongly suspect some operations not to be coherent over
time (ie. create and delete immediately a directory may fail ?), but I
never found any clear case. ]

0 new messages