Some small tweaks

- Updated LFSR_BTREE_INLINESIZE to properly include the overhead for
  mdir pointers, which need 2 block addresses instead of 1. This adds
  4 bytes to the lfsr_btree_t struct.

- Changed code that marks rbyds as "needing compaction" to use -1
  instead of block_size. This can use a cheaper constant and helps
  debugging.

- Changed the mid representation of root to 0.0 from ?.-1. The mid 0.0
  is always reserved for the roots dstart, so it shouldn't be used for
  any actual file. This disambiguates root vs special metadata mids and
  is a step towards making mids unsigned.

  It also saves a tiny bit of code since 0 comparisons are generally
  cheaper and we can leverage the order-preserving conversion of mid
  to an integer.
This commit is contained in:
Christopher Haster
2023-08-04 22:33:09 -05:00
parent da4e86abac
commit 3c42ed98a4
2 changed files with 35 additions and 19 deletions
+27 -12
View File
@@ -1532,6 +1532,17 @@ static lfs_ssize_t lfsr_fcrc_fromdisk(lfs_t *lfs, lfsr_fcrc_t *fcrc,
#define LFSR_MID(_bid, _rid) ((lfsr_mid_t){_bid, _rid})
static inline int lfsr_mid_cmp(lfsr_mid_t a, lfsr_mid_t b) {
union { lfsr_mid_t mid; lfs_ssize_t w; } a_u = {.mid=a};
union { lfsr_mid_t mid; lfs_ssize_t w; } b_u = {.mid=b};
return a_u.w - b_u.w;
}
// we use the root's dstart at 0.0 to represent root
static inline bool lfsr_mid_isroot(lfsr_mid_t mid) {
return lfsr_mid_cmp(mid, LFSR_MID(0, 0)) == 0;
}
/// Global-state things ///
@@ -1947,7 +1958,7 @@ static int lfsr_rbyd_fetch(lfs_t *lfs, lfsr_rbyd_t *rbyd,
}
if (!erased) {
rbyd->off = lfs->cfg->block_size;
rbyd->off = -1;
}
return 0;
@@ -2098,7 +2109,7 @@ static int lfsr_rbyd_appendrev(lfs_t *lfs, lfsr_rbyd_t *rbyd, uint32_t rev) {
failed:
// if we fail mark the rbyd as unerased and release the pcache
lfs_cache_zero(lfs, &lfs->pcache);
rbyd->off = lfs->cfg->block_size;
rbyd->off = -1;
return err;
}
@@ -2710,7 +2721,7 @@ leaf:;
failed:;
// if we fail mark the rbyd as unerased and release the pcache
lfs_cache_zero(lfs, &lfs->pcache);
rbyd->off = lfs->cfg->block_size;
rbyd->off = -1;
return err;
}
@@ -2993,7 +3004,7 @@ static int lfsr_rbyd_compact(lfs_t *lfs, lfsr_rbyd_t *rbyd,
failed:;
// if we fail mark the rbyd as unerased and release the pcache
lfs_cache_zero(lfs, &lfs->pcache);
rbyd->off = lfs->cfg->block_size;
rbyd->off = -1;
return err;
#else
@@ -3095,7 +3106,7 @@ static int lfsr_rbyd_commit(lfs_t *lfs, lfsr_rbyd_t *rbyd,
int err = lfsr_bd_read(lfs, rbyd_.block, aligned, lfs->cfg->prog_size,
&perturb, 1);
if (err && err != LFS_ERR_CORRUPT) {
rbyd->off = lfs->cfg->block_size;
rbyd->off = -1;
return err;
}
@@ -3204,7 +3215,7 @@ static int lfsr_rbyd_commit(lfs_t *lfs, lfsr_rbyd_t *rbyd,
failed:;
// if we fail mark the rbyd as unerased and release the pcache
lfs_cache_zero(lfs, &lfs->pcache);
rbyd->off = lfs->cfg->block_size;
rbyd->off = -1;
return err;
}
@@ -5119,7 +5130,7 @@ static int lfsr_mdir_alloc(lfs_t *lfs, lfsr_mdir_t *mdir, lfsr_mid_t mid) {
mdir->m.rbyd.weight = 0;
mdir->m.rbyd.block = blocks[1];
// mark mdir as needing compaction
mdir->m.rbyd.off = lfs->cfg->block_size;
mdir->m.rbyd.off = -1;
mdir->m.rbyd.trunk = 0;
return 0;
}
@@ -6223,7 +6234,8 @@ static int lfsr_mtree_pathlookup(lfs_t *lfs, const char *path,
lfsr_mdir_t *mdir_, lfsr_tag_t *tag_,
lfs_size_t *did_, const char **name_, lfs_size_t *name_size_) {
// setup root
lfsr_mdir_t mdir = {.mid.rid=-1};
lfsr_mdir_t mdir;
mdir.mid = LFSR_MID(0, 0);
lfsr_tag_t tag = LFSR_TAG_DIR;
lfs_size_t did = LFSR_DID_ROOT;
@@ -6277,7 +6289,7 @@ static int lfsr_mtree_pathlookup(lfs_t *lfs, const char *path,
if (name[0] == '\0') {
// generally we don't allow operations that change our root,
// report root as inval, but let upper layers intercept this
if (mdir.mid.rid == -1) {
if (lfsr_mid_isroot(mdir.mid)) {
return LFS_ERR_INVAL;
}
return 0;
@@ -6289,7 +6301,7 @@ static int lfsr_mtree_pathlookup(lfs_t *lfs, const char *path,
}
// read the next did from the mdir if this is not the root
if (mdir.mid.rid != -1) {
if (!lfsr_mid_isroot(mdir.mid)) {
lfsr_data_t data;
int err = lfsr_mdir_lookup(lfs, &mdir, mdir.mid.rid, LFSR_TAG_DID,
NULL, &data);
@@ -7020,6 +7032,9 @@ static int lfsr_formatinited(lfs_t *lfs) {
return err;
}
// note the initial revision count is arbitrary, but we use
// -1 and 0 here to help test that our sequence comparison
// works correctly
err = lfsr_rbyd_appendrev(lfs, &rbyd, (uint32_t)i - 1);
if (err) {
return err;
@@ -7223,7 +7238,7 @@ int lfsr_mkdir(lfs_t *lfs, const char *path) {
err = lfsr_mtree_pathlookup(lfs, path,
&parent.mdir, NULL,
&parent_did, &name, &name_size);
if (err && (err != LFS_ERR_NOENT || parent.mdir.mid.rid == -1)) {
if (err && (err != LFS_ERR_NOENT || lfsr_mid_isroot(parent.mdir.mid))) {
return err;
}
@@ -7450,7 +7465,7 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) {
err = lfsr_mtree_pathlookup(lfs, new_path,
&new_mdir, &new_tag,
&new_did, &new_name, &new_name_size);
if (err && (err != LFS_ERR_NOENT || new_mdir.mid.rid == -1)) {
if (err && (err != LFS_ERR_NOENT || lfsr_mid_isroot(new_mdir.mid))) {
return err;
}
bool exists = (err != LFS_ERR_NOENT);
+8 -7
View File
@@ -52,6 +52,11 @@ typedef int16_t lfsr_smbid_t;
typedef uint16_t lfsr_mrid_t;
typedef int16_t lfsr_smrid_t;
typedef struct lfsr_mid {
lfsr_smbid_t bid;
lfsr_smrid_t rid;
} lfsr_mid_t;
// Maximum name size in bytes, may be redefined to reduce the size of the
// info struct. Limited to <= 1022. Stored in superblock and must be
// respected by other littlefs drivers.
@@ -342,8 +347,8 @@ typedef struct lfsr_rbyd {
// off=0, trunk=0 => not yet committed
// off=0, trunk>0 => not yet fetched
// off=block_size => rbyd not erased/needs compaction
lfs_off_t off;
lfs_off_t trunk;
lfs_off_t off;
uint32_t crc;
} lfsr_rbyd_t;
@@ -353,7 +358,8 @@ typedef struct lfsr_rbyd {
//
// Pointers we store:
// - block addresses => 1 leb128 => 5 bytes (worst case)
#define LFSR_BTREE_INLINESIZE 5
// - mdir addresses => 2 leb128 => 10 bytes (worst case)
#define LFSR_BTREE_INLINESIZE 10
typedef union lfsr_btree {
// note this lines up with weight in lfsr_rbyd_t
@@ -373,11 +379,6 @@ typedef union lfsr_btree {
} inlined;
} lfsr_btree_t;
typedef struct lfsr_mid {
lfsr_smbid_t bid;
lfsr_smrid_t rid;
} lfsr_mid_t;
typedef struct lfsr_mdir {
lfsr_mid_t mid;
struct {