From: Alex Rousskov Date: Sun, 20 Jan 2013 01:53:24 +0000 (-0700) Subject: Polished entry freeing. X-Git-Tag: SQUID_3_5_0_1~444^2~76 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=485466dce97e53d21515a04b52a6c1e9246550e2;p=thirdparty%2Fsquid.git Polished entry freeing. Clean Writeable entries in addition to Readables ones. Otherwise, there is no way for the caller to completely get rid of a [large] entry the caller has been writing! We hold the lock so this should be safe as long as slice.next (and slice extras) are valid even in a half-baked Writeable entry. Reset slice.next [before giving it to the caller]. As a consequence, we must free individual slices even if cleaner is not set. --- diff --git a/src/ipc/StoreMap.cc b/src/ipc/StoreMap.cc index 99a040c9c7..ac7eb27698 100644 --- a/src/ipc/StoreMap.cc +++ b/src/ipc/StoreMap.cc @@ -229,12 +229,15 @@ Ipc::StoreMap::freeChain(const sfileno fileno, Anchor &inode, const bool keepLoc { debugs(54, 7, "freeing " << inode.state << " entry " << fileno << " in map [" << path << ']'); - if (inode.state == Anchor::Readable && cleaner) { + if (inode.state != Anchor::Empty) { sfileno sliceId = inode.start; debugs(54, 7, "first slice " << sliceId); while (sliceId >= 0) { - const sfileno nextId = shared->slots[sliceId].slice.next; - cleaner->noteFreeMapSlice(sliceId); // might change slice state + Slice &slice = shared->slots[sliceId].slice; + const sfileno nextId = slice.next; + slice.next = -1; + if (cleaner) + cleaner->noteFreeMapSlice(sliceId); // might change slice state sliceId = nextId; } }