]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Shared Rock::DirMap version 6.
authorDmitry Kurochkin <dmitry.kurochkin@measurement-factory.com>
Tue, 1 Feb 2011 03:57:45 +0000 (06:57 +0300)
committerDmitry Kurochkin <dmitry.kurochkin@measurement-factory.com>
Tue, 1 Feb 2011 03:57:45 +0000 (06:57 +0300)
src/fs/rock/RockDirMap.cc
src/fs/rock/RockDirMap.h
src/fs/rock/RockRebuild.cc
src/fs/rock/RockSwapDir.cc
src/ipc/SharedMemory.cc
src/store_dir.cc

index e4b5e86bc9bd32389f31ddb68350667a6c23cb74..30dd39c222beb6c16a7759544822abaf6b8cf537 100644 (file)
 
 static const char SharedMemoryName[] = "RockDirMap";
 
-Rock::DirMap::DirMap(const char *const path, const int limit):
-    shm(SharedMemoryName(path))
+Rock::DirMap::DirMap(const char *const aPath, const int limit):
+    path(aPath), shm(sharedMemoryName())
 {
-    shm.create(limit);
+    shm.create(SharedSize(limit));
     assert(shm.mem());
     shared = new (shm.mem()) Shared(limit);
+    debugs(79, 5, HERE << "] new map [" << path << "] created using a new "
+           "shared memory segment for cache_dir '" << path << "' with limit=" <<
+           entryLimit());
 }
 
-Rock::DirMap::DirMap(const char *const path):
-    shm(SharedMemoryName(path))
+Rock::DirMap::DirMap(const char *const aPath):
+    path(aPath), shm(sharedMemoryName())
 {
     shm.open();
     assert(shm.mem());
     shared = reinterpret_cast<Shared *>(shm.mem());
+    debugs(79, 5, HERE << "] new map [" << path << "] created using existing "
+           "shared memory segment for cache_dir '" << path << "' with limit=" <<
+           entryLimit());
 }
 
 StoreEntryBasics *
 Rock::DirMap::openForWriting(const cache_key *const key, sfileno &fileno)
 {
+    debugs(79, 5, HERE << " trying to open entry for key " << storeKeyText(key)
+           << " for writing in map [" << path << ']');
     const int idx = slotIdx(key);
     free(idx);
     Slot &s = shared->slots[idx];
     if (s.state.swap_if(Slot::Empty, Slot::Writing)) {
+        fileno = idx;
         s.setKey(key);
+        debugs(79, 5, HERE << " opened entry at " << fileno << " for key " <<
+               storeKeyText(key) << " for writing in map [" << path << ']');
         return &s.seBasics;
     }
+    debugs(79, 5, HERE << " failed to open entry for key " << storeKeyText(key)
+           << " for writing in map [" << path << ']');
     return 0;
 }
 
 void
 Rock::DirMap::closeForWriting(const sfileno fileno)
 {
+    debugs(79, 5, HERE << " closing entry at " << fileno << " for writing in "
+           "map [" << path << ']');
     assert(valid(fileno));
     Slot &s = shared->slots[fileno];
     assert(s.state == Slot::Writing);
@@ -53,44 +68,71 @@ Rock::DirMap::closeForWriting(const sfileno fileno)
 bool
 Rock::DirMap::free(const sfileno fileno)
 {
+    debugs(79, 5, HERE << " trying to mark entry at " << fileno << " to be "
+           "freed in map [" << path << ']');
     if (openForReadingAt(fileno)) {
         Slot &s = shared->slots[fileno];
         s.state.swap_if(Slot::Usable, Slot::WaitingToBeFreed);
         --s.readLevel;
         freeIfNeeded(s);
+        debugs(79, 5, HERE << " marked entry at " << fileno << " to be freed in"
+               " map [" << path << ']');
         return true;
     }
+    debugs(79, 5, HERE << " failed to mark entry at " << fileno << " to be "
+           "freed in map [" << path << ']');
     return false;
 }
 
 const StoreEntryBasics *
 Rock::DirMap::openForReading(const cache_key *const key, sfileno &fileno)
 {
+    debugs(79, 5, HERE << " trying to open entry for key " << storeKeyText(key)
+           << " for reading in map [" << path << ']');
     const int idx = slotIdx(key);
     const StoreEntryBasics *const seBasics = openForReadingAt(idx);
-    if (seBasics && shared->slots[idx].checkKey(key)) {
-        fileno = idx;
-        return seBasics;
+    if (seBasics) {
+        Slot &s = shared->slots[idx];
+        if (s.checkKey(key)) {
+            fileno = idx;
+            debugs(79, 5, HERE << " opened entry at " << fileno << " for key "
+                   << storeKeyText(key) << " for reading in map [" << path <<
+                   ']');
+            return seBasics;
+        }
+        --s.readLevel;
+        freeIfNeeded(s);
     }
+    debugs(79, 5, HERE << " failed to open entry for key " << storeKeyText(key)
+           << " for reading in map [" << path << ']');
     return 0;
 }
 
 const StoreEntryBasics *
 Rock::DirMap::openForReadingAt(const sfileno fileno)
 {
+    debugs(79, 5, HERE << " trying to open entry at " << fileno << " for "
+           "reading in map [" << path << ']');
     assert(valid(fileno));
     Slot &s = shared->slots[fileno];
     ++s.readLevel;
-    if (s.state == Slot::Usable)
+    if (s.state == Slot::Usable) {
+        debugs(79, 5, HERE << " opened entry at " << fileno << " for reading in"
+               " map [" << path << ']');
         return &s.seBasics;
+    }
     --s.readLevel;
     freeIfNeeded(s);
+    debugs(79, 5, HERE << " failed to open entry at " << fileno << " for "
+           "reading in map [" << path << ']');
     return 0;
 }
 
 void
 Rock::DirMap::closeForReading(const sfileno fileno)
 {
+    debugs(79, 5, HERE << " closing entry at " << fileno << " for reading in "
+           "map [" << path << ']');
     assert(valid(fileno));
     Slot &s = shared->slots[fileno];
     assert(s.readLevel > 0);
@@ -132,7 +174,7 @@ Rock::DirMap::AbsoluteEntryLimit()
 int
 Rock::DirMap::slotIdx(const cache_key *const key) const
 {
-    const uint64_t *const k = reinterpret_cast<const uint64_t *>(&key);
+    const uint64_t *const k = reinterpret_cast<const uint64_t *>(key);
     // TODO: use a better hash function
     return (k[0] + k[1]) % shared->limit;
 }
@@ -158,27 +200,28 @@ Rock::DirMap::freeIfNeeded(Slot &s)
     }
 }
 
-int
-Rock::DirMap::SharedSize(const int limit)
-{
-    return sizeof(Shared) + limit * sizeof(Slot);
-}
-
 String
-Rock::DirMap::SharedMemoryName(const char *path)
+Rock::DirMap::sharedMemoryName()
 {
     String result;
-    for (const char *p = strchr(path, '/'); p; p = strchr(path, '/')) {
-        if (path != p) {
+    const char *begin = path.termedBuf();
+    for (const char *end = strchr(begin, '/'); end; end = strchr(begin, '/')) {
+        if (begin != end) {
+            result.append(begin, end - begin);
             result.append('.');
-            result.append(path, p - path);
         }
-        path = p + 1;
+        begin = end + 1;
     }
-    result.append(path);
+    result.append(begin);
     return result;
 }
 
+int
+Rock::DirMap::SharedSize(const int limit)
+{
+    return sizeof(Shared) + limit * sizeof(Slot);
+}
+
 void
 Rock::DirMap::Slot::setKey(const cache_key *const aKey)
 {
index 15a7f069b73a376d7369401943b85fa93131f32c..ba0d314a043e831e708de3aca169c3008c832b9f 100644 (file)
@@ -26,8 +26,8 @@ namespace Rock {
 class DirMap
 {
 public:
-    DirMap(const char *const path, const int limit); ///< create a new shared DirMap
-    DirMap(const char *const path); ///< open an existing shared DirMap
+    DirMap(const char *const aPath, const int limit); ///< create a new shared DirMap
+    DirMap(const char *const aPath); ///< open an existing shared DirMap
 
     /// start writing a new entry
     StoreEntryBasics *openForWriting(const cache_key *const key, sfileno &fileno);
@@ -83,10 +83,11 @@ private:
     Slot &slot(const cache_key *const key);
     const StoreEntryBasics *openForReading(Slot &s);
     void freeIfNeeded(Slot &s);
+    String sharedMemoryName();
 
     static int SharedSize(const int limit);
-    static String SharedMemoryName(const char *path);
 
+    const String path; ///< cache_dir path, used for logging
     SharedMemory shm; ///< shared memory segment
     Shared *shared; ///< pointer to shared memory
 };
index c8c2ca43c30dd8cac44773ee487352d8890db4da..6778c12b4ab46fab3aeeef03a489fca164aec7b8 100644 (file)
@@ -98,8 +98,10 @@ Rock::Rebuild::doOneEntry() {
     StoreEntry loadedE;
     if (!storeRebuildLoadEntry(fd, loadedE, key, counts, 0)) {
         // skip empty slots
-        if (loadedE.swap_filen > 0 || loadedE.swap_file_sz > 0)
+        if (loadedE.swap_filen > 0 || loadedE.swap_file_sz > 0) {
             counts.invalid++;
+            //sd->unlink(fileno); leave garbage on disk, it should not hurt
+        }
         return;
        }
 
index 413579a0da9d0d9f127ba69e36390d0664efc172..20029aba5ac95ba72271bf9f84b67dda574e5775 100644 (file)
@@ -67,6 +67,7 @@ Rock::SwapDir::get(const cache_key *key)
     EBIT_CLR(e->flags, KEY_PRIVATE);
     EBIT_SET(e->flags, ENTRY_VALIDATED);
 
+    e->hashInsert(key);
     trackReferences(*e);
 
     return e;
@@ -276,12 +277,15 @@ Rock::SwapDir::addEntry(const int fileno, const StoreEntry &from)
 
     int idx;
     StoreEntryBasics *const basics = map->openForWriting(key, idx);
-    if (!basics || fileno != idx) {
-        debugs(47, 5, HERE << "Rock::SwapDir::addEntry: map->add failed");
-        if (basics) {
-            map->closeForWriting(idx);
-            map->free(idx);
-        }
+    if (!basics) {
+        debugs(47, 5, HERE << "Rock::SwapDir::addEntry: the entry loaded from "
+               "disk clashed with locked newer entries");
+        return false;
+    } else if (fileno != idx) {
+        debugs(47, 5, HERE << "Rock::SwapDir::addEntry: the entry loaded from "
+               "disk was hashed to a new slot");
+        map->closeForWriting(idx);
+        map->free(idx);
         return false;
     }
     basics->set(from);
@@ -363,7 +367,7 @@ Rock::SwapDir::openStoreIO(StoreEntry &e, StoreIOState::STFNCB *cbFile, StoreIOS
     }
 
     if (!map->openForReadingAt(e.swap_filen)) {
-        debugs(47,1, HERE << "bug: dir " << index << " lost fileno: " <<
+        debugs(47,1, HERE << "bug: dir " << index << " lost locked fileno: " <<
             std::setfill('0') << std::hex << std::uppercase << std::setw(8) <<
             e.swap_filen);
         return NULL;
index c4438a1704fad4891fdccdd767f02a49b277faed..e7a64e7337fe9974e7dfca05b4a85a35b2a0b0d4 100644 (file)
@@ -35,7 +35,7 @@ SharedMemory::create(const int aSize)
     assert(aSize > 0);
     assert(theFD < 0);
 
-    theFD = shm_open(theName.termedBuf(), O_CREAT | O_RDWR,
+    theFD = shm_open(theName.termedBuf(), O_CREAT | O_RDWR | O_TRUNC,
                      S_IRUSR | S_IWUSR);
     if (theFD < 0) {
         debugs(54, 5, "SharedMemory::create: shm_open: " << xstrerror());
index a197807bdd4913731fcc583de175505b2a3f78a9..54f159df812505243325060553128883856c8058 100644 (file)
@@ -700,18 +700,15 @@ StoreController::get(const cache_key *key)
         // ask each cache_dir until the entry is found; use static starting
         // point to avoid asking the same subset of disks more often
         // TODO: coordinate with put() to be able to guess the right disk often
-        static int idx = 0;
-
         for (int n = 0; n < cacheDirs; ++n) {
-            if (idx >= cacheDirs)
-                idx = 0;
-
+            static int idx = 0;
             SwapDir *sd = dynamic_cast<SwapDir*>(INDEXSD(idx));
             if (StoreEntry *e = sd->get(key)) {
                 debugs(20, 1, HERE << "cache_dir " << idx <<
                     " got cached entry: " << *e);
                 return e;
             }
+            idx = (idx + 1) % cacheDirs;
         }
     }