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

FlushFileBuffers() vs FILE_FLAG_WRITE_THROUGH

1,541 views
Skip to first unread message

Steve Thresher

unread,
Dec 16, 2002, 11:36:34 AM12/16/02
to
We currently use FlushFileBuffers to ensure that writes to our data
protection log file are successful. I suggested we use the
FILE_FLAG_WRITE_THROUGH flag in the call to CreateFile() to achieve the same
result and increase performance but it didn't work. In a simple test of
writing out 10000 512byte records we did gain (50secs down to 40secs).
However if you run the same test and kill the power half way through a block
of garbage is written to the end of the file. The documentation for the
FILE_FLAG_WRITE_THROUGH flag implies it is designed to provide better data
integrity but in practice it is quite the opposite. Can anybody suggest
where the problem may lie or have any experience in optimising file access?


Karan Mehra [MS]

unread,
Dec 19, 2002, 3:45:48 AM12/19/02
to

"Steve Thresher" <steve.t...@ukonline.co.uk> wrote in message

Is the test platform Windows 2000 SP2 (or prior)? Is the HDD on an IDE bus or SCSI and is its write-cache enabled? The results will vary based on your response to these questions. Here is why :

There are two caches involved here. (a) The OS cache and (b) The HDD cache

1. FlushFileBuffers: This routine causes all sections of the file that are in the OS cache, to be written out the disk. This is then followed by a request to flush the entire HDD cache to oxide

The downside of (1) is that everything else in the HDD cache gets written out to media. This is because the OS cache manager might have lazily written out some sections of the file before this call. These sections might still reside in the HDD cache and there isn't a way to request the HDD to write-out only those parts

2. FILE_FLAG_WRITE_THROUGH: This flag causes all writes to be written-through both caches. This means that the OS cache manager and HDD firmware are most welcome to make a copy of the data in their cache, but they should ensure that by the time the request completes, the data has made it to the oxide

The downside of (2) is that if the write request isn't sector aligned, the OS cache manager needs to perform a read and follow it with a write. Also, the ATA spec does not define a way of requesting the HDD firmware to write-through its cache. So, essentially, on IDE drives, all writes get placed in the HDD cache

Further, because you are only writing out the data, the OS cache manager and the HDD firmware unnecessarily keep copies of the file in their respective caches. So, unless this file is going to be read too, this is an undesired side-effect (and FILE_FLAG_NO_BUFFERING might be useful, although it has alignment restrictions)

Finally, the OS is relevant because before Windows 2000 SP3, it conveniently forgot to query the write-cache setting on the HDD and hence assumed that it wasn't enabled. This means that the write-through requests went down as regular writes (not that this made a difference on IDE) and requests to flush the HDD cache (in response to the FlushFileBuffers), were dropped (kind of)

Hope this helps...

:)
karan

--
This posting is provided "AS IS" with no warranties, and confers no rights

steve....@veritas.com

unread,
Jan 15, 2003, 5:48:17 PM1/15/03
to
Karan,

Do you know how this applies to an optical scsi drive? We are suddenly
seeing delayed write errors when writing to a scsi optical drive in a
library. This is through a drive letter and using NTFS. We are using
W2K SP3 and we had not seen this prior to our SP3 update.

Thanks,
Steve

"Karan Mehra [MS]" <kar...@online.microsoft.com> wrote in message news:<uxCICszpCHA.2748@TK2MSFTNGP09>...


> "Steve Thresher" <steve.t...@ukonline.co.uk> wrote in message
> |
> | We currently use FlushFileBuffers to ensure that writes to our data
> | protection log file are successful. I suggested we use the

> | FILE FLAG WRITE THROUGH flag in the call to CreateFile() to achieve

> the same
> | result and increase performance but it didn't work. In a simple test
> of
> | writing out 10000 512byte records we did gain (50secs down to 40secs).
> | However if you run the same test and kill the power half way through a
> block
> | of garbage is written to the end of the file. The documentation for
> the

> | FILE FLAG WRITE THROUGH flag implies it is designed to provide better

> data
> | integrity but in practice it is quite the opposite. Can anybody
> suggest
> | where the problem may lie or have any experience in optimising file
> access?
> |
> |
>
> Is the test platform Windows 2000 SP2 (or prior)? Is the HDD on an IDE
> bus or SCSI and is its write-cache enabled? The results will vary based
> on your response to these questions. Here is why :
>
> There are two caches involved here. (a) The OS cache and (b) The HDD
> cache
>
> 1. FlushFileBuffers: This routine causes all sections of the file that
> are in the OS cache, to be written out the disk. This is then followed
> by a request to flush the entire HDD cache to oxide
>
> The downside of (1) is that everything else in the HDD cache gets
> written out to media. This is because the OS cache manager might have
> lazily written out some sections of the file before this call. These
> sections might still reside in the HDD cache and there isn't a way to
> request the HDD to write-out only those parts
>

> 2. FILE FLAG WRITE THROUGH: This flag causes all writes to be

> written-through both caches. This means that the OS cache manager and
> HDD firmware are most welcome to make a copy of the data in their cache,
> but they should ensure that by the time the request completes, the data
> has made it to the oxide
>
> The downside of (2) is that if the write request isn't sector aligned,
> the OS cache manager needs to perform a read and follow it with a write.
> Also, the ATA spec does not define a way of requesting the HDD firmware
> to write-through its cache. So, essentially, on IDE drives, all writes
> get placed in the HDD cache
>
> Further, because you are only writing out the data, the OS cache manager
> and the HDD firmware unnecessarily keep copies of the file in their
> respective caches. So, unless this file is going to be read too, this is

> an undesired side-effect (and FILE FLAG NO BUFFERING might be useful,

Karan Mehra [MS]

unread,
Jan 15, 2003, 9:14:10 PM1/15/03
to

Steve,
The system event log should have an Event ID 50 for every one of those {Delayed Write Failures}. These entries include the NTSTATUS failure code in the Data section, giving us a clue as to what might be causing the failure

Further, there should be a ton of entries from Disk (either Event ID 9, 11 or 51) containing the command that failed and the sense code (if any) returned by the drive

If you could obtain these events, I'd be happy to help interpret them...

Thanks!

--
karan

--
This posting is provided "AS IS" with no warranties, and confers no rights


<steve....@veritas.com> wrote in message


|
| Karan,
|
| Do you know how this applies to an optical scsi drive? We are suddenly
| seeing delayed write errors when writing to a scsi optical drive in a
| library. This is through a drive letter and using NTFS. We are using
| W2K SP3 and we had not seen this prior to our SP3 update.
|
| Thanks,
| Steve
|
| "Karan Mehra [MS]" <kar...@online.microsoft.com> wrote in message news:<uxCICszpCHA.2748@TK2MSFTNGP09>...
| >

steve....@veritas.com

unread,
Jan 17, 2003, 1:53:28 PM1/17/03
to
Karan,

Here is the event message that we received. Thanks for taking the time
to look at this.

Steve

{Lost Delayed-Write Data} The system was attempting to transfer file
data from buffers to
\Device\Harddisk2\DP(1)0-0+4.
The write operation failed, and only some of the data may have been
written to the file.

0000: 00040000 005a0001 00000000 80040032
0010: 00000000 00000000 00000000 00000000
0020: 00000000 00000000 c000009d

An error was detected on device \Device\Harddisk2\DR2 during a paging
operation.

0000: 04 00 22 00 01 00 72 00 .."...r.
0008: 00 00 00 00 33 00 04 80 ....3..?
0010: 2d 01 00 00 00 00 00 00 -.......
0018: 00 00 00 00 00 00 00 00 ........
0020: 00 c0 0f 27 00 00 00 00 .À.'....
0028: 00 00 00 00 03 00 00 00 ........
0030: 00 00 00 00 2a 00 00 00 ....*...
0038: 02 c4 00 00 00 29 06 00 .Ä...)..
0040: 2a 08 00 09 c3 f0 00 00 *...Ãð..
0048: 04 00

As Words:

0000: 00220004 00720001 00000000 80040033
0010: 0000012d 00000000 00000000 00000000
0020: 270fc000 00000000 00000000 00000003
0030: 00000000 0000002a 0000c402 00062900
0040: 0900082a 0000f0c3 0004


"Karan Mehra [MS]" <kar...@online.microsoft.com> wrote in message news:<#wiHrTQvCHA.1676@TK2MSFTNGP10>...

Karan Mehra [MS]

unread,
Jan 18, 2003, 10:25:02 PM1/18/03
to
The Data in an Event ID 51 conforms to the following structure :
 
[
typedef struct _IO_ERROR_LOG_PACKET { // Offset:
 
    UCHAR MajorFunctionCode;          // 0x00       0x04 = IRP_MJ_WRITE
    UCHAR RetryCount;                 // 0x01
    USHORT DumpDataSize;              // 0x02       0x0022 = cdb is present at the end
    USHORT NumberOfStrings;           // 0x04
    USHORT StringOffset;              // 0x06
    USHORT EventCategory;             // 0x08
                                      // 0x0a
    NTSTATUS ErrorCode;               // 0x0c       0x80040033 = IO_WARNING_PAGING_FAILURE
    ULONG UniqueErrorValue;           // 0x10
    NTSTATUS FinalStatus;             // 0x14
    ULONG SequenceNumber;             // 0x18
    ULONG IoControlCode;              // 0x1c
    LARGE_INTEGER DeviceOffset;       // 0x20
    ULONG DumpData;
                [0]                   // 0x28       0x00000000 = path
                [1]                   // 0x2c       0x00000003 = target
                [2]                   // 0x30       0x00000000 = lun
                [3]                   // 0x34           0x002a = SCSIOP_WRITE
                [4]                   // 0x38       0x0000c402 = SRB_STATUS_AUTOSENSE_VALID |
                                                                 SRB_STATUS_QUEUE_FROZEN    |
                                                                 SRB_STATUS_ERROR           |
                                                                 SCSISTAT_CHECK_CONDITION
                [5]                   // 0x3c       0x00062900 = SCSI_SENSE_UNIT_ATTENTION  |
                                                                 SCSI_ADSENSE_BUS_RESET
                [6]                   // 0x40       10 byte cdb, 2a 08 00 09 c3 f0 00 00 04 00
 
}IO_ERROR_LOG_PACKET, *PIO_ERROR_LOG_PACKET;
]
 
The WRITE10) cdb, command descriptor block, conforms to the following structure :
 
[
struct _CDB10 {

    UCHAR OperationCode;                            0x2a
    UCHAR RelativeAddress       : 1;                  0b
    UCHAR Reserved1             : 2;                 00b
    UCHAR ForceUnitAccess       : 1;                  1b
    UCHAR DisablePageOut        : 1;                  0b
    UCHAR LogicalUnitNumber     : 3;                000b
    UCHAR LogicalBlockByte0;                        0x00
    UCHAR LogicalBlockByte1;                        0x09
    UCHAR LogicalBlockByte2;                        0xc3
    UCHAR LogicalBlockByte3;                        0xf0
    UCHAR Reserved2;                                0x00
    UCHAR TransferBlocksMsb;                        0x00
    UCHAR TransferBlocksLsb;                        0x04
    UCHAR Control;                                  0x00

} CDB10;
]
 
The above request was to "write-through" to 4 sectors starting from sector #639984. Quite possibly the drive timed out and we reset the bus. Given that this did not happen on Windows 2000 SP2, I would like you to try the following :
 
1. Turn OFF the write-cache (under the Disk Properties tab via Device Manager). Go back and make sure that it is OFF. Now see if the {Delayed Writes Failures} continue to show up
 
2. Under Windows 2000 SP2, turn OFF the write-cache, hit OK. Go back and turn it ON. Now see if the failures show up
 
Let me know how this goes...
 
:)
karan
 
--
This posting is provided "AS IS" with no warranties, and confers no rights
 
<steve....@veritas.com> wrote in message
|
| Karan,
|
0 new messages