]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/fs/rock/RockSwapDir.cc
Source Format Enforcement (#532)
[thirdparty/squid.git] / src / fs / rock / RockSwapDir.cc
index b738a5a06ab00ace406bc8bab82d354a16b85d00..ac324aac5fc0faa904f831fdb3fa7d20224cac3c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -754,7 +754,7 @@ void
 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;
@@ -845,16 +845,15 @@ Rock::SwapDir::readCompleted(const char *, int rlen, int errflag, RefCount< ::Re
     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);
@@ -863,7 +862,7 @@ Rock::SwapDir::writeCompleted(int errflag, size_t, RefCount< ::WriteRequest> r)
     // 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;
     }
 
@@ -871,7 +870,7 @@ Rock::SwapDir::writeCompleted(int errflag, size_t, RefCount< ::WriteRequest> r)
 
     if (errflag != DISK_OK)
         handleWriteCompletionProblem(errflag, *request);
-    else if (droppedEarlierRequest(*request))
+    else if (!sio.expectedReply(request->id))
         handleWriteCompletionProblem(DISK_ERROR, *request);
     else
         handleWriteCompletionSuccess(*request);
@@ -888,15 +887,24 @@ Rock::SwapDir::handleWriteCompletionSuccess(const WriteRequest &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_;
@@ -915,7 +923,7 @@ Rock::SwapDir::handleWriteCompletionProblem(const int errflag, const WriteReques
 {
     auto &sio = *request.sio;
 
-    noteFreeMapSlice(request.sidNext);
+    noteFreeMapSlice(request.sidCurrent);
 
     writeError(sio);
     sio.finishedWriting(errflag);
@@ -936,23 +944,6 @@ Rock::SwapDir::writeError(StoreIOState &sio)
     // 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)
 {
@@ -1147,7 +1138,9 @@ void Rock::SwapDirRr::create()
             // 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