]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/fs/ufs/UFSStoreState.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / fs / ufs / UFSStoreState.cc
index e51133a7da2b876df236eb24fc59bcf33ae15187..4ec94330705164dbb3eda92ea55eb22b64554f4c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
@@ -14,9 +14,9 @@
 #include "DiskIO/ReadRequest.h"
 #include "DiskIO/WriteRequest.h"
 #include "Generic.h"
-#include "SquidList.h"
+#include "SquidConfig.h"
 #include "Store.h"
-#include "SwapDir.h"
+#include "store/Disk.h"
 #include "UFSStoreState.h"
 #include "UFSStrategy.h"
 
@@ -131,8 +131,9 @@ Fs::Ufs::UFSStoreState::read_(char *buf, size_t size, off_t aOffset, STRCB * aCa
     assert (aCallback);
 
     if (!theFile->canRead()) {
-        debugs(79, 3, "UFSStoreState::read_: queueing read because theFile can't read");
-        queueRead (buf, size, aOffset, aCallback, aCallbackData);
+        debugs(79, 3, "queueing read because theFile can't read");
+        assert(opening);
+        pending_reads.emplace(buf, size, aOffset, aCallback, aCallbackData);
         return;
     }
 
@@ -167,7 +168,17 @@ Fs::Ufs::UFSStoreState::write(char const *buf, size_t size, off_t aOffset, FREE
         return false;
     }
 
-    queueWrite(buf, size, aOffset, free_func);
+    const Store::Disk &dir = *INDEXSD(swap_dirn);
+    if (static_cast<uint64_t>(offset_ + size) > static_cast<uint64_t>(dir.maxObjectSize())) {
+        debugs(79, 2, "accepted unknown-size entry grew too big: " <<
+               (offset_ + size) << " > " << dir.maxObjectSize());
+        free_func((void*)buf);
+        tryClosing();
+        return false;
+    }
+
+    debugs(79, 3, (void*)this << " queueing write of size " << size);
+    pending_writes.emplace(buf, size, aOffset, free_func);
     drainWriteQueue();
     return true;
 }
@@ -181,28 +192,20 @@ Fs::Ufs::UFSStoreState::write(char const *buf, size_t size, off_t aOffset, FREE
 void
 Fs::Ufs::UFSStoreState::doWrite()
 {
-    debugs(79, 3, HERE << this << " UFSStoreState::doWrite");
+    debugs(79, 3, (void*)this);
 
     assert(theFile->canWrite());
 
-    _queued_write *q = (_queued_write *)linklistShift(&pending_writes);
-
-    if (q == NULL) {
-        debugs(79, 3, HERE << this << " UFSStoreState::doWrite queue is empty");
+    if (pending_writes.empty()) {
+        debugs(79, 3, (void*)this << " write queue is empty");
         return;
     }
 
+    auto &q = pending_writes.front();
+
     if (theFile->error()) {
-        debugs(79, DBG_IMPORTANT,HERE << "avoid write on theFile with error");
-        debugs(79,3,HERE << "calling free_func for " << (void*) q->buf);
-        /*
-         * DPW 2006-05-24
-         * Note "free_func" is memNodeWriteComplete(), which doesn't
-         * really free the memory.  Instead it clears the node's
-         * write_pending flag.
-         */
-        q->free_func((void*)q->buf);
-        delete q;
+        debugs(79, DBG_IMPORTANT, MYNAME << " avoid write on theFile with error");
+        pending_writes.pop();
         return;
     }
 
@@ -216,14 +219,15 @@ Fs::Ufs::UFSStoreState::doWrite()
      * coming in.  For now let's just not use the writing flag at
      * all.
      */
-    debugs(79, 3, HERE << this << " calling theFile->write(" << q->size << ")");
+    debugs(79, 3, (void*)this << " calling theFile->write(" << q.size << ")");
 
-    theFile->write(new WriteRequest(q->buf, q->offset, q->size, q->free_func));
-    delete q;
+    theFile->write(new WriteRequest(q.buf, q.offset, q.size, q.free_func));
+    q.buf = nullptr; // prevent buf deletion on pop, its used by the above object
+    pending_writes.pop();
 }
 
 void
-Fs::Ufs::UFSStoreState::readCompleted(const char *buf, int len, int errflag, RefCount<ReadRequest> result)
+Fs::Ufs::UFSStoreState::readCompleted(const char *buf, int len, int, RefCount<ReadRequest> result)
 {
     assert (result.getRaw());
     reading = false;
@@ -266,7 +270,7 @@ Fs::Ufs::UFSStoreState::readCompleted(const char *buf, int len, int errflag, Ref
 }
 
 void
-Fs::Ufs::UFSStoreState::writeCompleted(int errflag, size_t len, RefCount<WriteRequest> writeRequest)
+Fs::Ufs::UFSStoreState::writeCompleted(int, size_t len, RefCount<WriteRequest>)
 {
     debugs(79, 3, HERE << "dirno " << swap_dirn << ", fileno " <<
            std::setfill('0') << std::hex << std::uppercase << std::setw(8) << swap_filen <<
@@ -321,85 +325,65 @@ Fs::Ufs::UFSStoreState::doCloseCallback(int errflag)
 
 /* ============= THE REAL UFS CODE ================ */
 
-Fs::Ufs::UFSStoreState::UFSStoreState(SwapDir * SD, StoreEntry * anEntry, STIOCB * callback_, void *callback_data_) : opening (false), creating (false), closing (false), reading(false), writing(false), pending_reads(NULL), pending_writes (NULL)
+Fs::Ufs::UFSStoreState::UFSStoreState(SwapDir * SD, StoreEntry * anEntry, STIOCB * cbIo, void *data) :
+    StoreIOState(NULL, cbIo, data),
+    opening(false),
+    creating(false),
+    closing(false),
+    reading(false),
+    writing(false),
+    read_buf(NULL)
 {
+    // StoreIOState inherited members
     swap_filen = anEntry->swap_filen;
     swap_dirn = SD->index;
-    mode = O_BINARY;
-    callback = callback_;
-    callback_data = cbdataReference(callback_data_);
     e = anEntry;
+
+    // our flags
     flags.write_draining = false;
     flags.try_closing = false;
 }
 
 Fs::Ufs::UFSStoreState::~UFSStoreState()
 {
-    assert(pending_reads == NULL);
-    assert(pending_writes == NULL);
+    assert(pending_reads.empty());
+    assert(pending_writes.empty());
 }
 
 void
 Fs::Ufs::UFSStoreState::freePending()
 {
-    _queued_read *qr;
-
-    while ((qr = (_queued_read *)linklistShift(&pending_reads))) {
-        cbdataReferenceDone(qr->callback_data);
-        delete qr;
-    }
-
-    debugs(79,3,HERE << "UFSStoreState::freePending: freed pending reads");
-
-    _queued_write *qw;
-
-    while ((qw = (_queued_write *)linklistShift(&pending_writes))) {
-        if (qw->free_func)
-            qw->free_func(const_cast<char *>(qw->buf));
-        delete qw;
-    }
+    while (!pending_reads.empty())
+        pending_reads.pop();
+    debugs(79, 3, "freed pending reads");
 
-    debugs(79,3,HERE << "UFSStoreState::freePending: freed pending writes");
+    while (!pending_writes.empty())
+        pending_writes.pop();
+    debugs(79, 3, "freed pending writes");
 }
 
 bool
 Fs::Ufs::UFSStoreState::kickReadQueue()
 {
-    _queued_read *q = (_queued_read *)linklistShift(&pending_reads);
-
-    if (NULL == q)
+    if (pending_reads.empty())
         return false;
 
-    debugs(79, 3, "UFSStoreState::kickReadQueue: reading queued request of " << q->size << " bytes");
+    auto &q = pending_reads.front();
 
-    void *cbdata;
+    debugs(79, 3, "reading queued request of " << q.size << " bytes");
 
-    if (cbdataReferenceValidDone(q->callback_data, &cbdata)) {
-        read_(q->buf, q->size, q->offset, q->callback, cbdata);
+    bool result = true;
+    void *cbdata;
+    if (cbdataReferenceValidDone(q.callback_data, &cbdata)) {
+        read_(q.buf, q.size, q.offset, q.callback, cbdata);
     } else {
-        debugs(79, 2, "UFSStoreState::kickReadQueue: this: " << this << " cbdataReferenceValidDone returned false." << " closing: " << closing << " flags.try_closing: " << flags.try_closing);
-        delete q;
-        return false;
+        debugs(79, 2, "this=" << (void*)this << " cbdataReferenceValidDone returned false." <<
+               " closing: " << closing << " flags.try_closing: " << flags.try_closing);
+        result = false;
     }
 
-    delete q;
-
-    return true;
-}
-
-void
-Fs::Ufs::UFSStoreState::queueRead(char *buf, size_t size, off_t aOffset, STRCB *callback_, void *callback_data_)
-{
-    debugs(79, 3, "UFSStoreState::queueRead: queueing read");
-    assert(opening);
-    assert (pending_reads == NULL);
-    _queued_read *q = new _queued_read;
-    q->buf = buf;
-    q->size = size;
-    q->offset = aOffset;
-    q->callback = callback_;
-    q->callback_data = cbdataReference(callback_data_);
-    linklistPush(&pending_reads, q);
+    pending_reads.pop(); // erase the front object
+    return result;
 }
 
 /*
@@ -421,14 +405,13 @@ Fs::Ufs::UFSStoreState::drainWriteQueue()
     if (flags.write_draining)
         return;
 
-    if (!theFile->canWrite())
+    if (!theFile || !theFile->canWrite())
         return;
 
     flags.write_draining = true;
 
-    while (pending_writes != NULL) {
+    while (!pending_writes.empty())
         doWrite();
-    }
 
     flags.write_draining = false;
 
@@ -463,17 +446,3 @@ Fs::Ufs::UFSStoreState::tryClosing()
     theFile->close();
 }
 
-void
-Fs::Ufs::UFSStoreState::queueWrite(char const *buf, size_t size, off_t aOffset, FREE * free_func)
-{
-    debugs(79, 3, HERE << this << " UFSStoreState::queueWrite: queueing write of size " << size);
-
-    _queued_write *q;
-    q = new _queued_write;
-    q->buf = buf;
-    q->size = size;
-    q->offset = aOffset;
-    q->free_func = free_func;
-    linklistPush(&pending_writes, q);
-}
-