]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Use Rock::IoState::writeableAnchor_ to detect rock entries open for writing.
authorAlex Rousskov <rousskov@measurement-factory.com>
Wed, 10 Jul 2013 00:41:01 +0000 (18:41 -0600)
committerAlex Rousskov <rousskov@measurement-factory.com>
Wed, 10 Jul 2013 00:41:01 +0000 (18:41 -0600)
Just e.mem_obj->swapout.sio presence is not reliable enough because we
may switch from writing to reading while the [writing] sio is still around.

More explicitly disabled on-disk collapsing of entries. The relevant code is
unstable under load [at least when combined with memory caching]. We were not
calling Ipc::StoreMap::startAppending() before so we probably did not fully
disk-collapsed entries before these temporary changes.

Added an XXX to mark an assert() that may fail if we allow on-disk collapsing.

src/fs/rock/RockIoState.cc
src/fs/rock/RockSwapDir.cc

index 5646d075fba98ff730d13a4b2e6e28f3462f34c5..a202e3db8830e37f52d0b56a07a6e8fdaecd08f5 100644 (file)
@@ -177,7 +177,7 @@ Rock::IoState::tryWrite(char const *buf, size_t size, off_t coreOff)
             const SlotId sidNext = reserveSlotForWriting(); // throws
             assert(sidNext >= 0);
             writeToDisk(sidNext);
-        } else if (Store::Root().transientReaders(*e)) {
+        } else if (false && Store::Root().transientReaders(*e)) {
             // write partial buffer for all remote hit readers to see
             writeBufToDisk(-1);
         }
@@ -283,7 +283,7 @@ void
 Rock::IoState::finishedWriting(const int errFlag)
 {
     // we incremented offset_ while accumulating data in write()
-    writeableAnchor_ = NULL;
+    // we do not reset writeableAnchor_ here because we still keep the lock
     CollapsedForwarding::Broadcast(*e);
     callBack(errFlag);
 }
@@ -297,7 +297,7 @@ Rock::IoState::close(int how)
     if (!theFile) {
         debugs(79, 3, "I/O already canceled");
         assert(!callback);
-        assert(!writeableAnchor_);
+        // We keep writeableAnchor_ after callBack() on I/O errors.
         assert(!readableAnchor_);
         return;
     }
index 7c0c1effdbf79bc83a13c58b6b92bfe0b741f3fe..a81da20459e636c603af2004d636889156d58226 100644 (file)
@@ -83,7 +83,7 @@ Rock::SwapDir::get(const cache_key *key)
 bool
 Rock::SwapDir::anchorCollapsed(StoreEntry &collapsed, bool &inSync)
 {
-    if (!map || !theFile || !theFile->canRead())
+    if (true || !map || !theFile || !theFile->canRead())
         return false;
 
     sfileno filen;
@@ -161,13 +161,16 @@ void Rock::SwapDir::disconnect(StoreEntry &e)
     // before it switches from SWAPOUT_WRITING to SWAPOUT_DONE.
 
     // since e has swap_filen, its slot is locked for reading and/or writing
-    // but it is difficult to know whether THIS worker is reading or writing e
-    if (e.swap_status == SWAPOUT_WRITING ||
-        (e.mem_obj && e.mem_obj->swapout.sio != NULL)) {
+    // but it is difficult to know whether THIS worker is reading or writing e,
+    // especially since we may switch from writing to reading. This code relies
+    // on Rock::IoState::writeableAnchor_ being set when we locked for writing.
+    if (e.mem_obj && e.mem_obj->swapout.sio != NULL &&
+        dynamic_cast<IoState&>(*e.mem_obj->swapout.sio).writeableAnchor_) {
         map->abortWriting(e.swap_filen);
         e.swap_dirn = -1;
         e.swap_filen = -1;
         e.swap_status = SWAPOUT_NONE;
+        dynamic_cast<IoState&>(*e.mem_obj->swapout.sio).writeableAnchor_ = NULL;
         Store::Root().transientsAbandon(e); // broadcasts after the change
     } else {
         map->closeForReading(e.swap_filen);
@@ -750,6 +753,7 @@ Rock::SwapDir::openStoreIO(StoreEntry &e, StoreIOState::STFNCB *cbFile, StoreIOS
 
     assert(slot->sameKey(static_cast<const cache_key*>(e.key)));
     assert(slot->basics.swap_file_sz > 0);
+    // XXX: basics.swap_file_sz may grow for collapsed disk hits
     assert(slot->basics.swap_file_sz == e.swap_file_sz);
 
     return sio;
@@ -822,6 +826,7 @@ Rock::SwapDir::writeCompleted(int errflag, size_t rlen, RefCount< ::WriteRequest
         if (request->sidNext < 0) {
             // close, the entry gets the read lock
             map->closeForWriting(sio.swap_filen, true);
+            sio.writeableAnchor_ = NULL;
             sio.finishedWriting(errflag);
         }
     } else {