-
Type:
Bug
-
Resolution: Unresolved
-
Priority:
Minor - P4
-
None
-
Affects Version/s: None
-
Component/s: Block Manager
-
None
-
Storage Engines - Persistence
-
195.411
-
SE Persistence backlog
-
None
_wti_block_disagg_open walks conn->blockhash to find an existing block handle for a filename. That list holds both WT_BLOCK and WT_BLOCK_DISAGG entries, inserted by wt_block_open and _wti_block_disagg_open respectively, and the lookup does not distinguish them. A pre-existing TODO on the loop records this:
TAILQ_FOREACH (block, &conn->blockhash[bucket], hashq) {
/* TODO: Should check to make sure this is the right type of block */
if (strcmp(filename, block->name) == 0 && ((WT_BLOCK_DISAGG *)block)->tableid == tableid) {
The comparison now reads tableid, which is the first field past the prefix WT_BLOCK and WT_BLOCK_DISAGG share, so for a plain WT_BLOCK in the same bucket it reinterprets WT_BLOCK::fh (a pointer) as an integer table ID. WT_BLOCK is the larger structure, so there is no out-of-bounds read, and the practical outcome is a benign failure to match. The lookup is nonetheless relying on a type it does not verify.
Add a type discriminator to the shared prefix, or key the hash on it, so the lookup only ever compares disaggregated fields on a disaggregated block.
Found while reviewing WT-18068, which added the table ID comparison on that line.
- is related to
-
WT-18068 Follower reads stale btree ID after leader create/drop/create of a layered table
-
- In Code Review
-