From: Dmitry Kurochkin Date: Tue, 1 Feb 2011 03:57:45 +0000 (+0300) Subject: Shared Rock::DirMap version 6. X-Git-Tag: take01~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e1825c5da433d453add6557248db6865e63bd225;p=thirdparty%2Fsquid.git Shared Rock::DirMap version 6. --- diff --git a/src/fs/rock/RockDirMap.cc b/src/fs/rock/RockDirMap.cc index e4b5e86bc9..30dd39c222 100644 --- a/src/fs/rock/RockDirMap.cc +++ b/src/fs/rock/RockDirMap.cc @@ -11,38 +11,53 @@ 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(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(&key); + const uint64_t *const k = reinterpret_cast(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) { diff --git a/src/fs/rock/RockDirMap.h b/src/fs/rock/RockDirMap.h index 15a7f069b7..ba0d314a04 100644 --- a/src/fs/rock/RockDirMap.h +++ b/src/fs/rock/RockDirMap.h @@ -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 }; diff --git a/src/fs/rock/RockRebuild.cc b/src/fs/rock/RockRebuild.cc index c8c2ca43c3..6778c12b4a 100644 --- a/src/fs/rock/RockRebuild.cc +++ b/src/fs/rock/RockRebuild.cc @@ -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; } diff --git a/src/fs/rock/RockSwapDir.cc b/src/fs/rock/RockSwapDir.cc index 413579a0da..20029aba5a 100644 --- a/src/fs/rock/RockSwapDir.cc +++ b/src/fs/rock/RockSwapDir.cc @@ -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; diff --git a/src/ipc/SharedMemory.cc b/src/ipc/SharedMemory.cc index c4438a1704..e7a64e7337 100644 --- a/src/ipc/SharedMemory.cc +++ b/src/ipc/SharedMemory.cc @@ -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()); diff --git a/src/store_dir.cc b/src/store_dir.cc index a197807bdd..54f159df81 100644 --- a/src/store_dir.cc +++ b/src/store_dir.cc @@ -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(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; } }