]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/fs/ufs/RebuildState.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / fs / ufs / RebuildState.cc
index f028bf19390f192e78015a917b9f7b95e94d19e9..2609d43dedaa78cb1322f67fe4a89649c598bddf 100644 (file)
@@ -1,39 +1,18 @@
 /*
- * DEBUG: section 47    Store Directory Routines
- * AUTHOR: Robert Collins
- *
- * SQUID Web Proxy Cache          http://www.squid-cache.org/
- * ----------------------------------------------------------
- *
- *  Squid is the result of efforts by numerous individuals from
- *  the Internet community; see the CONTRIBUTORS file for full
- *  details.   Many organizations have provided support for Squid's
- *  development; see the SPONSORS file for full details.  Squid is
- *  Copyrighted (C) 2001 by the Regents of the University of
- *  California; see the COPYRIGHT file for full details.  Squid
- *  incorporates software developed and/or copyrighted by other
- *  sources; see the CREDITS file for full details.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
  *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
+/* DEBUG: section 47    Store Directory Routines */
+
 #include "squid.h"
 #include "disk.h"
 #include "globals.h"
 #include "RebuildState.h"
+#include "SquidConfig.h"
 #include "SquidTime.h"
 #include "store_key_md5.h"
 #include "store_rebuild.h"
 #include "tools.h"
 #include "UFSSwapLogParser.h"
 
-#if HAVE_MATH_H
-#include <math.h>
-#endif
+#include <cerrno>
+#include <cmath>
 #if HAVE_SYS_STAT_H
 #include <sys/stat.h>
 #endif
-#if HAVE_ERRNO_H
-#include <errno.h>
-#endif
 
 CBDATA_NAMESPACED_CLASS_INIT(Fs::Ufs,RebuildState);
 
 Fs::Ufs::RebuildState::RebuildState(RefCount<UFSSwapDir> aSwapDir) :
-        sd (aSwapDir), LogParser(NULL), e(NULL), fromLog(true), _done (false)
+    sd (aSwapDir), LogParser(NULL), e(NULL), fromLog(true), _done (false)
 {
     /*
      * If the swap.state file exists in the cache_dir, then
@@ -62,7 +37,7 @@ Fs::Ufs::RebuildState::RebuildState(RefCount<UFSSwapDir> aSwapDir) :
      * use commonUfsDirRebuildFromDirectory() to open up each file
      * and suck in the meta data.
      */
-    int clean = 0;
+    int clean = 0; //TODO: change to bool
     int zeroLengthLog = 0;
     FILE *fp = sd->openTmpSwapLog(&clean, &zeroLengthLog);
 
@@ -77,11 +52,11 @@ Fs::Ufs::RebuildState::RebuildState(RefCount<UFSSwapDir> aSwapDir) :
 
     } else {
         fromLog = true;
-        flags.clean = (unsigned int) clean;
+        flags.clean = (clean != 0);
     }
 
     if (!clean)
-        flags.need_to_validate = 1;
+        flags.need_to_validate = true;
 
     debugs(47, DBG_IMPORTANT, "Rebuilding storage in " << sd->path << " (" <<
            (clean ? "clean log" : (LogParser ? "dirty log" : "no log")) << ")");
@@ -155,7 +130,6 @@ Fs::Ufs::RebuildState::rebuildFromDirectory()
 
     struct stat sb;
     int fd = -1;
-    assert(this != NULL);
     debugs(47, 3, HERE << "DIR #" << sd->index);
 
     assert(fd == -1);
@@ -190,15 +164,25 @@ Fs::Ufs::RebuildState::rebuildFromDirectory()
     if (!storeRebuildLoadEntry(fd, sd->index, buf, counts))
         return;
 
+    const uint64_t expectedSize = sb.st_size > 0 ?
+                                  static_cast<uint64_t>(sb.st_size) : 0;
+
     StoreEntry tmpe;
-    const bool loaded = storeRebuildParseEntry(buf, tmpe, key, counts,
-                        (int64_t)sb.st_size);
+    const bool parsed = storeRebuildParseEntry(buf, tmpe, key, counts,
+                        expectedSize);
 
     file_close(fd);
     --store_open_disk_fd;
     fd = -1;
 
-    if (!loaded) {
+    bool accepted = parsed && tmpe.swap_file_sz > 0;
+    if (parsed && !accepted) {
+        debugs(47, DBG_IMPORTANT, "WARNING: Ignoring ufs cache entry with " <<
+               "unknown size: " << tmpe);
+        accepted = false;
+    }
+
+    if (!accepted) {
         // XXX: shouldn't this be a call to commonUfsUnlink?
         sd->unlinkFile(filn); // should we unlink in all failure cases?
         return;
@@ -345,7 +329,7 @@ Fs::Ufs::RebuildState::rebuildFromSwapLog()
             currentEntry()->lastmod = swapData.lastmod;
             currentEntry()->flags = swapData.flags;
             currentEntry()->refcount += swapData.refcount;
-            sd->dereference(*currentEntry());
+            sd->dereference(*currentEntry(), false);
         } else {
             debug_trap("commonUfsDirRebuildFromSwapLog: bad condition");
             debugs(47, DBG_IMPORTANT, HERE << "bad condition");
@@ -419,16 +403,21 @@ Fs::Ufs::RebuildState::undoAdd()
     added->releaseRequest();
 
     if (added->swap_filen > -1) {
-        UFSSwapDir *sde = dynamic_cast<UFSSwapDir *>(INDEXSD(added->swap_dirn));
-        assert(sde);
-        sde->undoAddDiskRestore(added);
+        SwapDir *someDir = INDEXSD(added->swap_dirn);
+        assert(someDir);
+        if (UFSSwapDir *ufsDir = dynamic_cast<UFSSwapDir*>(someDir))
+            ufsDir->undoAddDiskRestore(added);
+        // else the entry was loaded from and/or is currently in a non-UFS dir
+        // Thus, there is no use in preserving its disk file (the only purpose
+        // of undoAddDiskRestore!), even if we could. Instead, we release the
+        // the entry and [eventually] unlink its disk file or free its slot.
     }
 
     added->release();
 }
 
 int
-Fs::Ufs::RebuildState::getNextFile(sfileno * filn_p, int *size)
+Fs::Ufs::RebuildState::getNextFile(sfileno * filn_p, int *)
 {
     int fd = -1;
     int dirs_opened = 0;
@@ -443,12 +432,12 @@ Fs::Ufs::RebuildState::getNextFile(sfileno * filn_p, int *size)
     while (fd < 0 && done == 0) {
         fd = -1;
 
-        if (0 == flags.init) {  /* initialize, open first file */
+        if (!flags.init) {  /* initialize, open first file */
             done = 0;
             curlvl1 = 0;
             curlvl2 = 0;
             in_dir = 0;
-            flags.init = 1;
+            flags.init = true;
             assert(Config.cacheSwap.n_configured > 0);
         }
 
@@ -552,3 +541,4 @@ Fs::Ufs::RebuildState::currentItem()
 {
     return currentEntry();
 }
+