From: Alex Rousskov Date: Sat, 22 Jun 2013 15:11:30 +0000 (-0600) Subject: Properly reinitialize reused acnhor.start and slice.size. X-Git-Tag: SQUID_3_5_0_1~444^2~53 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a3023c0383ab843e8083f3390429a4b5148552b3;p=thirdparty%2Fsquid.git Properly reinitialize reused acnhor.start and slice.size. Since we allowed readers and [appending] writers to share an entry, it is no longer possible to implement abortIo(). The caller must either close the reading entry or abort the writing one, depending on the caller's lock. --- diff --git a/src/ipc/StoreMap.cc b/src/ipc/StoreMap.cc index 01a44ce9f3..7c602fb1c7 100644 --- a/src/ipc/StoreMap.cc +++ b/src/ipc/StoreMap.cc @@ -106,6 +106,7 @@ Ipc::StoreMap::openForWritingAt(const sfileno fileno, bool overwriteExisting) freeChain(fileno, s, true); assert(s.empty()); + s.start = -1; // we have not allocated any slices yet ++shared->count; //s.setKey(key); // XXX: the caller should do that @@ -180,7 +181,6 @@ Ipc::StoreMap::readableEntry(const AnchorId anchorId) const return shared->slots[anchorId].anchor; } -/// terminate writing the entry, freeing its slot for others to use void Ipc::StoreMap::abortWriting(const sfileno fileno) { @@ -194,27 +194,11 @@ Ipc::StoreMap::abortWriting(const sfileno fileno) debugs(54, 5, "closed clean entry " << fileno << " for writing " << path); } else { s.waitingToBeFreed = true; - // XXX: s.state &= !Anchor::Writeable; s.lock.unlockExclusive(); debugs(54, 5, "closed dirty entry " << fileno << " for writing " << path); } } -void -Ipc::StoreMap::abortIo(const sfileno fileno) -{ - debugs(54, 5, "aborting entry " << fileno << " for I/O in " << path); - assert(valid(fileno)); - Anchor &s = shared->slots[fileno].anchor; - - // The caller is a lock holder. Thus, if we are Writeable, then the - // caller must be the writer; otherwise the caller must be the reader. - if (s.writing()) - abortWriting(fileno); - else - closeForReading(fileno); -} - const Ipc::StoreMap::Anchor * Ipc::StoreMap::peekAtReader(const sfileno fileno) const { @@ -278,6 +262,7 @@ Ipc::StoreMap::freeChain(const sfileno fileno, Anchor &inode, const bool keepLoc while (sliceId >= 0) { Slice &slice = shared->slots[sliceId].slice; const sfileno nextId = slice.next; + slice.size = 0; slice.next = -1; if (cleaner) cleaner->noteFreeMapSlice(sliceId); // might change slice state diff --git a/src/ipc/StoreMap.h b/src/ipc/StoreMap.h index 3cb26d5599..ea90edc160 100644 --- a/src/ipc/StoreMap.h +++ b/src/ipc/StoreMap.h @@ -47,7 +47,7 @@ public: * the caller holds an appropriate lock */ bool empty() const { return !key[0] && !key[1]; } bool reading() const { return lock.readers; } - bool writing() const { return lock.writers; } + bool writing() const { return lock.writing; } bool complete() const { return !empty() && !writing(); } public: @@ -174,8 +174,8 @@ public: /// readable anchor for the entry created by openForReading() const Anchor &readableEntry(const AnchorId anchorId) const; - /// called by lock holder to terminate either slice writing or reading - void abortIo(const sfileno fileno); + /// stop writing the entry, freeing its slot for others to use if possible + void abortWriting(const sfileno fileno); /// finds an unlocked entry and frees it or returns false bool purgeOne(); @@ -192,18 +192,17 @@ public: void updateStats(ReadWriteLockStats &stats) const; StoreMapCleaner *cleaner; ///< notified before a readable entry is freed + const String path; ///< cache_dir path or similar cache name; for logging protected: static Owner *Init(const char *const path, const int limit, const size_t extrasSize); - const String path; ///< cache_dir path, used for logging Mem::Pointer shared; private: Anchor &anchorByKey(const cache_key *const key); Anchor *openForReading(Slice &s); - void abortWriting(const sfileno fileno); void freeChain(const sfileno fileno, Anchor &inode, const bool keepLock); };