From ebae43898e4b3e7d73847f7cfbc62782ad2f10e8 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sun, 27 Jul 2025 16:41:30 -0500 Subject: [PATCH] bmap: Changing direction, store bmap mode in wcompat flags The idea behind separate ctrled+unctrled airspaces was to try to avoid multiple interpretations of the on-disk bmap, but I'm starting to think this adds more complexity than it solves. The main conflict is the meaning of "in-flight" blocks. When using the "uncontrolled" bmap algorithm, in-flight blocks need to be double-checked by traversing the filesystem. But in the "controlled" bmap algorithm, blocks are only marked as "in-flight" while they are truly in-flight (in-use in RAM, but not yet in use on disk). Representing these both with the same "in-flight" state risks incompatible algorithms misinterpreting the bmap across different mounts. In theory the separate airspaces solve this, but now all the algorithms need to know how to convert the bmap from different modes, adding complexity and code cost. Well, in theory at least. I'm unsure separate airspaces actually solves this due to subtleties between what "in-flight" means in the different algorithms (note both in-use and free blocks are "in-flight" in the unknown airspace!). It really depends on how the "controlled" algorithm actually works, which isn't implemented/fully designed yet. --- Long story short, due to a time crunch, I'm ripping this out for now and just storing the current algorithm in the wcompat flags: LFS3_WCOMPAT_GBMAP 0x00006000 Global block-map in use LFS3_WCOMPAT_GBMAPNONE 0x00000000 Gbmap not in use LFS3_WCOMPAT_GBMAPCACHE 0x00002000 Gbmap in cache mode LFS3_WCOMPAT_GBMAPVFR 0x00004000 Gbmap in VFR mode LFS3_WCOMPAT_GBMAPIFR 0x00006000 Gbmap in IFR mode Note GBMAPVFR/IFR != BMAPSLOW/FAST! At least BMAPSLOW/FAST can share bmap representations: - GBMAPVFR => Uncontrolled airspace, i.e. in-flight blocks may or may not be in use, need to traverse open files. - GBMAPIFR => Controlled airspace, i.e. in-flight blocks are in use, at least until powerloss, no traversal needed, but requires more bmap writes. - BMAPSLOW => Treediff by checking what blocks are in B but not in A, and what blocks are in A but not in B, O(n^2), but minimizes bmap updates. Can be optimized with a bloom filter. - BMAPFAST => Treediff by clearing all blocks in A, and then setting all blocks in B, O(n), but also writes all blocks to the bmap twice even on small changes. Can be optimized with a sliding bitmap window (or a block hashtable, though a bitmap converges to the same thing in both algorithms when >=disk_size). It will probably be worth unifying the bmap representation later (the more algorithm-specific flags there are, the harder interop becomes for users, but for now this opens a path to implementing/experimenting with bmap algorithms without dealing with this headache. --- lfs3.c | 226 +++++++++++++++++++----------------------- lfs3.h | 46 +++------ lfs3_util.h | 24 +++-- scripts/dbgbmap.py | 7 +- scripts/dbgbmapsvg.py | 7 +- scripts/dbgflags.py | 24 +++-- scripts/dbglfs3.py | 7 +- 7 files changed, 156 insertions(+), 185 deletions(-) diff --git a/lfs3.c b/lfs3.c index 892fef43..5a72ff6e 100644 --- a/lfs3.c +++ b/lfs3.c @@ -10552,10 +10552,8 @@ static lfs3_data_t lfs3_data_fromgbmap(const lfs3_t *lfs3, uint8_t buffer[static LFS3_GBMAP_DSIZE]) { // cursor should not exceed 31-bits LFS3_ASSERT(lfs3->gbmap.cursor <= 0x7fffffff); - // ctrled should not exceed 31-bits - LFS3_ASSERT(lfs3->gbmap.ctrled <= 0x7fffffff); - // unctrled should not exceed 31-bits - LFS3_ASSERT(lfs3->gbmap.unctrled <= 0x7fffffff); + // known should not exceed 31-bits + LFS3_ASSERT(lfs3->gbmap.known <= 0x7fffffff); // make sure to zero so we don't leak any info lfs3_memset(buffer, 0, LFS3_GBMAP_DSIZE); @@ -10567,16 +10565,7 @@ static lfs3_data_t lfs3_data_fromgbmap(const lfs3_t *lfs3, } d += d_; - d_ = lfs3_toleb128(lfs3->gbmap.ctrled, &buffer[d], 5); - if (d_ < 0) { - LFS3_UNREACHABLE(); - } - d += d_; - - // in-driver unctrled contains both unctrled+ctrled airspaces to - // simplify bookkeeping - d_ = lfs3_toleb128(lfs3->gbmap.unctrled - lfs3->gbmap.ctrled, - &buffer[d], 5); + d_ = lfs3_toleb128(lfs3->gbmap.known, &buffer[d], 5); if (d_ < 0) { LFS3_UNREACHABLE(); } @@ -10596,20 +10585,11 @@ static int lfs3_data_readgbmap(lfs3_t *lfs3, lfs3_data_t *data) { return err; } - err = lfs3_data_readleb128(lfs3, data, &lfs3->gbmap.ctrled); + err = lfs3_data_readleb128(lfs3, data, &lfs3->gbmap.known); if (err) { return err; } - // in-driver unctrled contains both unctrled+ctrled airspaces to - // simplify bookkeeping - lfs3_block_t unctrled; - err = lfs3_data_readleb128(lfs3, data, &lfs3->gbmap.unctrled); - if (err) { - return err; - } - lfs3->gbmap.unctrled += lfs3->gbmap.ctrled; - err = lfs3_data_readbranch(lfs3, data, lfs3->block_count, &lfs3->gbmap.b.r); if (err) { @@ -10898,11 +10878,6 @@ static void lfs3_alloc_inc(lfs3_t *lfs3) { lfs3->lookahead.size -= 1; // decrement ckpoint lfs3->lookahead.ckpoint -= 1; - // decrement controlled/uncontrolled airspaces - #ifdef LFS3_BMAP - lfs3->gbmap.ctrled = lfs3_smax(lfs3->gbmap.ctrled-1, 0); - lfs3->gbmap.unctrled = lfs3_smax(lfs3->gbmap.unctrled-1, 0); - #endif } #endif @@ -10990,77 +10965,77 @@ static lfs3_sblock_t lfs3_alloc(lfs3_t *lfs3, uint32_t flags) { // no blocks in our lookahead buffer? - // controlled airspace in our bmap? - #ifdef LFS3_BMAP - if (lfs3->gbmap.ctrled > 0) { - lfs3_ssize_t d = lfs3_bmap_findairspace(lfs3, lfs3_min( - lfs3->gbmap.ctrled, - lfs3->lookahead.ckpoint)); - if (err) { - return err; - } - - // TODO should markinuse, etc, take the lookahead buffer? - // TODO do we need to zero now that we're not using the full - // buffer? - - // with a controlled airspace, we can trust all blocks - // states are exact - lfs3_alloc_markfree(lfs3, lfs3_min( - lfs3->gbmap.ctrled, - lfs3->lookahead.ckpoint)); - continue; - } - #endif - - // uncontrolled airspace in our bmap? - #ifdef LFS3_BMAP - if (lfs3->gbmap.unctrled > 0) { - // TODO this needs to know if in-flight blocks count? - lfs3_ssize_t d = lfs3_bmap_findairspace(lfs3, lfs3_min( - lfs3->gbmap.unctrled, - lfs3->lookahead.ckpoint)); - if (err) { - return err; - } - - // TODO should markinuse, etc, take the lookahead buffer? - // TODO do we need to zero now that we're not using the full - // buffer? - - // with an uncontrolled airspace, we need to check if there - // are any in-flight blocks - // - // note with our current implementation this can not contain - // any in-flight graft state - lfs3_trv_t trv; - lfs3_trv_init(&trv, - LFS3_T_RDONLY - | LFS3_T_LOOKAHEAD - | LFS3_T_INFLIGHTONLY); - while (true) { - lfs3_bptr_t bptr; - lfs3_stag_t tag = lfs3_mtree_traverse(lfs3, &trv, - &bptr); - if (tag < 0) { - if (tag == LFS3_ERR_NOENT) { - break; - } - return tag; - } - - // track in-use blocks - lfs3_alloc_markinuse(lfs3, tag, &bptr); - } - - // with a controlled airspace, we can trust all blocks - // states are exact - lfs3_alloc_markfree(lfs3, lfs3_min( - lfs3->gbmap.ctrled, - lfs3->lookahead.ckpoint)); - continue; - } - #endif +// // controlled airspace in our bmap? +// #ifdef LFS3_BMAP +// if (lfs3->gbmap.ctrled > 0) { +// lfs3_ssize_t d = lfs3_bmap_findairspace(lfs3, lfs3_min( +// lfs3->gbmap.ctrled, +// lfs3->lookahead.ckpoint)); +// if (err) { +// return err; +// } +// +// // TODO should markinuse, etc, take the lookahead buffer? +// // TODO do we need to zero now that we're not using the full +// // buffer? +// +// // with a controlled airspace, we can trust all blocks +// // states are exact +// lfs3_alloc_markfree(lfs3, lfs3_min( +// lfs3->gbmap.ctrled, +// lfs3->lookahead.ckpoint)); +// continue; +// } +// #endif +// +// // uncontrolled airspace in our bmap? +// #ifdef LFS3_BMAP +// if (lfs3->gbmap.unctrled > 0) { +// // TODO this needs to know if in-flight blocks count? +// lfs3_ssize_t d = lfs3_bmap_findairspace(lfs3, lfs3_min( +// lfs3->gbmap.unctrled, +// lfs3->lookahead.ckpoint)); +// if (err) { +// return err; +// } +// +// // TODO should markinuse, etc, take the lookahead buffer? +// // TODO do we need to zero now that we're not using the full +// // buffer? +// +// // with an uncontrolled airspace, we need to check if there +// // are any in-flight blocks +// // +// // note with our current implementation this can not contain +// // any in-flight graft state +// lfs3_trv_t trv; +// lfs3_trv_init(&trv, +// LFS3_T_RDONLY +// | LFS3_T_LOOKAHEAD +// | LFS3_T_INFLIGHTONLY); +// while (true) { +// lfs3_bptr_t bptr; +// lfs3_stag_t tag = lfs3_mtree_traverse(lfs3, &trv, +// &bptr); +// if (tag < 0) { +// if (tag == LFS3_ERR_NOENT) { +// break; +// } +// return tag; +// } +// +// // track in-use blocks +// lfs3_alloc_markinuse(lfs3, tag, &bptr); +// } +// +// // with a controlled airspace, we can trust all blocks +// // states are exact +// lfs3_alloc_markfree(lfs3, lfs3_min( +// lfs3->gbmap.ctrled, +// lfs3->lookahead.ckpoint)); +// continue; +// } +// #endif @@ -15241,11 +15216,7 @@ static int lfs3_init(lfs3_t *lfs3, uint32_t flags, #ifdef LFS3_BMAP lfs3_btree_init(&lfs3->gbmap.b); lfs3->gbmap.cursor = 0; - lfs3->gbmap.ctrled = 0; - lfs3->gbmap.unctrled = 0; - lfs3_btree_init(&lfs3->bmap.gbatc); - lfs3->bmap.known = 0; - lfs3->bmap.free = 0; + lfs3->gbmap.known = 0; lfs3_memset(lfs3->gbmap_p, 0, LFS3_GBMAP_DSIZE); lfs3_memset(lfs3->gbmap_d, 0, LFS3_GBMAP_DSIZE); #endif @@ -15321,17 +15292,38 @@ static int lfs3_deinit(lfs3_t *lfs3) { #define LFS3_WCOMPAT_RDONLY 0x00000002 // Writing is disallowed #define LFS3_WCOMPAT_DIR 0x00000010 // Directory files in use #define LFS3_WCOMPAT_GCKSUM 0x00001000 // Global-checksum in use -#define LFS3_WCOMPAT_GBMAP 0x00002000 // Global block-map in use +#define LFS3_WCOMPAT_GBMAP 0x00006000 // Global block-map in use +#define LFS3_WCOMPAT_GBMAPNONE 0x00000000 // Gbmap not in use +#define LFS3_WCOMPAT_GBMAPCACHE 0x00002000 // Gbmap in cache mode +#define LFS3_WCOMPAT_GBMAPVFR 0x00004000 // Gbmap in VFR mode +#define LFS3_WCOMPAT_GBMAPIFR 0x00006000 // Gbmap in IFR mode + // internal #define LFS3_wcompat_OVERFLOW 0x80000000 // Can't represent all flags // TODO this should really be calculated at runtime, we should allow no // gbmap when bmap mode == LFS3_M_BMAPNONE even when compiling with // LFS3_BMAP +#if defined(LFS3_YES_BMAPCACHE) #define LFS3_WCOMPAT_COMPAT \ (LFS3_WCOMPAT_DIR \ | LFS3_WCOMPAT_GCKSUM \ - | LFS3_IFDEF_BMAP(LFS3_WCOMPAT_GBMAP, 0)) + | LFS3_WCOMPAT_GBMAPCACHE) +#elif defined(LFS3_YES_BMAPVFR) +#define LFS3_WCOMPAT_COMPAT \ + (LFS3_WCOMPAT_DIR \ + | LFS3_WCOMPAT_GCKSUM \ + | LFS3_WCOMPAT_GBMAPVFR) +#elif defined(LFS3_YES_BMAPIFR) +#define LFS3_WCOMPAT_COMPAT \ + (LFS3_WCOMPAT_DIR \ + | LFS3_WCOMPAT_GCKSUM \ + | LFS3_WCOMPAT_GBMAPIFR) +#else +#define LFS3_WCOMPAT_COMPAT \ + (LFS3_WCOMPAT_DIR \ + | LFS3_WCOMPAT_GCKSUM) +#endif #define LFS3_OCOMPAT_NONSTANDARD 0x00000001 // Non-standard filesystem format // internal @@ -15826,14 +15818,6 @@ static int lfs3_mountinited(lfs3_t *lfs3) { // TODO switch to read-only? return err; } - - // setup bmap with last known cursor, this will be populated on - // first alloc - LFS3_ASSERT(lfs3->gbmap.unctrled == lfs3->block_count); - lfs3->bmap.gbatc = lfs3->gbmap.b; - lfs3->bmap.cursor = lfs3->gbmap.cursor; - lfs3->bmap.known = lfs3->gbmap.unctrled; - lfs3->bmap.free = 0; #endif return 0; @@ -15887,14 +15871,12 @@ int lfs3_mount(lfs3_t *lfs3, uint32_t flags, #ifdef LFS3_YES_CKDATA flags |= LFS3_M_CKDATA #endif - #if defined(LFS3_YES_BMAPFAST) - flags = (flags & ~LFS3_M_BMAPMODE) | LFS3_M_BMAPFAST; - #elif defined(LFS3_YES_BMAPSLOW) - flags = (flags & ~LFS3_M_BMAPMODE) | LFS3_M_BMAPSLOW; - #elif defined(LFS3_YES_BMAPCACHE) + #if defined(LFS3_YES_BMAPCACHE) flags = (flags & ~LFS3_M_BMAPMODE) | LFS3_M_BMAPCACHE; - #elif defined(LFS3_YES_BMAPNONE) - flags = (flags & ~LFS3_M_BMAPMODE) | LFS3_M_BMAPNONE; + #elif defined(LFS3_YES_BMAPVFR) + flags = (flags & ~LFS3_M_BMAPMODE) | LFS3_M_BMAPVFR; + #elif defined(LFS3_YES_BMAPIFR) + flags = (flags & ~LFS3_M_BMAPMODE) | LFS3_M_BMAPIFR; #endif // unknown flags? diff --git a/lfs3.h b/lfs3.h index 6cf0d8e4..2f8a1972 100644 --- a/lfs3.h +++ b/lfs3.h @@ -193,12 +193,12 @@ enum lfs3_type { #define LFS3_F_CKDATA 0x00002000 // Check metadata + data checksums #ifdef LFS3_BMAP -#define LFS3_F_BMAPMODE 0x03000000 // On-disk block map mode +#define LFS3_F_BMAPMODE 0x03000000 // On-disk block-map mode #define LFS3_F_BMAPNONE 0x00000000 // Don't use the bmap #define LFS3_F_BMAPCACHE \ 0x01000000 // Use the bmap to cache lookahead scans -#define LFS3_F_BMAPSLOW 0x02000000 // Use the slow bmap algorithm -#define LFS3_F_BMAPFAST 0x03000000 // Use the fast bmap algorithm +#define LFS3_F_BMAPVFR 0x02000000 // Use the bmap in VFR mode +#define LFS3_F_BMAPIFR 0x03000000 // Use the bmap in IFR mode #endif #endif @@ -248,11 +248,11 @@ enum lfs3_type { #ifdef LFS3_BMAP #define LFS3_M_BMAPMODE 0x03000000 // On-disk block map mode -#define LFS3_M_BMAPNONE 0x00000000 // Don't use the bmap +#define LFS3_M_BMAPNONE 0x00000000 // Don't use bmap #define LFS3_M_BMAPCACHE \ 0x01000000 // Use the bmap to cache lookahead scans -#define LFS3_M_BMAPSLOW 0x02000000 // Use the slow bmap algorithm -#define LFS3_M_BMAPFAST 0x03000000 // Use the fast bmap algorithm +#define LFS3_M_BMAPVFR 0x02000000 // Use the bmap in VFR mode +#define LFS3_M_BMAPIFR 0x03000000 // Use the bmap in IFR mode #endif @@ -301,8 +301,8 @@ enum lfs3_type { #define LFS3_I_BMAPNONE 0x00000000 // Mounted with LFS3_M_BMAPNONE #define LFS3_I_BMAPCACHE \ 0x01000000 // Mounted with LFS3_M_BMAPCACHE -#define LFS3_I_BMAPSLOW 0x02000000 // Mounted with LFS3_M_BMAPSLOW -#define LFS3_I_BMAPFAST 0x03000000 // Mounted with LFS3_M_BMAPFAST +#define LFS3_I_BMAPVFR 0x02000000 // Mounted with LFS3_M_BMAPVFR +#define LFS3_I_BMAPIFR 0x03000000 // Mounted with LFS3_M_BMAPIFR #endif // internally used flags, don't use these @@ -843,25 +843,22 @@ typedef struct lfs3_grm { } lfs3_grm_t; // gbmap encoding: -// .---+- -+- -+- -+- -. cursor: 1 leb128 <=5 bytes -// | cursor | ctrled: 1 leb128 <=5 bytes -// +---+- -+- -+- -+- -+ unctrled: 1 leb128 <=5 bytes -// | ctrled | block: 1 leb128 <=5 bytes -// +---+- -+- -+- -+- -+ trunk: 1 leb128 <=4 bytes -// | unctrled | cksum: 1 le32 4 bytes -// +---+- -+- -+- -+- -+ total: 28 bytes -// | block | +// .---+- -+- -+- -+- -. cursor: 1 leb128 <=5 bytes +// | cursor | known: 1 leb128 <=5 bytes +// +---+- -+- -+- -+- -+ block: 1 leb128 <=5 bytes +// | known | trunk: 1 leb128 <=4 bytes +// +---+- -+- -+- -+- -+ cksum: 1 le32 4 bytes +// | block | total: 23 bytes // +---+- -+- -+- -+- -' // | trunk | // +---+- -+- -+- -+ // | cksum | // '---+---+---+---' -#define LFS3_GBMAP_DSIZE (5+5+5+5+4+4) +#define LFS3_GBMAP_DSIZE (5+5+5+4+4) typedef struct lfs3_gbmap { lfs3_block_t cursor; - lfs3_block_t ctrled; - lfs3_block_t unctrled; + lfs3_block_t known; lfs3_btree_t b; } lfs3_gbmap_t; @@ -952,18 +949,7 @@ typedef struct lfs3 { uint8_t grm_d[LFS3_GRM_DSIZE]; #if !defined(LFS3_RDONLY) && !defined(LFS3_2BONLY) && defined(LFS3_BMAP) - // TODO do we only need known for the in-flight block-map? - // on-disk block-map lfs3_gbmap_t gbmap; - // in-flight block-map - struct { - lfs3_block_t cursor; - lfs3_block_t known; - lfs3_block_t free; - //lfs3_block_t erased; // TODO - lfs3_btree_t gbatc; - } bmap; - // block-map delta state uint8_t gbmap_p[LFS3_GBMAP_DSIZE]; uint8_t gbmap_d[LFS3_GBMAP_DSIZE]; #endif diff --git a/lfs3_util.h b/lfs3_util.h index 36fdff95..29eab2a7 100644 --- a/lfs3_util.h +++ b/lfs3_util.h @@ -87,22 +87,24 @@ #define LFS3_BMAP #endif -// TODO is this the best way to structure this? // LFS3_BMAP mappings // -// LFS3_YES_BMAP => LFS3_YES_BMAPFAST -#ifdef LFS3_YES_BMAP -#ifndef LFS3_YES_BMAPFAST -#define LFS3_YES_BMAPFAST -#endif -#endif +// TODO eventually allow runtime flags +// // LFS3_YES_BMAP* => LFS3_BMAP -#if defined(LFS3_YES_BMAPFAST) \ - || defined(LFS3_YES_BMAPSLOW) \ - || defined(LFS3_YES_BMAPCACHE) \ - || defined(LFS3_YES_BMAPNONE) +#if defined(LFS3_YES_BMAPCACHE) \ + || defined(LFS3_YES_BMAPVFR) \ + || defined(LFS3_YES_BMAPIFR) #define LFS3_BMAP #endif +// TODO figure out the best default bmap mode +// if LFS3_BMAP but no algorithm defined, default to LFS3_YES_BMAPCACHE +#if defined(LFS3_BMAP) \ + && !defined(LFS3_BMAPCACHE) \ + && !defined(LFS3_BMAPVFR) \ + && !defined(LFS3_BMAPIFR) +#define LFS3_YES_BMAPCACHE +#endif // LFS3_NO_LOG disables all logging macros #ifdef LFS3_NO_LOG diff --git a/scripts/dbgbmap.py b/scripts/dbgbmap.py index ece22ba3..633b2e4e 100755 --- a/scripts/dbgbmap.py +++ b/scripts/dbgbmap.py @@ -2774,8 +2774,7 @@ class Gstate: super().__init__(mtree, config, tag, gdeltas) d = 0 self.cursor, d_ = fromleb128(self.data, d); d += d_ - self.ctrled, d_ = fromleb128(self.data, d); d += d_ - self.unctrled, d_ = fromleb128(self.data, d); d += d_ + self.known, d_ = fromleb128(self.data, d); d += d_ block, trunk, cksum, d_ = frombranch(self.data, d); d += d_ self.btree = Btree.fetchck( mtree.bd, block, trunk, @@ -2783,9 +2782,9 @@ class Gstate: cksum) def repr(self): - return 'gbmap %s %d+%d' % ( + return 'gbmap %s 0x%x %d' % ( self.btree.addr(), - self.ctrled, self.unctrled) + self.cursor, self.known) # keep track of known gstate _known = [g for g in Gstate.__subclasses__() if g.tag is not None] diff --git a/scripts/dbgbmapsvg.py b/scripts/dbgbmapsvg.py index c8613363..3e522454 100755 --- a/scripts/dbgbmapsvg.py +++ b/scripts/dbgbmapsvg.py @@ -2804,8 +2804,7 @@ class Gstate: super().__init__(mtree, config, tag, gdeltas) d = 0 self.cursor, d_ = fromleb128(self.data, d); d += d_ - self.ctrled, d_ = fromleb128(self.data, d); d += d_ - self.unctrled, d_ = fromleb128(self.data, d); d += d_ + self.known, d_ = fromleb128(self.data, d); d += d_ block, trunk, cksum, d_ = frombranch(self.data, d); d += d_ self.btree = Btree.fetchck( mtree.bd, block, trunk, @@ -2813,9 +2812,9 @@ class Gstate: cksum) def repr(self): - return 'gbmap %s %d+%d' % ( + return 'gbmap %s 0x%x %d' % ( self.btree.addr(), - self.ctrled, self.unctrled) + self.cursor, self.known) # keep track of known gstate _known = [g for g in Gstate.__subclasses__() if g.tag is not None] diff --git a/scripts/dbgflags.py b/scripts/dbgflags.py index e93f432e..b7cc8df8 100755 --- a/scripts/dbgflags.py +++ b/scripts/dbgflags.py @@ -72,11 +72,11 @@ FLAGS = [ ('F_CKMETA', 0x00001000, "Check metadata checksums" ), ('F_CKDATA', 0x00002000, "Check metadata + data checksums" ), - ('F_BMAPMODE', 0x03000000, "On-disk block map mode" ), + ('F_BMAPMODE', 0x03000000, "On-disk block-map mode" ), ('^_BMAPNONE', 0x00000000, "Don't use the bmap" ), ('^_BMAPCACHE', 0x01000000, "Use the bmap to cache lookahead scans" ), - ('^_BMAPSLOW', 0x02000000, "Use the slow bmap algorithm" ), - ('^_BMAPFAST', 0x03000000, "Use the fast bmap algorithm" ), + ('^_BMAPVFR', 0x02000000, "Use the bmap in VFR mode" ), + ('^_BMAPIFR', 0x03000000, "Use the bmap in IFR mode" ), # Filesystem mount flags ('M_MODE', 1, "Mount's access mode" ), @@ -97,11 +97,11 @@ FLAGS = [ ('M_CKMETA', 0x00001000, "Check metadata checksums" ), ('M_CKDATA', 0x00002000, "Check metadata + data checksums" ), - ('M_BMAPMODE', 0x03000000, "On-disk block map mode" ), + ('M_BMAPMODE', 0x03000000, "On-disk block-map mode" ), ('^_BMAPNONE', 0x00000000, "Don't use the bmap" ), ('^_BMAPCACHE', 0x01000000, "Use the bmap to cache lookahead scans" ), - ('^_BMAPSLOW', 0x02000000, "Use the slow bmap algorithm" ), - ('^_BMAPFAST', 0x03000000, "Use the fast bmap algorithm" ), + ('^_BMAPVFR', 0x02000000, "Use the bmap in VFR mode" ), + ('^_BMAPIFR', 0x03000000, "Use the bmap in IFR mode" ), # GC flags ('GC_MKCONSISTENT',0x00000100, "Make the filesystem consistent" ), @@ -127,11 +127,11 @@ FLAGS = [ ('I_CKMETA', 0x00001000, "Metadata checksums not checked recently" ), ('I_CKDATA', 0x00002000, "Data checksums not checked recently" ), - ('I_BMAPMODE', 0x03000000, "On-disk block map mode" ), + ('I_BMAPMODE', 0x03000000, "On-disk block-map mode" ), ('^_BMAPNONE', 0x00000000, "Mounted with LFS3_M_BMAPNONE" ), ('^_BMAPCACHE', 0x01000000, "Mounted with LFS3_M_BMAPCACHE" ), - ('^_BMAPSLOW', 0x02000000, "Mounted with LFS3_M_BMAPSLOW" ), - ('^_BMAPFAST', 0x03000000, "Mounted with LFS3_M_BMAPFAST" ), + ('^_BMAPVFR', 0x02000000, "Mounted with LFS3_M_BMAPVFR" ), + ('^_BMAPIFR', 0x03000000, "Mounted with LFS3_M_BMAPIFR" ), ('i_INMTREE', 0x00030000, "Committing to mtree" ), ('^_INMTREE', 0x00010000, "Committing to mtree" ), @@ -202,7 +202,11 @@ FLAGS = [ ('WCOMPAT_RDONLY', 0x00000002, "Writing is disallowed" ), ('WCOMPAT_DIR', 0x00000010, "Directory file types in use" ), ('WCOMPAT_GCKSUM', 0x00001000, "Global-checksum in use" ), - ('WCOMPAT_GBMAP', 0x00002000, "Global block-map in use" ), + ('WCOMPAT_GBMAP', 0x00006000, "Global block-map in use" ), + ('^_GBMAPNONE', 0x00000000, "Gbmap not in use" ), + ('^_GBMAPCACHE', 0x00002000, "Gbmap in cache mode" ), + ('^_GBMAPVFR', 0x00004000, "Gbmap in VFR mode" ), + ('^_GBMAPIFR', 0x00006000, "Gbmap in IFR mode" ), ('wcompat_OVERFLOW', 0x80000000, "Can't represent all flags" ), diff --git a/scripts/dbglfs3.py b/scripts/dbglfs3.py index 959beda2..5af36289 100755 --- a/scripts/dbglfs3.py +++ b/scripts/dbglfs3.py @@ -2731,8 +2731,7 @@ class Gstate: super().__init__(mtree, config, tag, gdeltas) d = 0 self.cursor, d_ = fromleb128(self.data, d); d += d_ - self.ctrled, d_ = fromleb128(self.data, d); d += d_ - self.unctrled, d_ = fromleb128(self.data, d); d += d_ + self.known, d_ = fromleb128(self.data, d); d += d_ block, trunk, cksum, d_ = frombranch(self.data, d); d += d_ self.btree = Btree.fetchck( mtree.bd, block, trunk, @@ -2740,9 +2739,9 @@ class Gstate: cksum) def repr(self): - return 'gbmap %s %d+%d' % ( + return 'gbmap %s 0x%x %d' % ( self.btree.addr(), - self.ctrled, self.unctrled) + self.cursor, self.known) # keep track of known gstate _known = [g for g in Gstate.__subclasses__() if g.tag is not None]