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.
This commit is contained in:
+3
-4
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user