mirror of
https://gitee.com/openharmony/third_party_littlefs
synced 2025-02-13 03:40:50 +00:00
![Christopher Haster](/assets/img/avatar_default.png)
Currently unused, the insertion of new file entries in arbitrary locations in a metadata-pair is very easy to add into the existing metadata logging. The only tricky things: 1. Name tags must strictly precede any tags related to a file. We can pull this off during a compact, but must make two passes. One for the name tag, one for the file. Though a benefit of this is that now our scans during moves can exit early upon finding the name tag. 1. We need to handle name tags appearing out of order. This makes name tags symmetric to deletes, although it doesn't seem like we can leverage this fact very well. Note this also means we need to make the superblock tag a type of name tag.
107 lines
2.8 KiB
Python
Executable File
107 lines
2.8 KiB
Python
Executable File
#!/usr/bin/env python2
|
|
|
|
import struct
|
|
import binascii
|
|
|
|
TYPES = {
|
|
(0x1ff, 0x002): 'reg',
|
|
(0x1ff, 0x003): 'dir',
|
|
(0x1ff, 0x001): 'superblock',
|
|
(0x1ff, 0x000): 'root',
|
|
(0x1ff, 0x020): 'delete',
|
|
(0x1f0, 0x0e0): 'globals',
|
|
(0x1ff, 0x080): 'tail soft',
|
|
(0x1ff, 0x081): 'tail hard',
|
|
(0x1f0, 0x0a0): 'crc',
|
|
(0x1ff, 0x040): 'struct dir',
|
|
(0x1ff, 0x041): 'struct inline',
|
|
(0x1ff, 0x042): 'struct ctz',
|
|
(0x100, 0x100): 'attr',
|
|
}
|
|
|
|
def typeof(type):
|
|
for prefix in range(9):
|
|
mask = 0x1ff & ~((1 << prefix)-1)
|
|
if (mask, type & mask) in TYPES:
|
|
return TYPES[mask, type & mask] + (
|
|
' [%0*x]' % (prefix/4, type & ((1 << prefix)-1))
|
|
if prefix else '')
|
|
else:
|
|
return '[%02x]' % type
|
|
|
|
def main(*blocks):
|
|
# find most recent block
|
|
file = None
|
|
rev = None
|
|
crc = None
|
|
versions = []
|
|
|
|
for block in blocks:
|
|
try:
|
|
nfile = open(block, 'rb')
|
|
ndata = nfile.read(4)
|
|
ncrc = binascii.crc32(ndata)
|
|
nrev, = struct.unpack('<I', ndata)
|
|
|
|
assert rev != nrev
|
|
if not file or ((rev - nrev) & 0x80000000):
|
|
file = nfile
|
|
rev = nrev
|
|
crc = ncrc
|
|
|
|
versions.append((nrev, '%s (rev %d)' % (block, nrev)))
|
|
except (IOError, struct.error):
|
|
pass
|
|
|
|
if not file:
|
|
print 'Bad metadata pair {%s}' % ', '.join(blocks)
|
|
return 1
|
|
|
|
print "--- %s ---" % ', '.join(v for _,v in sorted(versions, reverse=True))
|
|
|
|
# go through each tag, print useful information
|
|
print "%-4s %-8s %-14s %3s %3s %s" % (
|
|
'off', 'tag', 'type', 'id', 'len', 'dump')
|
|
|
|
tag = 0xffffffff
|
|
off = 4
|
|
while True:
|
|
try:
|
|
data = file.read(4)
|
|
crc = binascii.crc32(data, crc)
|
|
ntag, = struct.unpack('<I', data)
|
|
except struct.error:
|
|
break
|
|
|
|
tag ^= ntag
|
|
off += 4
|
|
|
|
type = (tag & 0x7fc00000) >> 22
|
|
id = (tag & 0x003ff000) >> 12
|
|
size = (tag & 0x00000fff) >> 0
|
|
iscrc = (type & 0x1f0) == 0x0f0
|
|
|
|
data = file.read(size)
|
|
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 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 iscrc:
|
|
crc = 0
|
|
tag ^= (type & 1) << 31
|
|
|
|
return 0
|
|
|
|
if __name__ == "__main__":
|
|
import sys
|
|
sys.exit(main(*sys.argv[1:]))
|