[comp.os.msdos.programmer] Flushing and Database Integrity

kid@hpctdkg.HP.COM (Kevin Dietz) (12/05/90)

Hi,

This is a follow-up note to Turbo C++ fopen() and fflush().  I have
read all of the posted responses and understand the issues involved.
The question I have involves how DOS manipulates its internal buffers,
specifically, does DOS guarentee that file writes are performed in
the same order as the original write operations from the C program
when the file is closed/flushed?  The reason for this is that I am
trying to develop algorithms that will insure the integrity of a database,
but everything I come up with seems to have this requirement.

For example, lets say I have a file of fixed sized records with a small
area reserved at the beginning of the file for header-type information.
To guard against the file becoming corrupt due to a power failure during
a write-record operation, I could set a flag in the header, write the
record, then reset the flag, then flush everything.  The code sequence
is essentially:

	seek(...);
	write(...);  /* write #1, set header flag */
	seek(...);
	write(...);  /* write #2, write the record */
	seek(...);
	write(...);  /* write #3, reset the header flag */
	flush(...);  /* make sure its written to disk */

Note I'm using "flush()" as a generic routine that flushes all buffers
(C and DOS) to the physical disk.  

Whenever I open the database, I can check the flag to determine
if the file is corrupt.  

However, if DOS buffers this file such that the header is in Buffer 1,
and the record I'm writing is in Buffer 2, then write #3 could overwrite
write #1 within Buffer 1 before Buffer 1 was ever written to disk, and
if the flush/close operation wrote Buffer 1 followed by Buffer 2, and
a power failure occurred writing Buffer 2, then the header flag would
be reset even though the file was corrupt.

So is this a scenario I have to worry about, or does DOS guarentee this
won't happen by flushing buffers in such a way that the data is written
in the correct order?  It seems plausible that DOS could write buffers
in the order they were written to, and flush a buffer before accepting
a second write into that buffer, thus guarenteeing the ordering.  This
does seem like a reasonable requirement for an OS.

If not, one obvious solution is to insert flush() calls after write #1
and write #2, but this would degrade performance.

If anyone has solutions for guarenteeing database integrity that you
would like to share, I would appreciate hearing from you (I've used
the above algorithm for the purposes of this discussion, and do not
claim it to be the best solution).

Thanks,

Kevin Dietz

ekalenda@cup.portal.com (Edward John Kalenda) (12/06/90)

Kevin Dietz writes:
> This is a follow-up note to Turbo C++ fopen() and fflush().  I have
> read all of the posted responses and understand the issues involved.
> The question I have involves how DOS manipulates its internal buffers,
> specifically, does DOS guarentee that file writes are performed in
> the same order as the original write operations from the C program
> when the file is closed/flushed?  The reason for this is that I am
> trying to develop algorithms that will insure the integrity of a database,
> but everything I come up with seems to have this requirement.

The DOS buffers are used as a write-through cache so the order or disk
writes will always be the same as calls to DOS to write a disk block.
This statement is based on claims made in the MS-DOS Encyclopedia where
it discusses the BUFFER statement in the config.sys file. Reading about
the commit system call (int 21h function 68h) says it forces all buffers
for the file to be written and updates the FAT and directory data.

BUFFERS docs say there are no dirty buffers, commit docs imply there might
be. I'd call the commit function anytime I'm worried about file integrity.

Ed
ekalenda@cup.portal.com