Fixed ENOSPC issues with zero-granularity blocks

Result of testing on zero-granularity blocks, where the prog size and
read size equals the block size. This represents SD cards and other
traditional forms of block storage where we don't really get a benefit
from the metadata logging.

Unfortunately, since updates in both are tested by the same script,
we can't really use simple bash commands. Added a more complex
script to simulate corruption. Fortunately this should be more robust
than the previous solutions.

The main fixes were around corner cases where the commit logic fell
apart when it didn't have room to complete commits, but these were
fixable in the current design.
This commit is contained in:
Christopher Haster
2018-07-30 21:12:00 -05:00
parent 105907ba66
commit 1a58ba799c
4 changed files with 126 additions and 66 deletions

39
tests/corrupt.py Executable file
View File

@@ -0,0 +1,39 @@
#!/usr/bin/env python
import struct
import sys
import os
def main(*paths):
# find most recent block
file = None
rev = None
for path in paths:
try:
nfile = open(path, 'r+b')
nrev, = struct.unpack('<I', nfile.read(4))
assert rev != nrev
if not file or ((rev - nrev) & 0x80000000):
file = nfile
rev = nrev
except IOError:
pass
# go to last commit
tag = 0
while True:
try:
ntag, = struct.unpack('<I', file.read(4))
except struct.error:
break
tag ^= ntag
file.seek(tag & 0xfff, os.SEEK_CUR)
# lob off last 3 bytes
file.seek(-((tag & 0xfff) + 3), os.SEEK_CUR)
file.truncate()
if __name__ == "__main__":
main(*sys.argv[1:])