]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/fs/rock/RockRebuild.cc
Source Format Enforcement (#1234)
[thirdparty/squid.git] / src / fs / rock / RockRebuild.cc
index c8e641b190bb814733fad5b42844be637425c0ba..4d5790c599255961975644464c153452a677618a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
@@ -10,7 +10,7 @@
 
 #include "squid.h"
 #include "base/AsyncJobCalls.h"
-#include "DebugMessages.h"
+#include "debug/Messages.h"
 #include "fs/rock/RockDbCell.h"
 #include "fs/rock/RockRebuild.h"
 #include "fs/rock/RockSwapDir.h"
 #include "globals.h"
 #include "md5.h"
 #include "sbuf/Stream.h"
-#include "SquidTime.h"
 #include "Store.h"
 #include "tools.h"
 
+#include <array>
 #include <cerrno>
+#include <cstring>
 
 CBDATA_NAMESPACED_CLASS_INIT(Rock, Rebuild);
 
@@ -441,7 +442,7 @@ Rock::Rebuild::loadingSteps()
         getCurrentTime();
         const double elapsedMsec = tvSubMsec(loopStart, current_time);
         if (elapsedMsec > maxSpentMsec || elapsedMsec < 0) {
-            debugs(47, 5, HERE << "pausing after " << loaded << " entries in " <<
+            debugs(47, 5, "pausing after " << loaded << " entries in " <<
                    elapsedMsec << "ms; " << (elapsedMsec/loaded) << "ms per entry");
             break;
         }
@@ -508,6 +509,22 @@ Rock::Rebuild::loadOneSlot()
     useNewSlot(slotId, header);
 }
 
+/// whether the given slot buffer is likely to have nothing but zeros, as is
+/// common to slots in pre-initialized (with zeros) db files
+static bool
+ZeroedSlot(const MemBuf &buf)
+{
+    // We could memcmp the entire buffer, but it is probably safe enough to test
+    // a few bytes because even if we do not detect a corrupted entry, it is not
+    // a big deal: Store::UnpackPrefix() rejects all-0s metadata prefix.
+    static const std::array<char, 10> zeros = {};
+
+    if (static_cast<size_t>(buf.contentSize()) < zeros.size())
+        return false; // cannot be sure enough
+
+    return memcmp(buf.content(), zeros.data(), zeros.size()) == 0;
+}
+
 /// parse StoreEntry basics and add them to the map, returning true on success
 bool
 Rock::Rebuild::importEntry(Ipc::StoreMapAnchor &anchor, const sfileno fileno, const DbCellHeader &header)
@@ -516,6 +533,10 @@ Rock::Rebuild::importEntry(Ipc::StoreMapAnchor &anchor, const sfileno fileno, co
     StoreEntry loadedE;
     const uint64_t knownSize = header.entrySize > 0 ?
                                header.entrySize : anchor.basics.swap_file_sz.load();
+
+    if (ZeroedSlot(buf))
+        return false;
+
     if (!storeRebuildParseEntry(buf, loadedE, key, counts, knownSize))
         return false;
 
@@ -668,7 +689,7 @@ Rock::Rebuild::freeBadEntry(const sfileno fileno, const char *eDescription)
 void
 Rock::Rebuild::swanSong()
 {
-    debugs(47,3, HERE << "cache_dir #" << sd->index << " rebuild level: " <<
+    debugs(47,3, "cache_dir #" << sd->index << " rebuild level: " <<
            StoreController::store_dirs_rebuilding);
     storeRebuildComplete(&counts);
 }