diff options
-rw-r--r-- | lfs.c | 35 | ||||
-rwxr-xr-x | tests/corrupt.py | 2 | ||||
-rwxr-xr-x | tests/debug.py | 12 |
3 files changed, 27 insertions, 22 deletions
@@ -385,7 +385,7 @@ static inline uint16_t lfs_tag_type(uint32_t tag) { } static inline uint16_t lfs_tag_subtype(uint32_t tag) { - return (tag & 0x7c000000) >> 22; + return ((tag & 0x7c000000) >> 26) << 4; } static inline uint16_t lfs_tag_id(uint32_t tag) { @@ -470,7 +470,7 @@ static int32_t lfs_commit_get(lfs_t *lfs, lfs_block_t block, lfs_off_t off, while (off >= 2*sizeof(tag)+lfs_tag_size(tag)) { off -= sizeof(tag)+lfs_tag_size(tag); - if (lfs_tag_type(tag) == LFS_TYPE_CRC && stopatcommit) { + if (lfs_tag_subtype(tag) == LFS_TYPE_CRC && stopatcommit) { break; } else if (lfs_tag_type(tag) == LFS_TYPE_DELETE) { if (lfs_tag_id(tag) <= lfs_tag_id(gettag + getdiff)) { @@ -502,6 +502,7 @@ static int32_t lfs_commit_get(lfs_t *lfs, lfs_block_t block, lfs_off_t off, return err; } tag ^= lfs_fromle32(ntag); + tag &= 0x7fffffff; } return LFS_ERR_NOENT; @@ -632,8 +633,7 @@ static int lfs_commit_move(lfs_t *lfs, struct lfs_commit *commit, return err; } - ntag = lfs_fromle32(ntag); - ntag ^= tag; + ntag = lfs_fromle32(ntag) ^ tag; tag |= 0x80000000; } @@ -687,7 +687,7 @@ static int lfs_commit_crc(lfs_t *lfs, struct lfs_commit *commit) { lfs->cfg->prog_size); // read erased state from next program unit - uint32_t tag = 0; + uint32_t tag; int err = lfs_bd_read(lfs, &lfs->pcache, &lfs->rcache, sizeof(tag), commit->block, off, &tag, sizeof(tag)); @@ -696,10 +696,9 @@ static int lfs_commit_crc(lfs_t *lfs, struct lfs_commit *commit) { } // build crc tag - tag = lfs_fromle32(tag); - tag = (0x80000000 & ~tag) | - LFS_MKTAG(LFS_TYPE_CRC, 0x3ff, - off - (commit->off+sizeof(uint32_t))); + bool reset = ~lfs_fromle32(tag) >> 31; + tag = LFS_MKTAG(LFS_TYPE_CRC + reset, + 0x3ff, off - (commit->off+sizeof(uint32_t))); // write out crc uint32_t footer[2]; @@ -713,7 +712,7 @@ static int lfs_commit_crc(lfs_t *lfs, struct lfs_commit *commit) { return err; } commit->off += sizeof(tag)+lfs_tag_size(tag); - commit->ptag = tag; + commit->ptag = tag ^ (reset << 31); // flush buffers err = lfs_bd_sync(lfs, &lfs->pcache, &lfs->rcache, false); @@ -774,7 +773,7 @@ static int lfs_dir_alloc(lfs_t *lfs, lfs_mdir_t *dir) { // set defaults dir->off = sizeof(dir->rev); - dir->etag = 0; + dir->etag = 0xffffffff; dir->count = 0; dir->tail[0] = 0xffffffff; dir->tail[1] = 0xffffffff; @@ -817,7 +816,7 @@ static int32_t lfs_dir_fetchmatch(lfs_t *lfs, // load blocks and check crc for (int i = 0; i < 2; i++) { lfs_off_t off = sizeof(dir->rev); - uint32_t ptag = 0; + uint32_t ptag = 0xffffffff; uint32_t crc = 0xffffffff; dir->rev = lfs_tole32(rev[0]); @@ -851,8 +850,8 @@ static int32_t lfs_dir_fetchmatch(lfs_t *lfs, tag = lfs_fromle32(tag) ^ ptag; // next commit not yet programmed - if (lfs_tag_type(ptag) == LFS_TYPE_CRC && !lfs_tag_isvalid(tag)) { - dir->erased = true; + if (!lfs_tag_isvalid(tag)) { + dir->erased = (lfs_tag_subtype(ptag) == LFS_TYPE_CRC); break; } @@ -862,7 +861,7 @@ static int32_t lfs_dir_fetchmatch(lfs_t *lfs, break; } - if (lfs_tag_type(tag) == LFS_TYPE_CRC) { + if (lfs_tag_subtype(tag) == LFS_TYPE_CRC) { // check the crc attr uint32_t dcrc; err = lfs_bd_read(lfs, @@ -882,6 +881,10 @@ static int32_t lfs_dir_fetchmatch(lfs_t *lfs, break; } + // reset the next bit if we need to + tag ^= (lfs_tag_type(tag) & 1) << 31; + + // update with what's found so far foundtag = tempfoundtag; dir->off = off + sizeof(tag)+lfs_tag_size(tag); dir->etag = tag; @@ -1096,7 +1099,7 @@ commit: // setup commit state commit.off = 0; commit.crc = 0xffffffff; - commit.ptag = 0; + commit.ptag = 0xffffffff; // space is complicated, we need room for tail, crc, globals, // cleanup delete, and we cap at half a block to give room diff --git a/tests/corrupt.py b/tests/corrupt.py index 5e2a9a3..9b5d4bd 100755 --- a/tests/corrupt.py +++ b/tests/corrupt.py @@ -11,7 +11,7 @@ def corrupt(block): file.read(4) # go to last commit - tag = 0 + tag = 0xffffffff while True: try: ntag, = struct.unpack('<I', file.read(4)) diff --git a/tests/debug.py b/tests/debug.py index 65b0ad0..117416a 100755 --- a/tests/debug.py +++ b/tests/debug.py @@ -12,7 +12,7 @@ TYPES = { (0x1f0, 0x080): 'globals', (0x1ff, 0x0c0): 'tail soft', (0x1ff, 0x0c1): 'tail hard', - (0x1ff, 0x0f0): 'crc', + (0x1f0, 0x0f0): 'crc', (0x1ff, 0x040): 'struct dir', (0x1ff, 0x041): 'struct inline', (0x1ff, 0x042): 'struct ctz', @@ -63,7 +63,7 @@ def main(*blocks): print "%-4s %-8s %-14s %3s %3s %s" % ( 'off', 'tag', 'type', 'id', 'len', 'dump') - tag = 0 + tag = 0xffffffff off = 4 while True: try: @@ -79,23 +79,25 @@ def main(*blocks): type = (tag & 0x7fc00000) >> 22 id = (tag & 0x003ff000) >> 12 size = (tag & 0x00000fff) >> 0 + iscrc = (type & 0x1f0) == 0x0f0 data = file.read(size) - if type == 0x0f0: + if iscrc: crc = binascii.crc32(data[:4], crc) else: crc = binascii.crc32(data, crc) print '%04x: %08x %-14s %3s %3d %-23s %-8s' % ( off, tag, - typeof(type) + (' bad!' if type == 0x0f0 and ~crc else ''), + typeof(type) + (' bad!' if iscrc and ~crc else ''), id if id != 0x3ff else '.', size, ' '.join('%02x' % ord(c) for c in data[:8]), ''.join(c if c >= ' ' and c <= '~' else '.' for c in data[:8])) off += tag & 0xfff - if type == 0x0f0: + if iscrc: crc = 0 + tag ^= (type & 1) << 31 return 0 |