Initial groundwork for rbyd trees

- primitive lfs_rbyd_fetch
- primitive lfs_rbyd_commit
- tag reading/progging and encoding machinery

The tag encoding scheme here uses pairs of leb128s, encoding either
a normal tag:

  iiii iiiiiii iiiiiTT TTTTTTt ttttt0v
                   ^--------^------^-^- 16-bit id
                            '------|-|- 8-bit type2
                                   '-|- 6-bit type1
                                     '- valid bit
  llll lllllll lllllll lllllll lllllll
                                     ^- n-bit length

Or an alt pointer:

  wwww wwwwwww wwwwwww wwwwwww wwwcd1v
                                 ^^^-^- 28-bit weight
                                  '|-|- color bit
                                   '-|- direction bit
                                     '- valid bit
  jjjj jjjjjjj jjjjjjj jjjjjjj jjjjjjj
                                     ^- n-bit jump

Note that two bits overlap the alt pointer dir/color encoding, this
is actually not a problem at all since some tags (crcs/fcrcs) don't
participate in the rbyd tree and can use these bits.

There's a number of benefits to using leb128s, which should probably
be written about, most notably is the abstraction of the device's
word-size. The "n-bits" above can be whatever word size works on the
device, trading off code-size for storage capabilities without breaking
compatibility with other devices. This will eventually be negotiated via
the superblock.
This commit is contained in:
Christopher Haster
2022-12-20 00:26:43 -06:00
parent 37dcee8868
commit 2802880eaa
5 changed files with 943 additions and 0 deletions
+11
View File
@@ -84,6 +84,7 @@ enum lfs_error {
LFS_ERR_NOMEM = -12, // No more memory available
LFS_ERR_NOATTR = -61, // No data/attr available
LFS_ERR_NAMETOOLONG = -36, // File name too long
LFS_ERR_OVERFLOW = -75, // Value too large for defined data type
};
// File types
@@ -326,6 +327,16 @@ typedef struct lfs_cache {
uint8_t *buffer;
} lfs_cache_t;
typedef struct lfs_rbyd {
lfs_block_t block;
lfs_off_t trunk;
lfs_off_t noff;
uint32_t rev;
uint32_t crc;
uint16_t count;
bool erased;
} lfs_rbyd_t;
typedef struct lfs_mdir {
lfs_block_t pair[2];
uint32_t rev;