Takes extra precautions of flushing disk cache with autosave.

We must flush every time we save the content file, not only
the last time.
This commit is contained in:
Andrea Mazzoleni 2014-11-10 22:46:19 +01:00
parent b4469d379d
commit baef69c949
2 changed files with 29 additions and 1 deletions

View file

@ -877,6 +877,16 @@ int windows_fsync(int fd)
return -1;
}
/*
* "The FlushFileBuffers API can be used to flush all the outstanding data
* and metadata on a single file or a whole volume. However, frequent use
* of this API can cause reduced throughput. Internally, Windows uses the
* SCSI Synchronize Cache or the IDE/ATAPI Flush cache commands."
*
* From:
* "Windows Write Caching - Part 2 An overview for Application Developers"
* http://winntfs.com/2012/11/29/windows-write-caching-part-2-an-overview-for-application-developers/
*/
if (!FlushFileBuffers(h)) {
DWORD error = GetLastError();
@ -887,7 +897,7 @@ int windows_fsync(int fd)
* doesn't support buffering, like the console output.
*
* We had a report that also ATA-over-Ethernet returns
* this * error, but not enough sure to ignore it.
* this error, but not enough sure to ignore it.
* So, we use now an extended error reporting.
*/
fprintf(stderr, "Unexpected Windows INVALID_HANDLE error in FlushFileBuffers().\n");

View file

@ -959,6 +959,24 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
state_progress_stop(state);
printf("Autosaving...\n");
/* before writing the new content file we ensure that */
/* the parity is really written flushing the disk cache */
for (l = 0; l < state->level; ++l) {
ret = parity_sync(parity[l]);
if (ret == -1) {
/* LCOV_EXCL_START */
fprintf(stdlog, "parity_error:%u:%s: Sync error\n", i, lev_config_name(l));
fprintf(stderr, "DANGER! Unexpected sync error in %s disk.\n", lev_name(l));
fprintf(stderr, "Ensure that disk '%s' is sane and have some free space available.\n", lev_config_name(l));
printf("Stopping at block %u\n", i);
++error;
goto bail;
/* LCOV_EXCL_STOP */
}
}
/* now we can safely write the content file */
state_write(state);
state_progress_restart(state);