*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.135 2003/03/28 20:17:13 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.136 2003/05/10 19:04:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
static void StartBufferIO(BufferDesc *buf, bool forInput);
static void TerminateBufferIO(BufferDesc *buf);
static void ContinueBufferIO(BufferDesc *buf, bool forInput);
+static void buffer_write_error_callback(void *arg);
/*
* Macro : BUFFER_IS_BROKEN
{
int i;
BufferDesc *bufHdr;
- Buffer buffer;
- int status;
- RelFileNode rnode;
- XLogRecPtr recptr;
- Relation reln = NULL;
+ ErrorContextCallback errcontext;
+
+ /* Setup error traceback support for ereport() */
+ errcontext.callback = buffer_write_error_callback;
+ errcontext.arg = NULL;
+ errcontext.previous = error_context_stack;
+ error_context_stack = &errcontext;
for (i = 0, bufHdr = BufferDescriptors; i < NBuffers; i++, bufHdr++)
{
+ Buffer buffer;
+ int status;
+ RelFileNode rnode;
+ XLogRecPtr recptr;
+ Relation reln;
+
+ errcontext.arg = bufHdr;
+
LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
if (!(bufHdr->flags & BM_VALID))
RelationDecrementReferenceCount(reln);
}
+ /* Pop the error context stack */
+ error_context_stack = errcontext.previous;
}
/*
Relation reln;
XLogRecPtr recptr;
int status;
+ ErrorContextCallback errcontext;
/* To check if block content changed while flushing. - vadim 01/17/97 */
bufHdr->flags &= ~BM_JUST_DIRTIED;
LWLockRelease(BufMgrLock);
+ /* Setup error traceback support for ereport() */
+ errcontext.callback = buffer_write_error_callback;
+ errcontext.arg = bufHdr;
+ errcontext.previous = error_context_stack;
+ error_context_stack = &errcontext;
+
/*
* No need to lock buffer context - no one should be able to end
* ReadBuffer
if (reln != (Relation) NULL)
RelationDecrementReferenceCount(reln);
+ /* Pop the error context stack */
+ error_context_stack = errcontext.previous;
+
LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
if (status == SM_FAIL)
BufferDesc *bufHdr;
XLogRecPtr recptr;
int status;
+ ErrorContextCallback errcontext;
+
+ /* Setup error traceback support for ereport() */
+ errcontext.callback = buffer_write_error_callback;
+ errcontext.arg = NULL;
+ errcontext.previous = error_context_stack;
+ error_context_stack = &errcontext;
if (rel->rd_istemp)
{
for (i = 0; i < NLocBuffer; i++)
{
bufHdr = &LocalBufferDescriptors[i];
+ errcontext.arg = bufHdr;
if (RelFileNodeEquals(bufHdr->tag.rnode, rel->rd_node))
{
if (bufHdr->flags & BM_DIRTY || bufHdr->cntxDirty)
(char *) MAKE_PTR(bufHdr->data));
if (status == SM_FAIL)
{
+ error_context_stack = errcontext.previous;
elog(WARNING, "FlushRelationBuffers(%s (local), %u): block %u is dirty, could not flush it",
RelationGetRelationName(rel), firstDelBlock,
bufHdr->tag.blockNum);
}
if (LocalRefCount[i] > 0)
{
+ error_context_stack = errcontext.previous;
elog(WARNING, "FlushRelationBuffers(%s (local), %u): block %u is referenced (%ld)",
RelationGetRelationName(rel), firstDelBlock,
bufHdr->tag.blockNum, LocalRefCount[i]);
bufHdr->tag.rnode.relNode = InvalidOid;
}
}
+
+ /* Pop the error context stack */
+ error_context_stack = errcontext.previous;
+
return 0;
}
for (i = 0; i < NBuffers; i++)
{
bufHdr = &BufferDescriptors[i];
+ errcontext.arg = bufHdr;
if (RelFileNodeEquals(bufHdr->tag.rnode, rel->rd_node))
{
if (bufHdr->flags & BM_DIRTY || bufHdr->cntxDirty)
if (!(bufHdr->flags & BM_FREE))
{
LWLockRelease(BufMgrLock);
+ error_context_stack = errcontext.previous;
elog(WARNING, "FlushRelationBuffers(%s, %u): block %u is referenced (private %ld, global %d)",
RelationGetRelationName(rel), firstDelBlock,
bufHdr->tag.blockNum,
BufTableDelete(bufHdr);
}
}
+
LWLockRelease(BufMgrLock);
+
+ /* Pop the error context stack */
+ error_context_stack = errcontext.previous;
+
return 0;
}
return (bufHdr->tag.rnode);
}
+
+/*
+ * Error context callback for errors occurring during buffer writes.
+ */
+static void
+buffer_write_error_callback(void *arg)
+{
+ BufferDesc *bufHdr = (BufferDesc *) arg;
+
+ if (bufHdr != NULL)
+ errcontext("writing block %u of relation %u/%u",
+ bufHdr->tag.blockNum,
+ bufHdr->tag.rnode.tblNode, bufHdr->tag.rnode.relNode);
+}