]> git.ipfire.org Git - thirdparty/squid.git/commit
Initialize StoreMapSlice when reserving a new cache slot (#350)
authorEduard Bagdasaryan <eduard.bagdasaryan@measurement-factory.com>
Wed, 23 Jan 2019 03:51:12 +0000 (03:51 +0000)
committerSquid Anubis <squid-anubis@squid-cache.org>
Wed, 23 Jan 2019 03:51:16 +0000 (03:51 +0000)
commitc203754768afb698246d9dd1f9f650403eca0382
tree749471009bb15bdce025ca1ea8706165e4a9b707
parent387e1d45ae60c35240f4b364c9cdcc8f8bd2fd45
Initialize StoreMapSlice when reserving a new cache slot (#350)

Rock sets the StoreMapSlice::next field when sending a slice to disk. To
avoid writing slice A twice, Rock allocates a new slice B to prime
A.next right before writing A. Scheduling A's writing and, sometimes,
lack of data to fill B create a gap between B's allocation and B's
writing (which sets B.next). During that time, A.next points to B, but
B.next is untouched.

If writing slice A or swapout in general fails, the chain of failed
entry slices (now containing both A and B) is freed. If untouched B.next
contains garbage, then freeChainAt() adds "random" slices after B to the
free slice pool. Subsequent swapouts use those incorrectly freed slices,
effectively overwriting portions of random cache entries, corrupting the
cache.

How did B.next get dirty in the first place? freeChainAt() cleans the
slices it frees, but Rock also makes direct noteFreeMapSlice() calls.
Shared memory cache may have avoided this corruption because it makes no
such calls.

Ipc::StoreMap::prepFreeSlice() now clears allocated slices. Long-term,
we may be able to move free slice management into StoreMap to automate
this cleanup.

Also simplified and polished slot allocation code a little, removing the
Rock::IoState::reserveSlotForWriting() middleman. This change also
improves the symmetry between Rock and shared memory cache code.
src/MemStore.cc
src/fs/rock/RockIoState.cc
src/fs/rock/RockIoState.h
src/fs/rock/RockSwapDir.cc
src/fs/rock/RockSwapDir.h
src/ipc/StoreMap.cc
src/ipc/StoreMap.h