77 *
88 *
99 * IDENTIFICATION
10- * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.8 1997/01/16 08:11:41 vadim Exp $
10+ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.9 1997/01/20 04:36:48 vadim Exp $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
@@ -474,7 +474,19 @@ BufferAlloc(Relation reln,
474474else
475475 {
476476BufferFlushCount ++ ;
477- buf -> flags &= ~BM_DIRTY ;
477+ /*
478+ * BM_JUST_DIRTIED cleared by BufferReplace and shouldn't
479+ * be setted by anyone. - vadim 01/17/97
480+ */
481+ if (buf -> flags & BM_JUST_DIRTIED )
482+ {
483+ elog (FATAL ,"BufferAlloc: content of block %u (%s) changed while flushing" ,
484+ buf -> tag .blockNum ,buf -> sb_relname );
485+ }
486+ else
487+ {
488+ buf -> flags &= ~BM_DIRTY ;
489+ }
478490 }
479491
480492/*
@@ -488,7 +500,8 @@ BufferAlloc(Relation reln,
488500 * no reason to think that we have an immediate disaster on
489501 * our hands.
490502 */
491- if (buf && buf -> refcount > 1 ) {
503+ if (buf && buf -> refcount > 1 )
504+ {
492505inProgress = FALSE;
493506buf -> flags &= ~BM_IO_IN_PROGRESS ;
494507#ifdef HAS_TEST_AND_SET
@@ -643,7 +656,7 @@ WriteBuffer(Buffer buffer)
643656
644657SpinAcquire (BufMgrLock );
645658Assert (bufHdr -> refcount > 0 );
646- bufHdr -> flags |=BM_DIRTY ;
659+ bufHdr -> flags |=( BM_DIRTY | BM_JUST_DIRTIED );
647660UnpinBuffer (bufHdr );
648661SpinRelease (BufMgrLock );
649662 }
@@ -733,19 +746,36 @@ FlushBuffer(Buffer buffer, bool release)
733746bufrel = RelationIdCacheGetRelation (bufHdr -> tag .relId .relId );
734747Assert (bufrel != (Relation )NULL );
735748
749+ /* To check if block content changed while flushing. - vadim 01/17/97 */
750+ SpinAcquire (BufMgrLock );
751+ bufHdr -> flags &= ~BM_JUST_DIRTIED ;
752+ SpinRelease (BufMgrLock );
753+
736754status = smgrflush (bufHdr -> bufsmgr ,bufrel ,bufHdr -> tag .blockNum ,
737755 (char * )MAKE_PTR (bufHdr -> data ));
738756
739757if (status == SM_FAIL )
740758 {
741- elog (WARN ,"FlushBuffer: cannot flush block %u of the relation %.*s" ,
742- bufHdr -> tag .blockNum ,
743- NAMEDATALEN ,bufrel -> rd_rel -> relname .data );
759+ elog (WARN ,"FlushBuffer: cannot flush block %u of the relation %s" ,
760+ bufHdr -> tag .blockNum ,bufHdr -> sb_relname );
744761return (STATUS_ERROR );
745762 }
746763
747764SpinAcquire (BufMgrLock );
748- bufHdr -> flags &= ~BM_DIRTY ;
765+ /*
766+ * If this buffer was marked by someone as DIRTY while
767+ * we were flushing it out we must not clear DIRTY flag
768+ * - vadim 01/17/97
769+ */
770+ if (bufHdr -> flags & BM_JUST_DIRTIED )
771+ {
772+ elog (NOTICE ,"FlusfBuffer: content of block %u (%s) changed while flushing" ,
773+ bufHdr -> tag .blockNum ,bufHdr -> sb_relname );
774+ }
775+ else
776+ {
777+ bufHdr -> flags &= ~BM_DIRTY ;
778+ }
749779if (release )
750780UnpinBuffer (bufHdr );
751781SpinRelease (BufMgrLock );
@@ -779,7 +809,7 @@ WriteNoReleaseBuffer(Buffer buffer)
779809bufHdr = & BufferDescriptors [buffer - 1 ];
780810
781811SpinAcquire (BufMgrLock );
782- bufHdr -> flags |=BM_DIRTY ;
812+ bufHdr -> flags |=( BM_DIRTY | BM_JUST_DIRTIED );
783813SpinRelease (BufMgrLock );
784814 }
785815return (STATUS_OK );
@@ -878,13 +908,19 @@ BufferSync()
878908UnpinBuffer (bufHdr );
879909if (bufHdr -> flags & BM_IO_ERROR )
880910 {
881- elog (WARN ,"cannot write %u for %s" ,
911+ elog (WARN ,"BufferSync: write error %u for %s" ,
882912bufHdr -> tag .blockNum ,bufHdr -> sb_relname );
883913 }
884914if (reln != (Relation )NULL )
885915RelationDecrementReferenceCount (reln );
886916continue ;
887917}
918+
919+ /*
920+ * To check if block content changed while flushing
921+ * (see below). - vadim 01/17/97
922+ */
923+ bufHdr -> flags &= ~BM_JUST_DIRTIED ;
888924
889925/*
890926 * If we didn't have the reldesc in our local cache, flush this
@@ -912,15 +948,23 @@ BufferSync()
912948UnpinBuffer (bufHdr );
913949if (status == SM_FAIL ) {
914950bufHdr -> flags |=BM_IO_ERROR ;
915- elog (WARN ,"cannot write %u for %s" ,
951+ elog (WARN ,"BufferSync: cannot write %u for %s" ,
916952bufHdr -> tag .blockNum ,bufHdr -> sb_relname );
917953}
918954/*
919- *What if someone has markedthis buffer as DIRTYafter
920- *smgr[blind]write but before SpinAcquire(BufMgrLock)
921- *??? - vadim 01/16 /97
955+ *If this buffer was markedby someone as DIRTYwhile
956+ *we were flushing it out we must not clear DIRTY flag
957+ * - vadim 01/17 /97
922958 */
923- bufHdr -> flags &= ~BM_DIRTY ;
959+ if (bufHdr -> flags & BM_JUST_DIRTIED )
960+ {
961+ elog (NOTICE ,"BufferSync: content of block %u (%s) changed while flushing" ,
962+ bufHdr -> tag .blockNum ,bufHdr -> sb_relname );
963+ }
964+ else
965+ {
966+ bufHdr -> flags &= ~BM_DIRTY ;
967+ }
924968if (reln != (Relation )NULL )
925969RelationDecrementReferenceCount (reln );
926970 }
@@ -1189,6 +1233,9 @@ BufferReplace(BufferDesc *bufHdr, bool bufferLockHeld)
11891233reln = RelationIdCacheGetRelation (bufrel );
11901234else
11911235reln = (Relation )NULL ;
1236+
1237+ /* To check if block content changed while flushing. - vadim 01/17/97 */
1238+ bufHdr -> flags &= ~BM_JUST_DIRTIED ;
11921239
11931240SpinRelease (BufMgrLock );
11941241