Added mlimit to the superconfig, dropped mtreelimit
This should be stored in the superconfig, and we should use it during mount instead of rederiving it from the block_size (TODO). Note that this stores the "mlimit", (1 << mbits)-1, not the mbits directly. littlefs will probably always be limited to powers-of-two for this, since mbits is fairly arbitrary, but storing the expanded value allows for non-powers-of-two _just in case_.
This commit is contained in:
@@ -6235,15 +6235,16 @@ static lfsr_data_t lfsr_data_fromsuperconfig(lfs_t *lfs,
|
|||||||
LFS_ASSERT(d_ >= 0);
|
LFS_ASSERT(d_ >= 0);
|
||||||
d += d_;
|
d += d_;
|
||||||
|
|
||||||
|
// on-disk mlimit
|
||||||
|
lfsr_mid_t mlimit = lfsr_mweight(lfs)-1;
|
||||||
|
d_ = lfs_toleb128(mlimit, &buffer[d], 5);
|
||||||
|
LFS_ASSERT(d_ >= 0);
|
||||||
|
d += d_;
|
||||||
|
|
||||||
// on-disk utag limit
|
// on-disk utag limit
|
||||||
buffer[d] = 0x7f;
|
buffer[d] = 0x7f;
|
||||||
d += 1;
|
d += 1;
|
||||||
|
|
||||||
// on-disk mtree limit
|
|
||||||
d_ = lfs_toleb128(0x7fffffff, &buffer[d], 5);
|
|
||||||
LFS_ASSERT(d_ >= 0);
|
|
||||||
d += d_;
|
|
||||||
|
|
||||||
// on-disk attr limit
|
// on-disk attr limit
|
||||||
d_ = lfs_toleb128(0x7fffffff, &buffer[d], 5);
|
d_ = lfs_toleb128(0x7fffffff, &buffer[d], 5);
|
||||||
LFS_ASSERT(d_ >= 0);
|
LFS_ASSERT(d_ >= 0);
|
||||||
@@ -6432,6 +6433,21 @@ static int lfsr_mountinited(lfs_t *lfs) {
|
|||||||
return LFS_ERR_INVAL;
|
return LFS_ERR_INVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check the on-disk mtree limit
|
||||||
|
// TODO actually use this
|
||||||
|
lfsr_mid_t mlimit;
|
||||||
|
err = lfsr_data_readleb128(lfs, &data, (int32_t*)&mlimit);
|
||||||
|
// treat any leb128 overflows as out-of-range values
|
||||||
|
if (err && err != LFS_ERR_CORRUPT) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err == LFS_ERR_CORRUPT || mlimit != lfsr_mweight(lfs)-1) {
|
||||||
|
LFS_ERROR("Incompatible mlimit 0x%"PRIx32,
|
||||||
|
(err ? (lfsr_mid_t)-1 : mlimit));
|
||||||
|
return LFS_ERR_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
// check the on-disk utag limit
|
// check the on-disk utag limit
|
||||||
// TODO actually use this
|
// TODO actually use this
|
||||||
int32_t utag_limit;
|
int32_t utag_limit;
|
||||||
@@ -6449,23 +6465,6 @@ static int lfsr_mountinited(lfs_t *lfs) {
|
|||||||
return LFS_ERR_INVAL;
|
return LFS_ERR_INVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the on-disk mtree limit
|
|
||||||
// TODO actually use this
|
|
||||||
lfsr_smid_t mtree_limit;
|
|
||||||
err = lfsr_data_readleb128(lfs, &data, &mtree_limit);
|
|
||||||
// treat any leb128 overflows as out-of-range values
|
|
||||||
if (err && err != LFS_ERR_CORRUPT) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err == LFS_ERR_CORRUPT || mtree_limit != 0x7fffffff) {
|
|
||||||
LFS_ERROR("Incompatible mdir limit 0x%"PRIx32
|
|
||||||
" (> 0x%"PRIx32")",
|
|
||||||
(err ? -1 : mtree_limit),
|
|
||||||
0x7fffffff);
|
|
||||||
return LFS_ERR_INVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check the on-disk attr limit
|
// check the on-disk attr limit
|
||||||
// TODO actually use this
|
// TODO actually use this
|
||||||
lfs_ssize_t attr_limit;
|
lfs_ssize_t attr_limit;
|
||||||
|
|||||||
+28
-20
@@ -645,6 +645,7 @@ def superconfig(mroot):
|
|||||||
next('flags')
|
next('flags')
|
||||||
next('block_size')
|
next('block_size')
|
||||||
next('block_count')
|
next('block_count')
|
||||||
|
next('mlimit')
|
||||||
next('utag_limit')
|
next('utag_limit')
|
||||||
next('attr_limit')
|
next('attr_limit')
|
||||||
next('name_limit')
|
next('name_limit')
|
||||||
@@ -653,10 +654,10 @@ def superconfig(mroot):
|
|||||||
|
|
||||||
# collect gstate
|
# collect gstate
|
||||||
class GState:
|
class GState:
|
||||||
def __init__(self, mbits):
|
def __init__(self, mweight):
|
||||||
self.gstate = {}
|
self.gstate = {}
|
||||||
self.gdelta = {}
|
self.gdelta = {}
|
||||||
self.mbits = mbits
|
self.mweight = mweight
|
||||||
|
|
||||||
def xor(self, mbid, mw, mdir):
|
def xor(self, mbid, mw, mdir):
|
||||||
tag = TAG_GSTATE-0x1
|
tag = TAG_GSTATE-0x1
|
||||||
@@ -690,11 +691,11 @@ class GState:
|
|||||||
for _ in range(count):
|
for _ in range(count):
|
||||||
mid, d_ = fromleb128(data[d:]); d += d_
|
mid, d_ = fromleb128(data[d:]); d += d_
|
||||||
rms.append((
|
rms.append((
|
||||||
mid & ~((1 << self.mbits)-1),
|
mid - (mid % self.mweight),
|
||||||
mid & ((1 << self.mbits)-1)))
|
mid % self.mweight))
|
||||||
return rms
|
return rms
|
||||||
|
|
||||||
def grepr(tag, data, mbits):
|
def grepr(tag, data, mweight):
|
||||||
if tag == TAG_GRM:
|
if tag == TAG_GRM:
|
||||||
d = 0
|
d = 0
|
||||||
count, d_ = fromleb128(data[d:]); d += d_
|
count, d_ = fromleb128(data[d:]); d += d_
|
||||||
@@ -703,11 +704,11 @@ def grepr(tag, data, mbits):
|
|||||||
for _ in range(count):
|
for _ in range(count):
|
||||||
mid, d_ = fromleb128(data[d:]); d += d_
|
mid, d_ = fromleb128(data[d:]); d += d_
|
||||||
rms.append((
|
rms.append((
|
||||||
mid & ~((1 << mbits)-1),
|
mid - (mid % self.mweight),
|
||||||
mid & ((1 << mbits)-1)))
|
mid % self.mweight))
|
||||||
return 'grm %s' % (
|
return 'grm %s' % (
|
||||||
'none' if count == 0
|
'none' if count == 0
|
||||||
else ' '.join('%d.%d' % (mbid >> mbits, rid)
|
else ' '.join('%d.%d' % (mbid//mweight, rid)
|
||||||
for mbid, rid in rms)
|
for mbid, rid in rms)
|
||||||
if count <= 2
|
if count <= 2
|
||||||
else '0x%x' % count)
|
else '0x%x' % count)
|
||||||
@@ -737,6 +738,7 @@ def frepr(mdir, rid, tag):
|
|||||||
|
|
||||||
def main(disk, mroots=None, *,
|
def main(disk, mroots=None, *,
|
||||||
block_size=None,
|
block_size=None,
|
||||||
|
mweight=None,
|
||||||
color='auto',
|
color='auto',
|
||||||
**args):
|
**args):
|
||||||
# figure out what color should be
|
# figure out what color should be
|
||||||
@@ -759,9 +761,10 @@ def main(disk, mroots=None, *,
|
|||||||
f.seek(0, os.SEEK_END)
|
f.seek(0, os.SEEK_END)
|
||||||
block_size = f.tell()
|
block_size = f.tell()
|
||||||
|
|
||||||
# determine the number of mbits from the block_size, this is just
|
# determine the mweight from the block_size, this is just for
|
||||||
# for printing purposes
|
# printing purposes
|
||||||
mbits = m.ceil(m.log2(block_size // 16))
|
if mweight is None:
|
||||||
|
mweight = 1 << m.ceil(m.log2(block_size // 16))
|
||||||
|
|
||||||
# before we print, we need to do a pass for a few things:
|
# before we print, we need to do a pass for a few things:
|
||||||
# - find the actual mroot
|
# - find the actual mroot
|
||||||
@@ -770,10 +773,10 @@ def main(disk, mroots=None, *,
|
|||||||
# - collect superconfig
|
# - collect superconfig
|
||||||
# - collect gstate
|
# - collect gstate
|
||||||
# - any missing or orphaned bookmark entries
|
# - any missing or orphaned bookmark entries
|
||||||
mweight = 0
|
bweight = 0
|
||||||
rweight = 0
|
rweight = 0
|
||||||
corrupted = False
|
corrupted = False
|
||||||
gstate = GState(mbits)
|
gstate = GState(mweight)
|
||||||
config = {}
|
config = {}
|
||||||
dir_dids = [(0, b'', -1, 0, None, -1, TAG_DID, 0)]
|
dir_dids = [(0, b'', -1, 0, None, -1, TAG_DID, 0)]
|
||||||
bookmark_dids = []
|
bookmark_dids = []
|
||||||
@@ -844,7 +847,7 @@ def main(disk, mroots=None, *,
|
|||||||
block, trunk, w, cksum = frombtree(data)
|
block, trunk, w, cksum = frombtree(data)
|
||||||
mtree = Rbyd.fetch(f, block_size, block, trunk)
|
mtree = Rbyd.fetch(f, block_size, block, trunk)
|
||||||
|
|
||||||
mweight = w
|
bweight = w
|
||||||
|
|
||||||
# traverse entries
|
# traverse entries
|
||||||
mbid = -1
|
mbid = -1
|
||||||
@@ -941,10 +944,10 @@ def main(disk, mroots=None, *,
|
|||||||
print('littlefs v%s.%s %s, rev %d, weight %d.%d' % (
|
print('littlefs v%s.%s %s, rev %d, weight %d.%d' % (
|
||||||
config.get('major_version', ('?',))[0],
|
config.get('major_version', ('?',))[0],
|
||||||
config.get('minor_version', ('?',))[0],
|
config.get('minor_version', ('?',))[0],
|
||||||
mroot.addr(), mroot.rev, mweight >> mbits, 1 << mbits))
|
mroot.addr(), mroot.rev, bweight//mweight, 1*mweight))
|
||||||
|
|
||||||
# print header
|
# print header
|
||||||
w_width = (m.ceil(m.log10(max(1, mweight >> mbits)+1))
|
w_width = (m.ceil(m.log10(max(1, bweight//mweight)+1))
|
||||||
+ 2*m.ceil(m.log10(max(1, rweight)+1))
|
+ 2*m.ceil(m.log10(max(1, rweight)+1))
|
||||||
+ 2)
|
+ 2)
|
||||||
if dtree:
|
if dtree:
|
||||||
@@ -999,7 +1002,7 @@ def main(disk, mroots=None, *,
|
|||||||
print('%12s %-*s %s' % (
|
print('%12s %-*s %s' % (
|
||||||
'gstate:' if i == 0 else '',
|
'gstate:' if i == 0 else '',
|
||||||
w_width + 23,
|
w_width + 23,
|
||||||
grepr(tag, data, mbits),
|
grepr(tag, data, mweight),
|
||||||
next(xxd(data, 8), '')
|
next(xxd(data, 8), '')
|
||||||
if not args.get('no_truncate') else ''))
|
if not args.get('no_truncate') else ''))
|
||||||
|
|
||||||
@@ -1034,7 +1037,7 @@ def main(disk, mroots=None, *,
|
|||||||
','.join('%04x' % block
|
','.join('%04x' % block
|
||||||
for block in it.chain([mdir.block],
|
for block in it.chain([mdir.block],
|
||||||
mdir.redund_blocks)),
|
mdir.redund_blocks)),
|
||||||
w_width, mbid >> mbits,
|
w_width, mbid//mweight,
|
||||||
tagrepr(tag, 0, len(data)),
|
tagrepr(tag, 0, len(data)),
|
||||||
next(xxd(data, 8), '')
|
next(xxd(data, 8), '')
|
||||||
if not args.get('no_truncate') else '',
|
if not args.get('no_truncate') else '',
|
||||||
@@ -1137,8 +1140,8 @@ def main(disk, mroots=None, *,
|
|||||||
mdir.redund_blocks))
|
mdir.redund_blocks))
|
||||||
if mbid != pmbid else '',
|
if mbid != pmbid else '',
|
||||||
w_width, '%d.%d-%d' % (
|
w_width, '%d.%d-%d' % (
|
||||||
mbid >> mbits, rid-(w-1), rid)
|
mbid//mweight, rid-(w-1), rid)
|
||||||
if w > 1 else '%d.%d' % (mbid >> mbits, rid)
|
if w > 1 else '%d.%d' % (mbid//mweight, rid)
|
||||||
if w > 0 else '',
|
if w > 0 else '',
|
||||||
f_width, '%s%s' % (
|
f_width, '%s%s' % (
|
||||||
prefixes[0+(i==len(dir)-1)],
|
prefixes[0+(i==len(dir)-1)],
|
||||||
@@ -1239,6 +1242,11 @@ if __name__ == "__main__":
|
|||||||
'-B', '--block-size',
|
'-B', '--block-size',
|
||||||
type=lambda x: int(x, 0),
|
type=lambda x: int(x, 0),
|
||||||
help="Block size in bytes.")
|
help="Block size in bytes.")
|
||||||
|
parser.add_argument(
|
||||||
|
'-M', '--mweight',
|
||||||
|
type=lambda x: int(x, 0),
|
||||||
|
help="Weight of mtree leaves for mid decoding. Defaults to a "
|
||||||
|
"block_size derived value.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--color',
|
'--color',
|
||||||
choices=['never', 'always', 'auto'],
|
choices=['never', 'always', 'auto'],
|
||||||
|
|||||||
+19
-12
@@ -739,6 +739,7 @@ class Rbyd:
|
|||||||
|
|
||||||
def main(disk, mroots=None, *,
|
def main(disk, mroots=None, *,
|
||||||
block_size=None,
|
block_size=None,
|
||||||
|
mweight=None,
|
||||||
color='auto',
|
color='auto',
|
||||||
**args):
|
**args):
|
||||||
# figure out what color should be
|
# figure out what color should be
|
||||||
@@ -761,14 +762,15 @@ def main(disk, mroots=None, *,
|
|||||||
f.seek(0, os.SEEK_END)
|
f.seek(0, os.SEEK_END)
|
||||||
block_size = f.tell()
|
block_size = f.tell()
|
||||||
|
|
||||||
# determine the number of mbits from the block_size, this is just
|
# determine the mweight from the block_size, this is just for
|
||||||
# for printing purposes
|
# printing purposes
|
||||||
mbits = m.ceil(m.log2(block_size // 16))
|
if mweight is None:
|
||||||
|
mweight = 1 << m.ceil(m.log2(block_size // 16))
|
||||||
|
|
||||||
# before we print, we need to do a pass for a few things:
|
# before we print, we need to do a pass for a few things:
|
||||||
# - find the actual mroot
|
# - find the actual mroot
|
||||||
# - find the total weight
|
# - find the total weight
|
||||||
mweight = 0
|
bweight = 0
|
||||||
rweight = 0
|
rweight = 0
|
||||||
|
|
||||||
mroot = Rbyd.fetch(f, block_size, mroots)
|
mroot = Rbyd.fetch(f, block_size, mroots)
|
||||||
@@ -813,7 +815,7 @@ def main(disk, mroots=None, *,
|
|||||||
block, trunk, w, cksum = frombtree(data)
|
block, trunk, w, cksum = frombtree(data)
|
||||||
mtree = Rbyd.fetch(f, block_size, block, trunk)
|
mtree = Rbyd.fetch(f, block_size, block, trunk)
|
||||||
|
|
||||||
mweight = w
|
bweight = w
|
||||||
|
|
||||||
# traverse entries
|
# traverse entries
|
||||||
mbid = -1
|
mbid = -1
|
||||||
@@ -1307,8 +1309,8 @@ def main(disk, mroots=None, *,
|
|||||||
if args.get('tree') or args.get('btree') else '',
|
if args.get('tree') or args.get('btree') else '',
|
||||||
'%*s %-22s%s' % (
|
'%*s %-22s%s' % (
|
||||||
w_width, '%d.%d-%d' % (
|
w_width, '%d.%d-%d' % (
|
||||||
mbid >> mbits, rid-(w-1), rid)
|
mbid//mweight, rid-(w-1), rid)
|
||||||
if w > 1 else '%d.%d' % (mbid >> mbits, rid)
|
if w > 1 else '%d.%d' % (mbid//mweight, rid)
|
||||||
if w > 0 or i == 0 else '',
|
if w > 0 or i == 0 else '',
|
||||||
tagrepr(tag, w, len(data), j),
|
tagrepr(tag, w, len(data), j),
|
||||||
' %s' % next(xxd(data, 8), '')
|
' %s' % next(xxd(data, 8), '')
|
||||||
@@ -1364,9 +1366,9 @@ def main(disk, mroots=None, *,
|
|||||||
treerepr(bid, w, bd, rid, 0, tag)
|
treerepr(bid, w, bd, rid, 0, tag)
|
||||||
if args.get('tree') or args.get('btree') else '',
|
if args.get('tree') or args.get('btree') else '',
|
||||||
w_width, '' if i != 0
|
w_width, '' if i != 0
|
||||||
else '%d-%d' % ((bid-(w-1)) >> mbits, bid >> mbits)
|
else '%d-%d' % ((bid-(w-1))//mweight, bid//mweight)
|
||||||
if (w >> mbits) > 1
|
if (w//mweight) > 1
|
||||||
else bid >> mbits if w > 0
|
else bid//mweight if w > 0
|
||||||
else '',
|
else '',
|
||||||
tagrepr(tag, w if i == 0 else 0, len(data), None),
|
tagrepr(tag, w if i == 0 else 0, len(data), None),
|
||||||
# note we render names a bit different here
|
# note we render names a bit different here
|
||||||
@@ -1407,10 +1409,10 @@ def main(disk, mroots=None, *,
|
|||||||
|
|
||||||
# print some information about the mtree
|
# print some information about the mtree
|
||||||
print('mtree %s, rev %d, weight %d.%d' % (
|
print('mtree %s, rev %d, weight %d.%d' % (
|
||||||
mroot.addr(), mroot.rev, mweight >> mbits, 1 << mbits))
|
mroot.addr(), mroot.rev, bweight//mweight, 1*mweight))
|
||||||
|
|
||||||
# print header
|
# print header
|
||||||
w_width = (m.ceil(m.log10(max(1, mweight >> mbits)+1))
|
w_width = (m.ceil(m.log10(max(1, bweight//mweight)+1))
|
||||||
+ 2*m.ceil(m.log10(max(1, rweight)+1))
|
+ 2*m.ceil(m.log10(max(1, rweight)+1))
|
||||||
+ 2)
|
+ 2)
|
||||||
print('%-11s %*s%-*s %-22s %s' % (
|
print('%-11s %*s%-*s %-22s %s' % (
|
||||||
@@ -1600,6 +1602,11 @@ if __name__ == "__main__":
|
|||||||
'-B', '--block-size',
|
'-B', '--block-size',
|
||||||
type=lambda x: int(x, 0),
|
type=lambda x: int(x, 0),
|
||||||
help="Block size in bytes.")
|
help="Block size in bytes.")
|
||||||
|
parser.add_argument(
|
||||||
|
'-M', '--mweight',
|
||||||
|
type=lambda x: int(x, 0),
|
||||||
|
help="Weight of mtree leaves for mid decoding. Defaults to a "
|
||||||
|
"block_size derived value.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--color',
|
'--color',
|
||||||
choices=['never', 'always', 'auto'],
|
choices=['never', 'always', 'auto'],
|
||||||
|
|||||||
Reference in New Issue
Block a user