88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.135 2003/03/28 20:17:13 tgl Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.136 2003/05/10 19:04:30 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -68,6 +68,7 @@ static void WaitIO(BufferDesc *buf);
6868static void StartBufferIO (BufferDesc * buf ,bool forInput );
6969static void TerminateBufferIO (BufferDesc * buf );
7070static void ContinueBufferIO (BufferDesc * buf ,bool forInput );
71+ static void buffer_write_error_callback (void * arg );
7172
7273/*
7374 * Macro : BUFFER_IS_BROKEN
@@ -699,14 +700,24 @@ BufferSync(void)
699700{
700701int i ;
701702BufferDesc * bufHdr ;
702- Buffer buffer ;
703- int status ;
704- RelFileNode rnode ;
705- XLogRecPtr recptr ;
706- Relation reln = NULL ;
703+ ErrorContextCallback errcontext ;
704+
705+ /* Setup error traceback support for ereport() */
706+ errcontext .callback = buffer_write_error_callback ;
707+ errcontext .arg = NULL ;
708+ errcontext .previous = error_context_stack ;
709+ error_context_stack = & errcontext ;
707710
708711for (i = 0 ,bufHdr = BufferDescriptors ;i < NBuffers ;i ++ ,bufHdr ++ )
709712{
713+ Buffer buffer ;
714+ int status ;
715+ RelFileNode rnode ;
716+ XLogRecPtr recptr ;
717+ Relation reln ;
718+
719+ errcontext .arg = bufHdr ;
720+
710721LWLockAcquire (BufMgrLock ,LW_EXCLUSIVE );
711722
712723if (!(bufHdr -> flags & BM_VALID ))
@@ -834,6 +845,8 @@ BufferSync(void)
834845RelationDecrementReferenceCount (reln );
835846}
836847
848+ /* Pop the error context stack */
849+ error_context_stack = errcontext .previous ;
837850}
838851
839852/*
@@ -1011,12 +1024,19 @@ BufferReplace(BufferDesc *bufHdr)
10111024Relation reln ;
10121025XLogRecPtr recptr ;
10131026int status ;
1027+ ErrorContextCallback errcontext ;
10141028
10151029/* To check if block content changed while flushing. - vadim 01/17/97 */
10161030bufHdr -> flags &= ~BM_JUST_DIRTIED ;
10171031
10181032LWLockRelease (BufMgrLock );
10191033
1034+ /* Setup error traceback support for ereport() */
1035+ errcontext .callback = buffer_write_error_callback ;
1036+ errcontext .arg = bufHdr ;
1037+ errcontext .previous = error_context_stack ;
1038+ error_context_stack = & errcontext ;
1039+
10201040/*
10211041 * No need to lock buffer context - no one should be able to end
10221042 * ReadBuffer
@@ -1043,6 +1063,9 @@ BufferReplace(BufferDesc *bufHdr)
10431063if (reln != (Relation )NULL )
10441064RelationDecrementReferenceCount (reln );
10451065
1066+ /* Pop the error context stack */
1067+ error_context_stack = errcontext .previous ;
1068+
10461069LWLockAcquire (BufMgrLock ,LW_EXCLUSIVE );
10471070
10481071if (status == SM_FAIL )
@@ -1380,12 +1403,20 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
13801403BufferDesc * bufHdr ;
13811404XLogRecPtr recptr ;
13821405int status ;
1406+ ErrorContextCallback errcontext ;
1407+
1408+ /* Setup error traceback support for ereport() */
1409+ errcontext .callback = buffer_write_error_callback ;
1410+ errcontext .arg = NULL ;
1411+ errcontext .previous = error_context_stack ;
1412+ error_context_stack = & errcontext ;
13831413
13841414if (rel -> rd_istemp )
13851415{
13861416for (i = 0 ;i < NLocBuffer ;i ++ )
13871417{
13881418bufHdr = & LocalBufferDescriptors [i ];
1419+ errcontext .arg = bufHdr ;
13891420if (RelFileNodeEquals (bufHdr -> tag .rnode ,rel -> rd_node ))
13901421{
13911422if (bufHdr -> flags & BM_DIRTY || bufHdr -> cntxDirty )
@@ -1395,6 +1426,7 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
13951426 (char * )MAKE_PTR (bufHdr -> data ));
13961427if (status == SM_FAIL )
13971428{
1429+ error_context_stack = errcontext .previous ;
13981430elog (WARNING ,"FlushRelationBuffers(%s (local), %u): block %u is dirty, could not flush it" ,
13991431RelationGetRelationName (rel ),firstDelBlock ,
14001432bufHdr -> tag .blockNum );
@@ -1405,6 +1437,7 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
14051437}
14061438if (LocalRefCount [i ]> 0 )
14071439{
1440+ error_context_stack = errcontext .previous ;
14081441elog (WARNING ,"FlushRelationBuffers(%s (local), %u): block %u is referenced (%ld)" ,
14091442RelationGetRelationName (rel ),firstDelBlock ,
14101443bufHdr -> tag .blockNum ,LocalRefCount [i ]);
@@ -1414,6 +1447,10 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
14141447bufHdr -> tag .rnode .relNode = InvalidOid ;
14151448}
14161449}
1450+
1451+ /* Pop the error context stack */
1452+ error_context_stack = errcontext .previous ;
1453+
14171454return 0 ;
14181455}
14191456
@@ -1422,6 +1459,7 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
14221459for (i = 0 ;i < NBuffers ;i ++ )
14231460{
14241461bufHdr = & BufferDescriptors [i ];
1462+ errcontext .arg = bufHdr ;
14251463if (RelFileNodeEquals (bufHdr -> tag .rnode ,rel -> rd_node ))
14261464{
14271465if (bufHdr -> flags & BM_DIRTY || bufHdr -> cntxDirty )
@@ -1483,6 +1521,7 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
14831521if (!(bufHdr -> flags & BM_FREE ))
14841522{
14851523LWLockRelease (BufMgrLock );
1524+ error_context_stack = errcontext .previous ;
14861525elog (WARNING ,"FlushRelationBuffers(%s, %u): block %u is referenced (private %ld, global %d)" ,
14871526RelationGetRelationName (rel ),firstDelBlock ,
14881527bufHdr -> tag .blockNum ,
@@ -1493,7 +1532,12 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
14931532BufTableDelete (bufHdr );
14941533}
14951534}
1535+
14961536LWLockRelease (BufMgrLock );
1537+
1538+ /* Pop the error context stack */
1539+ error_context_stack = errcontext .previous ;
1540+
14971541return 0 ;
14981542}
14991543
@@ -2083,3 +2127,17 @@ BufferGetFileNode(Buffer buffer)
20832127
20842128return (bufHdr -> tag .rnode );
20852129}
2130+
2131+ /*
2132+ * Error context callback for errors occurring during buffer writes.
2133+ */
2134+ static void
2135+ buffer_write_error_callback (void * arg )
2136+ {
2137+ BufferDesc * bufHdr = (BufferDesc * )arg ;
2138+
2139+ if (bufHdr != NULL )
2140+ errcontext ("writing block %u of relation %u/%u" ,
2141+ bufHdr -> tag .blockNum ,
2142+ bufHdr -> tag .rnode .tblNode ,bufHdr -> tag .rnode .relNode );
2143+ }