Dropped attr-size down to at most 28-bits (4 leb128 bytes)
This really doesn't need to be this large. The extra 4-bits is not worth the required extra byte of waste in every commit (CRCs tags are forced to use a fully expanded leb128 due to a catch-22 issue).
This commit is contained in:
@@ -696,14 +696,12 @@ static void lfs_fcrc_tole32(struct lfs_fcrc *fcrc) {
|
|||||||
struct lfs_rfcrc {
|
struct lfs_rfcrc {
|
||||||
uint32_t crc;
|
uint32_t crc;
|
||||||
lfs_size_t size;
|
lfs_size_t size;
|
||||||
// extra space for leb128 encoding
|
|
||||||
uint8_t spill[1];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static lfs_ssize_t lfs_rfcrc_todisk(struct lfs_rfcrc *fcrc) {
|
static lfs_ssize_t lfs_rfcrc_todisk(struct lfs_rfcrc *fcrc) {
|
||||||
lfs_tole32_(fcrc->crc, &fcrc->crc);
|
lfs_tole32_(fcrc->crc, &fcrc->crc);
|
||||||
|
|
||||||
lfs_ssize_t delta = lfs_toleb128(fcrc->size, (uint8_t*)&fcrc->size, 5);
|
lfs_ssize_t delta = lfs_toleb128(fcrc->size, (uint8_t*)&fcrc->size, 4);
|
||||||
if (delta < 0) {
|
if (delta < 0) {
|
||||||
return delta;
|
return delta;
|
||||||
}
|
}
|
||||||
@@ -714,7 +712,7 @@ static lfs_ssize_t lfs_rfcrc_todisk(struct lfs_rfcrc *fcrc) {
|
|||||||
static lfs_ssize_t lfs_rfcrc_fromdisk(struct lfs_rfcrc *fcrc) {
|
static lfs_ssize_t lfs_rfcrc_fromdisk(struct lfs_rfcrc *fcrc) {
|
||||||
fcrc->crc = lfs_fromle32_(&fcrc->crc);
|
fcrc->crc = lfs_fromle32_(&fcrc->crc);
|
||||||
|
|
||||||
lfs_ssize_t delta = lfs_fromleb128(&fcrc->size, (uint8_t*)&fcrc->size, 5);
|
lfs_ssize_t delta = lfs_fromleb128(&fcrc->size, (uint8_t*)&fcrc->size, 4);
|
||||||
if (delta < 0) {
|
if (delta < 0) {
|
||||||
return delta;
|
return delta;
|
||||||
}
|
}
|
||||||
@@ -922,7 +920,7 @@ static lfs_ssize_t lfs_rbyd_readtag(lfs_t *lfs,
|
|||||||
*tag = 0;
|
*tag = 0;
|
||||||
|
|
||||||
// read a pair of leb128s
|
// read a pair of leb128s
|
||||||
uint8_t buffer[2*5];
|
uint8_t buffer[2*4];
|
||||||
lfs_size_t i = 0;
|
lfs_size_t i = 0;
|
||||||
|
|
||||||
// TODO allow different hint for lookup? bench this? does our hint work backwards?
|
// TODO allow different hint for lookup? bench this? does our hint work backwards?
|
||||||
@@ -935,14 +933,14 @@ static lfs_ssize_t lfs_rbyd_readtag(lfs_t *lfs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
lfs_rtag_t tag_;
|
lfs_rtag_t tag_;
|
||||||
ssize_t delta = lfs_fromleb128(&tag_, &buffer[i], 5);
|
ssize_t delta = lfs_fromleb128(&tag_, &buffer[i], 4);
|
||||||
if (delta < 0) {
|
if (delta < 0) {
|
||||||
return delta;
|
return delta;
|
||||||
}
|
}
|
||||||
i += delta;
|
i += delta;
|
||||||
|
|
||||||
lfs_size_t size_;
|
lfs_size_t size_;
|
||||||
delta = lfs_fromleb128(&size_, &buffer[i], 5);
|
delta = lfs_fromleb128(&size_, &buffer[i], 4);
|
||||||
if (delta < 0) {
|
if (delta < 0) {
|
||||||
return delta;
|
return delta;
|
||||||
}
|
}
|
||||||
@@ -1154,7 +1152,7 @@ static lfs_srtag_t lfs_rbyd_lookup(lfs_t *lfs, const lfs_rbyd_t *rbyd,
|
|||||||
lfs_rtag_t alt;
|
lfs_rtag_t alt;
|
||||||
lfs_off_t jump;
|
lfs_off_t jump;
|
||||||
lfs_ssize_t delta = lfs_rbyd_readtag(lfs,
|
lfs_ssize_t delta = lfs_rbyd_readtag(lfs,
|
||||||
&lfs->pcache, &lfs->rcache, 2*5,
|
&lfs->pcache, &lfs->rcache, 2*4,
|
||||||
rbyd->block, branch, &alt, &jump, NULL);
|
rbyd->block, branch, &alt, &jump, NULL);
|
||||||
if (delta < 0) {
|
if (delta < 0) {
|
||||||
return delta;
|
return delta;
|
||||||
@@ -1224,16 +1222,16 @@ static lfs_ssize_t lfs_rbyd_progtag(lfs_t *lfs,
|
|||||||
tag |= lfs_popc(crc_) & 1;
|
tag |= lfs_popc(crc_) & 1;
|
||||||
|
|
||||||
// compress into pair of leb128s
|
// compress into pair of leb128s
|
||||||
uint8_t buffer[2*5];
|
uint8_t buffer[2*4];
|
||||||
lfs_size_t i = 0;
|
lfs_size_t i = 0;
|
||||||
|
|
||||||
ssize_t delta = lfs_toleb128(tag, &buffer[i], 5);
|
ssize_t delta = lfs_toleb128(tag, &buffer[i], 4);
|
||||||
if (delta < 0) {
|
if (delta < 0) {
|
||||||
return delta;
|
return delta;
|
||||||
}
|
}
|
||||||
i += delta;
|
i += delta;
|
||||||
|
|
||||||
delta = lfs_toleb128(size, &buffer[i], 5);
|
delta = lfs_toleb128(size, &buffer[i], 4);
|
||||||
if (delta < 0) {
|
if (delta < 0) {
|
||||||
return delta;
|
return delta;
|
||||||
}
|
}
|
||||||
@@ -1412,7 +1410,7 @@ static int lfs_rbyd_commit(lfs_t *lfs, lfs_rbyd_t *rbyd,
|
|||||||
lfs_rtag_t alt;
|
lfs_rtag_t alt;
|
||||||
lfs_off_t jump;
|
lfs_off_t jump;
|
||||||
lfs_ssize_t delta = lfs_rbyd_readtag(lfs,
|
lfs_ssize_t delta = lfs_rbyd_readtag(lfs,
|
||||||
&lfs->pcache, &lfs->rcache, 2*5,
|
&lfs->pcache, &lfs->rcache, 2*4,
|
||||||
block, branch, &alt, &jump, NULL);
|
block, branch, &alt, &jump, NULL);
|
||||||
if (delta < 0) {
|
if (delta < 0) {
|
||||||
return delta;
|
return delta;
|
||||||
@@ -1607,19 +1605,19 @@ static int lfs_rbyd_commit(lfs_t *lfs, lfs_rbyd_t *rbyd,
|
|||||||
// 1-byte fcrc tag
|
// 1-byte fcrc tag
|
||||||
// + 1-byte fcrc len (worst case)
|
// + 1-byte fcrc len (worst case)
|
||||||
// + 4-byte fcrc crc
|
// + 4-byte fcrc crc
|
||||||
// + 5-byte fcrc crc-len (worst case)
|
// + 4-byte fcrc crc-len (worst case)
|
||||||
// + 1-byte crc tag
|
// + 1-byte crc tag
|
||||||
// + 5-byte crc len (worst case)
|
// + 4-byte crc len (worst case)
|
||||||
// + 4-byte crc crc
|
// + 4-byte crc crc
|
||||||
// = 21 bytes
|
// = 19 bytes
|
||||||
// - 3-word crc with no following prog (end of block)
|
// - 3-word crc with no following prog (end of block)
|
||||||
// 1-byte crc tag
|
// 1-byte crc tag
|
||||||
// + 5-byte crc len (worst case)
|
// + 4-byte crc len (worst case)
|
||||||
// + 4-byte crc crc
|
// + 4-byte crc crc
|
||||||
// = 10 bytes
|
// = 9 bytes
|
||||||
//
|
//
|
||||||
const lfs_off_t aligned = lfs_alignup(
|
const lfs_off_t aligned = lfs_alignup(
|
||||||
lfs_min(off + 1+1+4+5 + 1+5+4, lfs->cfg->block_size),
|
lfs_min(off + 1+1+4+4 + 1+4+4, lfs->cfg->block_size),
|
||||||
lfs->cfg->prog_size);
|
lfs->cfg->prog_size);
|
||||||
|
|
||||||
// space for fcrc?
|
// space for fcrc?
|
||||||
@@ -1671,34 +1669,33 @@ static int lfs_rbyd_commit(lfs_t *lfs, lfs_rbyd_t *rbyd,
|
|||||||
// note padding-size depends on leb-encoding depends on padding-size, to
|
// note padding-size depends on leb-encoding depends on padding-size, to
|
||||||
// get around this catch-22 we just always write a fully-expanded leb128
|
// get around this catch-22 we just always write a fully-expanded leb128
|
||||||
// encoding
|
// encoding
|
||||||
uint8_t buffer[1+5+4];
|
uint8_t buffer[1+4+4];
|
||||||
buffer[0] = (LFS_MKRTAG(CRC0, 0, 0) << 1) | (lfs_popc(crc) & 1);
|
buffer[0] = (LFS_MKRTAG(CRC0, 0, 0) << 1) | (lfs_popc(crc) & 1);
|
||||||
|
|
||||||
lfs_off_t padding = aligned - (off + 1+5);
|
lfs_off_t padding = aligned - (off + 1+4);
|
||||||
buffer[1] = 0x80 | (0x7f & (padding >> 0));
|
buffer[1] = 0x80 | (0x7f & (padding >> 0));
|
||||||
buffer[2] = 0x80 | (0x7f & (padding >> 7));
|
buffer[2] = 0x80 | (0x7f & (padding >> 7));
|
||||||
buffer[3] = 0x80 | (0x7f & (padding >> 14));
|
buffer[3] = 0x80 | (0x7f & (padding >> 14));
|
||||||
buffer[4] = 0x80 | (0x7f & (padding >> 21));
|
buffer[4] = 0x00 | (0x7f & (padding >> 21));
|
||||||
buffer[5] = 0x00 | (0x7f & (padding >> 28));
|
|
||||||
|
|
||||||
crc = lfs_crc32c(crc, buffer, 1+5);
|
crc = lfs_crc32c(crc, buffer, 1+4);
|
||||||
// we can't let the next tag appear as valid, so intentionally perturb the
|
// we can't let the next tag appear as valid, so intentionally perturb the
|
||||||
// commit if this happens, note parity(crc(m)) == parity(m) with crc32c,
|
// commit if this happens, note parity(crc(m)) == parity(m) with crc32c,
|
||||||
// so we can really change any bit to make this happen, we've reserved a bit
|
// so we can really change any bit to make this happen, we've reserved a bit
|
||||||
// in crc tags just for this purpose
|
// in crc tags just for this purpose
|
||||||
if ((lfs_popc(crc) & 1) == (perturb & 1)) {
|
if ((lfs_popc(crc) & 1) == (perturb & 1)) {
|
||||||
buffer[0] ^= 0x2;
|
buffer[0] ^= 0x2;
|
||||||
crc ^= 0xdb8ca0c3; // note crc(a ^ b) == crc(a) ^ crc(b)
|
crc ^= 0x7022df58; // note crc(a ^ b) == crc(a) ^ crc(b)
|
||||||
}
|
}
|
||||||
lfs_tole32_(crc, &buffer[1+5]);
|
lfs_tole32_(crc, &buffer[1+4]);
|
||||||
|
|
||||||
int err = lfs_bd_prog(lfs,
|
int err = lfs_bd_prog(lfs,
|
||||||
&lfs->pcache, &lfs->rcache, false,
|
&lfs->pcache, &lfs->rcache, false,
|
||||||
block, off, buffer, 1+5+4);
|
block, off, buffer, 1+4+4);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
off += 1+5+4;
|
off += 1+4+4;
|
||||||
|
|
||||||
// flush our caches, finalizing the commit on-disk
|
// flush our caches, finalizing the commit on-disk
|
||||||
err = lfs_bd_sync(lfs, &lfs->pcache, &lfs->rcache, false);
|
err = lfs_bd_sync(lfs, &lfs->pcache, &lfs->rcache, false);
|
||||||
@@ -1718,7 +1715,7 @@ static int lfs_rbyd_commit(lfs_t *lfs, lfs_rbyd_t *rbyd,
|
|||||||
if (crc_ != crc) {
|
if (crc_ != crc) {
|
||||||
// oh no, something went wrong
|
// oh no, something went wrong
|
||||||
printf("oh no %08x != %08x\n", crc_, crc);
|
printf("oh no %08x != %08x\n", crc_, crc);
|
||||||
//return LFS_ERR_CORRUPT;
|
return LFS_ERR_CORRUPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ok, everything is good, save what we've committed
|
// ok, everything is good, save what we've committed
|
||||||
|
|||||||
Reference in New Issue
Block a user