7
7
*
8
8
*
9
9
* 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 $
11
11
*
12
12
*-------------------------------------------------------------------------
13
13
*/
@@ -474,7 +474,19 @@ BufferAlloc(Relation reln,
474
474
else
475
475
{
476
476
BufferFlushCount ++ ;
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
+ }
478
490
}
479
491
480
492
/*
@@ -488,7 +500,8 @@ BufferAlloc(Relation reln,
488
500
* no reason to think that we have an immediate disaster on
489
501
* our hands.
490
502
*/
491
- if (buf && buf -> refcount > 1 ) {
503
+ if ( buf && buf -> refcount > 1 )
504
+ {
492
505
inProgress = FALSE;
493
506
buf -> flags &= ~BM_IO_IN_PROGRESS ;
494
507
#ifdef HAS_TEST_AND_SET
@@ -643,7 +656,7 @@ WriteBuffer(Buffer buffer)
643
656
644
657
SpinAcquire (BufMgrLock );
645
658
Assert (bufHdr -> refcount > 0 );
646
- bufHdr -> flags |= BM_DIRTY ;
659
+ bufHdr -> flags |= ( BM_DIRTY | BM_JUST_DIRTIED );
647
660
UnpinBuffer (bufHdr );
648
661
SpinRelease (BufMgrLock );
649
662
}
@@ -733,19 +746,36 @@ FlushBuffer(Buffer buffer, bool release)
733
746
bufrel = RelationIdCacheGetRelation (bufHdr -> tag .relId .relId );
734
747
Assert (bufrel != (Relation ) NULL );
735
748
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
+
736
754
status = smgrflush (bufHdr -> bufsmgr , bufrel , bufHdr -> tag .blockNum ,
737
755
(char * ) MAKE_PTR (bufHdr -> data ));
738
756
739
757
if (status == SM_FAIL )
740
758
{
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 );
744
761
return (STATUS_ERROR );
745
762
}
746
763
747
764
SpinAcquire (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
+ }
749
779
if ( release )
750
780
UnpinBuffer (bufHdr );
751
781
SpinRelease (BufMgrLock );
@@ -779,7 +809,7 @@ WriteNoReleaseBuffer(Buffer buffer)
779
809
bufHdr = & BufferDescriptors [buffer - 1 ];
780
810
781
811
SpinAcquire (BufMgrLock );
782
- bufHdr -> flags |= BM_DIRTY ;
812
+ bufHdr -> flags |= ( BM_DIRTY | BM_JUST_DIRTIED );
783
813
SpinRelease (BufMgrLock );
784
814
}
785
815
return (STATUS_OK );
@@ -878,13 +908,19 @@ BufferSync()
878
908
UnpinBuffer (bufHdr );
879
909
if (bufHdr -> flags & BM_IO_ERROR )
880
910
{
881
- elog (WARN , "cannot write %u for %s" ,
911
+ elog (WARN , "BufferSync: write error %u for %s" ,
882
912
bufHdr -> tag .blockNum , bufHdr -> sb_relname );
883
913
}
884
914
if (reln != (Relation )NULL )
885
915
RelationDecrementReferenceCount (reln );
886
916
continue ;
887
917
}
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 ;
888
924
889
925
/*
890
926
* If we didn't have the reldesc in our local cache, flush this
@@ -912,15 +948,23 @@ BufferSync()
912
948
UnpinBuffer (bufHdr );
913
949
if (status == SM_FAIL ) {
914
950
bufHdr -> flags |= BM_IO_ERROR ;
915
- elog (WARN , "cannot write %u for %s" ,
951
+ elog (WARN , "BufferSync: cannot write %u for %s" ,
916
952
bufHdr -> tag .blockNum , bufHdr -> sb_relname );
917
953
}
918
954
/*
919
- * What if someone has marked this buffer as DIRTY after
920
- * smgr[blind]write but before SpinAcquire(BufMgrLock)
921
- * ??? - vadim 01/16 /97
955
+ * If this buffer was marked by someone as DIRTY while
956
+ * we were flushing it out we must not clear DIRTY flag
957
+ * - vadim 01/17 /97
922
958
*/
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
+ }
924
968
if (reln != (Relation )NULL )
925
969
RelationDecrementReferenceCount (reln );
926
970
}
@@ -1189,6 +1233,9 @@ BufferReplace(BufferDesc *bufHdr, bool bufferLockHeld)
1189
1233
reln = RelationIdCacheGetRelation (bufrel );
1190
1234
else
1191
1235
reln = (Relation ) NULL ;
1236
+
1237
+ /* To check if block content changed while flushing. - vadim 01/17/97 */
1238
+ bufHdr -> flags &= ~BM_JUST_DIRTIED ;
1192
1239
1193
1240
SpinRelease (BufMgrLock );
1194
1241
0 commit comments