/*
- * $Id: store_io_ufs.cc,v 1.34 2006/05/31 17:47:53 wessels Exp $
+ * $Id$
*
* DEBUG: section 79 Storage Manager UFS Interface
* AUTHOR: Duane Wessels
* 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.
*
*/
-#include "squid.h"
+#include "squid-old.h"
#include "Store.h"
#include "ufscommon.h"
#include "Generic.h"
}
StoreIOState::Pointer
-UFSStrategy::createState(SwapDir *SD, StoreEntry *e, StoreIOState::STIOCB * callback, void *callback_data) const
+UFSStrategy::createState(SwapDir *SD, StoreEntry *e, StoreIOState::STIOCB * aCallback, void *callback_data) const
{
- return new UFSStoreState (SD, e, callback, callback_data);
+ return new UFSStoreState (SD, e, aCallback, callback_data);
}
DiskFile::Pointer
{
if (opening) {
opening = false;
- debug(79, 3) ("UFSStoreState::ioCompletedNotification: dirno %d, fileno %08x status %d\n",
- swap_dirn, swap_filen, theFile->error());
+ debugs(79, 3, "UFSStoreState::ioCompletedNotification: dirno " <<
+ swap_dirn << ", fileno "<< std::setfill('0') << std::hex <<
+ std::setw(8) << swap_filen << " status "<< std::setfill(' ') <<
+ std::dec << theFile->error());
+
assert (FILE_MODE(mode) == O_RDONLY);
openDone();
if (creating) {
creating = false;
- debug(79, 3) ("UFSStoreState::ioCompletedNotification: dirno %d, fileno %08x status %d\n",
- swap_dirn, swap_filen, theFile->error());
+ debugs(79, 3, "UFSStoreState::ioCompletedNotification: dirno " <<
+ swap_dirn << ", fileno "<< std::setfill('0') << std::hex <<
+ std::setw(8) << swap_filen << " status "<< std::setfill(' ') <<
+ std::dec << theFile->error());
+
openDone();
return;
}
assert (!(closing ||opening));
- debug(79, 3) ("diskd::ioCompleted: dirno %d, fileno %08x status %d\n", swap_dirn, swap_filen, theFile->error());
+ debugs(79, 3, "diskd::ioCompleted: dirno " << swap_dirn << ", fileno "<<
+ std::setfill('0') << std::hex << std::setw(8) << swap_filen <<
+ " status "<< std::setfill(' ') << std::dec << theFile->error());
+
/* Ok, notification past open means an error has occured */
assert (theFile->error());
tryClosing();
if (flags.try_closing)
tryClosing();
- debug(79, 3) ("UFSStoreState::openDone: exiting\n");
+ debugs(79, 3, "UFSStoreState::openDone: exiting");
}
void
UFSStoreState::closeCompleted()
{
assert (closing);
- debug(79, 3) ("UFSStoreState::closeCompleted: dirno %d, fileno %08x status %d\n",
- swap_dirn, swap_filen, theFile->error());
+ debugs(79, 3, "UFSStoreState::closeCompleted: dirno " << swap_dirn <<
+ ", fileno "<< std::setfill('0') << std::hex << std::setw(8) <<
+ swap_filen << " status "<< std::setfill(' ') << std::dec <<
+ theFile->error());
if (theFile->error()) {
debugs(79,3,HERE<< "theFile->error() ret " << theFile->error());
* when it is safe to actually signal the lower layer for closing.
*/
void
-UFSStoreState::close()
+UFSStoreState::close(int)
{
- debug(79, 3) ("UFSStoreState::close: dirno %d, fileno %08X\n", swap_dirn,
- swap_filen);
- tryClosing();
+ debugs(79, 3, "UFSStoreState::close: dirno " << swap_dirn << ", fileno "<<
+ std::setfill('0') << std::hex << std::uppercase << std::setw(8) << swap_filen);
+ tryClosing(); // UFS does not distinguish different closure types
}
void
-UFSStoreState::read_(char *buf, size_t size, off_t offset, STRCB * callback, void *callback_data)
+UFSStoreState::read_(char *buf, size_t size, off_t aOffset, STRCB * aCallback, void *aCallbackData)
{
assert(read.callback == NULL);
assert(read.callback_data == NULL);
assert(!reading);
assert(!closing);
- assert (callback);
+ assert (aCallback);
if (!theFile->canRead()) {
- debug(79, 3) ("UFSStoreState::read_: queueing read because theFile can't read\n");
- queueRead (buf, size, offset, callback, callback_data);
+ debugs(79, 3, "UFSStoreState::read_: queueing read because theFile can't read");
+ queueRead (buf, size, aOffset, aCallback, aCallbackData);
return;
}
- read.callback = callback;
- read.callback_data = cbdataReference(callback_data);
- debug(79, 3) ("UFSStoreState::read_: dirno %d, fileno %08X\n",
- swap_dirn, swap_filen);
- offset_ = offset;
+ read.callback = aCallback;
+ read.callback_data = cbdataReference(aCallbackData);
+ debugs(79, 3, "UFSStoreState::read_: dirno " << swap_dirn << ", fileno "<<
+ std::setfill('0') << std::hex << std::uppercase << std::setw(8) << swap_filen);
+ offset_ = aOffset;
read_buf = buf;
reading = true;
- theFile->read(new ReadRequest(buf,offset,size));
+ theFile->read(new ReadRequest(buf,aOffset,size));
}
* code simpler and always go through the pending_writes queue.
*/
void
-UFSStoreState::write(char const *buf, size_t size, off_t offset, FREE * free_func)
+UFSStoreState::write(char const *buf, size_t size, off_t aOffset, FREE * free_func)
{
- debug(79, 3) ("UFSStoreState::write: dirn %d, fileno %08X\n", swap_dirn, swap_filen);
+ debugs(79, 3, "UFSStoreState::write: dirn " << swap_dirn << ", fileno "<<
+ std::setfill('0') << std::hex << std::uppercase << std::setw(8) << swap_filen);
if (theFile->error()) {
debugs(79,1,HERE << "avoid write on theFile with error");
return;
}
- queueWrite(buf, size, offset, free_func);
+ queueWrite(buf, size, aOffset, free_func);
drainWriteQueue();
}
* write_pending flag.
*/
q->free_func((void*)q->buf);
+ delete q;
return;
}
debugs(79, 3, HERE << this << " calling theFile->write(" << q->size << ")");
theFile->write(new WriteRequest(q->buf, q->offset, q->size, q->free_func));
+ delete q;
}
void
{
assert (result.getRaw());
reading = false;
- debug(79, 3) ("UFSStoreState::readCompleted: dirno %d, fileno %08x len %d\n",
- swap_dirn, swap_filen, len);
+ debugs(79, 3, "UFSStoreState::readCompleted: dirno " << swap_dirn <<
+ ", fileno "<< std::setfill('0') << std::hex << std::setw(8) <<
+ swap_filen << " len "<< std::setfill(' ') << std::dec << len);
if (len > 0)
offset_ += len;
- STRCB *callback = read.callback;
+ STRCB *callback_ = read.callback;
- assert(callback);
+ assert(callback_);
read.callback = NULL;
if (len > 0 && read_buf != buf)
memcpy(read_buf, buf, len);
- callback(cbdata, read_buf, len, this);
+ callback_(cbdata, read_buf, len, this);
}
- if (theFile != NULL && theFile->error())
+ if (flags.try_closing || (theFile != NULL && theFile->error()) )
tryClosing();
}
void
UFSStoreState::writeCompleted(int errflag, size_t len, RefCount<WriteRequest> writeRequest)
{
- debug(79, 3) ("UFSStoreState::writeCompleted: dirno %d, fileno %08X, len %ld\n",
- swap_dirn, swap_filen, (long int) len);
+ debugs(79, 3, HERE << "dirno " << swap_dirn << ", fileno " <<
+ std::setfill('0') << std::hex << std::uppercase << std::setw(8) << swap_filen <<
+ ", len " << len);
/*
* DPW 2006-05-24
* See doWrites() for why we don't update UFSStoreState::writing
offset_ += len;
if (theFile->error()) {
- debugs(79,2,HERE << "UFSStoreState::writeCompleted" <<
- " detected an error, will try to close");
+ debugs(79,2,HERE << " detected an error, will try to close");
tryClosing();
}
+
+ /*
+ * HNO 2009-07-24
+ * Kick any pending write/close operations alive
+ */
+ drainWriteQueue();
}
void
UFSStoreState::doCloseCallback(int errflag)
{
- debug(79, 3) ("storeUfsIOCallback: errflag=%d\n", errflag);
+ debugs(79, 3, "storeUfsIOCallback: errflag=" << errflag);
/*
* DPW 2006-05-24
* When we signal the higher layer with this callback, it might unlock
if (NULL == q)
return false;
- debug(79, 3) ("UFSStoreState::kickReadQueue: reading queued request of %ld bytes\n",
- (long int) q->size);
+ debugs(79, 3, "UFSStoreState::kickReadQueue: reading queued request of " << q->size << " bytes");
void *cbdata;
- if (cbdataReferenceValidDone(q->callback_data, &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;
+ }
delete q;
}
void
-UFSStoreState::queueRead(char *buf, size_t size, off_t offset, STRCB *callback, void *callback_data)
+UFSStoreState::queueRead(char *buf, size_t size, off_t aOffset, STRCB *callback_, void *callback_data_)
{
- debug(79, 3) ("UFSStoreState::queueRead: queueing read\n");
+ 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 = offset;
- q->callback = callback;
- q->callback_data = cbdataReference(callback_data);
+ q->offset = aOffset;
+ q->callback = callback_;
+ q->callback_data = cbdataReference(callback_data_);
linklistPush(&pending_reads, q);
}
void
UFSStoreState::drainWriteQueue()
{
- assert(!flags.write_draining);
+ /*
+ * DPW 2007-04-12
+ * We might find that flags.write_draining is already set
+ * because schemes like diskd can process I/O acks
+ * before sending another I/O request. e.g. the following
+ * sequence of events: open request -> write request ->
+ * drainWriteQueue() -> queue full -> callbacks -> openDone() ->
+ * drainWriteQueue().
+ */
+ if (flags.write_draining)
+ return;
if (!theFile->canWrite())
return;
" ioInProgress = " << theFile->ioInProgress());
if (theFile->ioInProgress()) {
+ debugs(79, 3, HERE << this <<
+ " won't close since ioInProgress is true, bailing");
flags.try_closing = true;
return;
}
}
void
-UFSStoreState::queueWrite(char const *buf, size_t size, off_t offset, FREE * free_func)
+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);
q = new _queued_write;
q->buf = buf;
q->size = size;
- q->offset = offset;
+ q->offset = aOffset;
q->free_func = free_func;
linklistPush(&pending_writes, q);
}
StoreIOState::Pointer
UFSStrategy::open(SwapDir * SD, StoreEntry * e, StoreIOState::STFNCB * file_callback,
- StoreIOState::STIOCB * callback, void *callback_data)
+ StoreIOState::STIOCB * aCallback, void *callback_data)
{
assert (((UFSSwapDir *)SD)->IO == this);
- debug(79, 3) ("UFSStrategy::open: fileno %08X\n", e->swap_filen);
+ debugs(79, 3, "UFSStrategy::open: fileno "<< std::setfill('0') << std::hex << std::uppercase << std::setw(8) << e->swap_filen);
/* to consider: make createstate a private UFSStrategy call */
- StoreIOState::Pointer sio = createState (SD, e, callback, callback_data);
+ StoreIOState::Pointer sio = createState (SD, e, aCallback, callback_data);
sio->mode |= O_RDONLY;
StoreIOState::Pointer
UFSStrategy::create(SwapDir * SD, StoreEntry * e, StoreIOState::STFNCB * file_callback,
- StoreIOState::STIOCB * callback, void *callback_data)
+ StoreIOState::STIOCB * aCallback, void *callback_data)
{
assert (((UFSSwapDir *)SD)->IO == this);
/* Allocate a number */
sfileno filn = ((UFSSwapDir *)SD)->mapBitAllocate();
- debug(79, 3) ("UFSStrategy::create: fileno %08X\n", filn);
+ debugs(79, 3, "UFSStrategy::create: fileno "<< std::setfill('0') << std::hex << std::uppercase << std::setw(8) << filn);
/* Shouldn't we handle a 'bitmap full' error here? */
- StoreIOState::Pointer sio = createState (SD, e, callback, callback_data);
+ StoreIOState::Pointer sio = createState (SD, e, aCallback, callback_data);
sio->mode |= O_WRONLY | O_CREAT | O_TRUNC;