dafs: prevent corruption in large fsstate.dat files
authorMark Vitale <mvitale@sinenomine.net>
Wed, 13 Mar 2013 02:13:20 +0000 (22:13 -0400)
committerDerrick Brashear <shadow@your-file-system.com>
Tue, 26 Mar 2013 14:48:18 +0000 (07:48 -0700)
commit42351db75e04e46012208d38f80dc17be7ab776d
tree57822577604389220284ee32f50533b956336531
parente8faeae6dcae0e566de2b21d53d3f78f3cc44e3f
dafs: prevent corruption in large fsstate.dat files

If while writing to the fsstate.dat file, it exceeds the current
size of the file (multiples of FS_STATE_INIT_FILESIZE (8MiB)),
we call fs_stateResizeFile.  This un-mmaps, truncates, and
re-mmaps the file.  Unfortunately, fs_stateMapFile() resets the
state->mmap.offset and .cursor, so any writes in flight over
the resize will overwrite the first bytes of the file (and leave
zeros in the file where the data should have been written).

Upon return from the write that caused a file resize, the offset
is eventually corrected and the state dump continues with a
silent failure.  Eventually the state dump completes and the
file header is rewritten; this may conceal some or all of
the overwrite damage at offset 0.  However, any zeros near the 8MiB
offset (and its multiples) remain as corruption.

Add a flag to fs_stateMapFile() to allow the caller to specify if
the offset and cursor should be preserved.  Modify fs_stateResizeFile()
to use this capability.

testing note: temporarily reduced FS_STATE_INIT_FILESIZE to 256 bytes
during testing in order to make the problem easier to reproduce.
This problem would normally occur only on relatively large/active
DAFS fileservers.

Change-Id: I9b6c57ef7727837ae7cfc00d02192983355dad2b
Reviewed-on: http://gerrit.openafs.org/9599
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@your-file-system.com>
src/viced/serialize_state.c