77 *
88 *
99 * IDENTIFICATION
10- * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.7 1997/01/14 05:40:45 vadim Exp $
10+ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.8 1997/01/16 08:11:41 vadim Exp $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
2626 *
2727 * WriteNoReleaseBuffer() -- mark the buffer contents as "dirty"
2828 *but don't unpin. The disk IO is delayed until buffer
29- *replacement ifLateWrite flag isset .
29+ *replacement ifWriteMode isBUFFER_LATE_WRITE .
3030 *
3131 * WriteBuffer() -- WriteNoReleaseBuffer() + ReleaseBuffer()
3232 *
7474#include "executor/execdebug.h" /* for NDirectFileRead */
7575#include "catalog/catalog.h"
7676
77- extern int LateWrite ;
7877extern SPINLOCK BufMgrLock ;
7978extern int ReadBufferCount ;
8079extern int BufferHitCount ;
8180extern int BufferFlushCount ;
8281
82+ static int WriteMode = BUFFER_LATE_WRITE ;/* Delayed write is default */
83+
8384static void WaitIO (BufferDesc * buf ,SPINLOCK spinlock );
8485#ifndef HAS_TEST_AND_SET
8586static void SignalIO (BufferDesc * buf );
@@ -90,7 +91,7 @@ static Buffer ReadBufferWithBufferLock(Relation relation, BlockNumber blockNum,
9091bool bufferLockHeld );
9192static BufferDesc * BufferAlloc (Relation reln ,BlockNumber blockNum ,
9293bool * foundPtr ,bool bufferLockHeld );
93- static int FlushBuffer (Buffer buffer );
94+ static int FlushBuffer (Buffer buffer , bool release );
9495static void BufferSync (void );
9596static int BufferReplace (BufferDesc * bufHdr ,bool bufferLockHeld );
9697
@@ -611,8 +612,8 @@ BufferAlloc(Relation reln,
611612/*
612613 * WriteBuffer--
613614 *
614- *Pushes buffer contents to disk ifLateWrite is
615- * not set. Otherwise, marks contents as dirty.
615+ *Pushes buffer contents to disk ifWriteMode is BUFFER_FLUSH_WRITE.
616+ * Otherwise, marks contents as dirty.
616617 *
617618 * Assume that buffer is pinned. Assume that reln is
618619 *valid.
@@ -628,8 +629,8 @@ WriteBuffer(Buffer buffer)
628629{
629630BufferDesc * bufHdr ;
630631
631- if (! LateWrite ) {
632- return (FlushBuffer (buffer ));
632+ if (WriteMode == BUFFER_FLUSH_WRITE ) {
633+ return (FlushBuffer (buffer , TRUE ));
633634 }else {
634635
635636if (BufferIsLocal (buffer ))
@@ -712,26 +713,41 @@ DirtyBufferCopy(Oid dbid, Oid relid, BlockNumber blkno, char *dest)
712713 * us).
713714 */
714715static int
715- FlushBuffer (Buffer buffer )
716+ FlushBuffer (Buffer buffer , bool release )
716717{
717718BufferDesc * bufHdr ;
719+ Oid bufdb ;
720+ Relation bufrel ;
721+ int status ;
718722
719723if (BufferIsLocal (buffer ))
720- return FlushLocalBuffer (buffer );
724+ return FlushLocalBuffer (buffer , release );
721725
722726if (BAD_BUFFER_ID (buffer ))
723727return (STATUS_ERROR );
724728
725729bufHdr = & BufferDescriptors [buffer - 1 ];
730+ bufdb = bufHdr -> tag .relId .dbId ;
726731
727- if (!BufferReplace (bufHdr , false)) {
728- elog (WARN ,"FlushBuffer: cannot flush %d" ,bufHdr -> tag .blockNum );
732+ Assert (bufdb == MyDatabaseId || bufdb == (Oid )NULL );
733+ bufrel = RelationIdCacheGetRelation (bufHdr -> tag .relId .relId );
734+ Assert (bufrel != (Relation )NULL );
735+
736+ status = smgrflush (bufHdr -> bufsmgr ,bufrel ,bufHdr -> tag .blockNum ,
737+ (char * )MAKE_PTR (bufHdr -> data ));
738+
739+ if (status == SM_FAIL )
740+ {
741+ elog (WARN ,"FlushBuffer: cannot flush block %u of the relation %.*s" ,
742+ bufHdr -> tag .blockNum ,
743+ NAMEDATALEN ,bufrel -> rd_rel -> relname .data );
729744return (STATUS_ERROR );
730745 }
731746
732747SpinAcquire (BufMgrLock );
733748bufHdr -> flags &= ~BM_DIRTY ;
734- UnpinBuffer (bufHdr );
749+ if (release )
750+ UnpinBuffer (bufHdr );
735751SpinRelease (BufMgrLock );
736752
737753return (STATUS_OK );
@@ -750,8 +766,8 @@ WriteNoReleaseBuffer(Buffer buffer)
750766{
751767BufferDesc * bufHdr ;
752768
753- if (! LateWrite ) {
754- return (FlushBuffer (buffer ));
769+ if (WriteMode == BUFFER_FLUSH_WRITE ) {
770+ return (FlushBuffer (buffer , FALSE ));
755771 }else {
756772
757773if (BufferIsLocal (buffer ))
@@ -899,7 +915,11 @@ BufferSync()
899915elog (WARN ,"cannot write %u for %s" ,
900916bufHdr -> tag .blockNum ,bufHdr -> sb_relname );
901917}
902-
918+ /*
919+ * What if someone has marked this buffer as DIRTY after
920+ * smgr[blind]write but before SpinAcquire(BufMgrLock)
921+ * ??? - vadim 01/16/97
922+ */
903923bufHdr -> flags &= ~BM_DIRTY ;
904924if (reln != (Relation )NULL )
905925RelationDecrementReferenceCount (reln );
@@ -1145,7 +1165,6 @@ BufferGetRelation(Buffer buffer)
11451165 *
11461166 * Flush the buffer corresponding to 'bufHdr'
11471167 *
1148- * Assumes that the BufMgrLock has NOT been acquired.
11491168 */
11501169static int
11511170BufferReplace (BufferDesc * bufHdr ,bool bufferLockHeld )
@@ -1655,3 +1674,11 @@ BufferRefCountRestore(int *refcountsave)
16551674 }
16561675}
16571676
1677+ int SetBufferWriteMode (int mode )
1678+ {
1679+ int old ;
1680+
1681+ old = WriteMode ;
1682+ WriteMode = mode ;
1683+ return (old );
1684+ }