Views: raise the durable reader floor before creating the v3 lock namespace

Merged
AF
5d ago
+117-8

With views on, the first v3 registration on a project could create blobs/v3 and its reservation lock before the durable reader floor was raised. During that window, a v0.60.0 reader could open storage that already held v3 data. The floor guard storage_retention::v3_collector_tests::no_production_path_writes_v3_over_a_v0_60_0_floor caught it intermittently, most recently in #1116's Windows queue run, and it kept knocking PRs out of the queue.

  • Cause: ReservationLock::acquire and acquire_until (blob_store/v3.rs) created the namespace directory and lock file. Registration reaches with_base_barrier, which takes that lock before the registry opener raises the floor (views/base_refs.rs). The semantic publisher already raised its floor before taking the lock, so the failure depended on which operation reached storage first. This is pre-existing, and main alone is affected; it is not a regression from #1116 or #1118.
  • Fix: a shared prepare_path raises the combined durable version-1 floor via reader_floor::publish_v3_with_floor before creating the namespace or the lock file, for both acquire paths. Registry openers still raise any higher schema floor themselves. If the floor raise fails, nothing is created. The guard is unchanged.
  • Tests: v3_first_registration_and_lock_raise_floor_before_namespace makes registration the first v3 operation on a captured v0.60.0 floor. It fails without the fix on Linux, native Windows, macOS, main alone and #1116 alone. A Unix regression injects a floor-directory sync failure on both acquire APIs and requires a real sync before the namespace exists.

Views are off by default, so this blocks only views-on users and turning views on by default. Verified on the build server: the floor collector tests three times, 129 v3 store and reader-floor tests, and the Windows target check. The worker also ran the collector gate on native Windows and macOS.


Summary by cubic

Fixes a race where, with views on, the first v3 registration could create the blobs/v3 namespace and its reservation lock before the durable reader floor was raised, letting a v0.60.0 reader open storage that already held v3 data. Views are off by default, so only views-on users are affected.

Bug Fixes

  • Both ReservationLock::acquire and acquire_until now raise the v3 reader floor via a shared prepare_path before creating the namespace or lock file; a failed floor raise leaves nothing created.
  • Registry openers still raise any higher schema floor themselves.

Tests

  • A regression makes registration (and both lock paths) the first v3 operation on a v0.60.0 floor; it fails without the fix on Linux, native Windows, and macOS.
  • A Unix test injects a floor-directory sync failure on both acquire APIs and requires a real sync before the namespace exists.
  • Adds a search-quality descriptor tracking the fix as a non-ranking slice.