/*
- * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
*
* Squid software is distributed under GPLv2+ license and includes
* contributions from numerous individuals and organizations.
Rock::SwapDir::noteFreeMapSlice(const Ipc::StoreMapSliceId sliceId)
{
Ipc::Mem::PageId pageId;
- pageId.pool = index+1;
+ pageId.pool = Ipc::Mem::PageStack::IdForSwapDirSpace(index);
pageId.number = sliceId+1;
if (waitingForPage) {
*waitingForPage = pageId;
ReadRequest *request = dynamic_cast<Rock::ReadRequest*>(r.getRaw());
assert(request);
IoState::Pointer sio = request->sio;
-
- if (errflag == DISK_OK && rlen > 0)
- sio->offset_ += rlen;
-
- sio->callReaderBack(r->buf, rlen);
+ sio->handleReadCompletion(*request, rlen, errflag);
}
void
Rock::SwapDir::writeCompleted(int errflag, size_t, RefCount< ::WriteRequest> r)
{
+ // TODO: Move details into IoState::handleWriteCompletion() after figuring
+ // out how to deal with map access. See readCompleted().
+
Rock::WriteRequest *request = dynamic_cast<Rock::WriteRequest*>(r.getRaw());
assert(request);
assert(request->sio != NULL);
// quit if somebody called IoState::close() while we were waiting
if (!sio.stillWaiting()) {
debugs(79, 3, "ignoring closed entry " << sio.swap_filen);
- noteFreeMapSlice(request->sidNext);
+ noteFreeMapSlice(request->sidCurrent);
return;
}
if (errflag != DISK_OK)
handleWriteCompletionProblem(errflag, *request);
- else if (droppedEarlierRequest(*request))
+ else if (!sio.expectedReply(request->id))
handleWriteCompletionProblem(DISK_ERROR, *request);
else
handleWriteCompletionSuccess(*request);
sio.splicingPoint = request.sidCurrent;
// do not increment sio.offset_ because we do it in sio->write()
- // finalize the shared slice info after writing slice contents to disk
+ assert(sio.writeableAnchor_);
+ if (sio.writeableAnchor_->start < 0) { // wrote the first slot
+ Must(request.sidPrevious < 0);
+ sio.writeableAnchor_->start = request.sidCurrent;
+ } else {
+ Must(request.sidPrevious >= 0);
+ map->writeableSlice(sio.swap_filen, request.sidPrevious).next = request.sidCurrent;
+ }
+
+ // finalize the shared slice info after writing slice contents to disk;
+ // the chain gets possession of the slice we were writing
Ipc::StoreMap::Slice &slice =
map->writeableSlice(sio.swap_filen, request.sidCurrent);
slice.size = request.len - sizeof(DbCellHeader);
- slice.next = request.sidNext;
+ Must(slice.next < 0);
if (request.eof) {
assert(sio.e);
- assert(sio.writeableAnchor_);
if (sio.touchingStoreEntry()) {
sio.e->swap_file_sz = sio.writeableAnchor_->basics.swap_file_sz =
sio.offset_;
{
auto &sio = *request.sio;
- noteFreeMapSlice(request.sidNext);
+ noteFreeMapSlice(request.sidCurrent);
writeError(sio);
sio.finishedWriting(errflag);
// All callers must also call IoState callback, to propagate the error.
}
-/// whether the disk has dropped at least one of the previous write requests
-bool
-Rock::SwapDir::droppedEarlierRequest(const WriteRequest &request) const
-{
- const auto &sio = *request.sio;
- assert(sio.writeableAnchor_);
- const Ipc::StoreMapSliceId expectedSliceId = sio.splicingPoint < 0 ?
- sio.writeableAnchor_->start :
- map->writeableSlice(sio.swap_filen, sio.splicingPoint).next;
- if (expectedSliceId != request.sidCurrent) {
- debugs(79, 3, "yes; expected " << expectedSliceId << ", but got " << request.sidCurrent);
- return true;
- }
-
- return false;
-}
-
void
Rock::SwapDir::updateHeaders(StoreEntry *updatedE)
{
// TODO: somehow remove pool id and counters from PageStack?
Ipc::Mem::Owner<Ipc::Mem::PageStack> *const freeSlotsOwner =
shm_new(Ipc::Mem::PageStack)(sd->freeSlotsPath(),
- i+1, capacity, 0);
+ Ipc::Mem::PageStack::IdForSwapDirSpace(i),
+ capacity,
+ 0);
freeSlotsOwners.push_back(freeSlotsOwner);
// TODO: add method to initialize PageStack with no free pages