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.
{
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;
}
}