-
Type:
Bug
-
Resolution: Fixed
-
Priority:
Major - P3
-
Affects Version/s: None
-
Component/s: Checkpoints
-
None
-
Storage Engines - Persistence
-
59.204
-
None
-
None
Right now __wti_block_disagg_decrease_size loads the size, checks it for underflow, and then subtracts in a separate atomic op. Those are three independent steps, so theres a window between the load/check and the subtract where another thread can change the size out from under us. That means we can end up subtracting from a value we never validated, so the underflow check doesnt actually guarantee anything and the clamp-to-zero can be wrong.
The fix is to fold the check and the decrement into a single CAS loop, i.e.:
do { orig = __wt_atomic_load_uint64(&block_disagg->size); } while (!__wt_atomic_cas_uint64(&block_disagg->size, orig, orig < size ? 0 : orig - size));
This way we only ever subtract from the same value we read, and the CAS guarantees nothing slipped in between. If
the CAS fails it just means a concurrent update beat us to it, so we reload and retry.