diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index bc6c0f6993cbd029a991d1810bdce63ca4a3bacc..400fbcf1ff7d1bb9bae4cb59488f0c8b2fa2db3b 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.168 2004/05/31 19:24:05 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.169 2004/05/31 20:31:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -182,7 +182,8 @@ ReadBufferInternal(Relation reln, BlockNumber blockNum,
 	{
 		/* new buffers are zero-filled */
 		MemSet((char *) MAKE_PTR(bufHdr->data), 0, BLCKSZ);
-		smgrextend(reln->rd_smgr, blockNum, (char *) MAKE_PTR(bufHdr->data));
+		smgrextend(reln->rd_smgr, blockNum, (char *) MAKE_PTR(bufHdr->data),
+				   reln->rd_istemp);
 	}
 	else
 	{
@@ -915,8 +916,8 @@ BufferGetFileNode(Buffer buffer)
  * NOTE: this actually just passes the buffer contents to the kernel; the
  * real write to disk won't happen until the kernel feels like it.  This
  * is okay from our point of view since we can redo the changes from WAL.
- * However, we will need to force the changes to disk via sync/fsync
- * before we can checkpoint WAL.
+ * However, we will need to force the changes to disk via fsync before
+ * we can checkpoint WAL.
  *
  * BufMgrLock must be held at entry, and the buffer must be pinned.  The
  * caller is also responsible for doing StartBufferIO/TerminateBufferIO.
@@ -979,7 +980,8 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln)
 	 */
 	smgrwrite(reln,
 			  buf->tag.blockNum,
-			  (char *) MAKE_PTR(buf->data));
+			  (char *) MAKE_PTR(buf->data),
+			  false);
 
 	/* Pop the error context stack */
 	error_context_stack = errcontext.previous;
@@ -1033,7 +1035,7 @@ RelationTruncate(Relation rel, BlockNumber nblocks)
 	rel->rd_targblock = InvalidBlockNumber;
 
 	/* Do the real work */
-	smgrtruncate(rel->rd_smgr, nblocks);
+	smgrtruncate(rel->rd_smgr, nblocks, rel->rd_istemp);
 }
 
 /* ---------------------------------------------------------------------
@@ -1351,7 +1353,8 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
 
 					smgrwrite(rel->rd_smgr,
 							  bufHdr->tag.blockNum,
-							  (char *) MAKE_PTR(bufHdr->data));
+							  (char *) MAKE_PTR(bufHdr->data),
+							  true);
 
 					bufHdr->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED);
 					bufHdr->cntxDirty = false;
diff --git a/src/backend/storage/buffer/localbuf.c b/src/backend/storage/buffer/localbuf.c
index ba4be8750cb491e37709b41a0f8ab20c62481c1e..95e86e955d19a5cddefca88828c4e9a6f4a7bd02 100644
--- a/src/backend/storage/buffer/localbuf.c
+++ b/src/backend/storage/buffer/localbuf.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/storage/buffer/localbuf.c,v 1.54 2004/04/22 07:21:55 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/storage/buffer/localbuf.c,v 1.55 2004/05/31 20:31:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -111,7 +111,8 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
 		/* And write... */
 		smgrwrite(reln,
 				  bufHdr->tag.blockNum,
-				  (char *) MAKE_PTR(bufHdr->data));
+				  (char *) MAKE_PTR(bufHdr->data),
+				  true);
 
 		LocalBufferFlushCount++;
 	}
diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c
index 5ac5868f690b32196f7eca791674d2de3c6ca4b0..1a0218c4e58def73447acf5e0077b413270d8ba3 100644
--- a/src/backend/storage/smgr/md.c
+++ b/src/backend/storage/smgr/md.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/storage/smgr/md.c,v 1.105 2004/05/31 03:48:06 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/storage/smgr/md.c,v 1.106 2004/05/31 20:31:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -270,7 +270,7 @@ mdunlink(RelFileNode rnode, bool isRedo)
  * already.  Might as well pass in the position and save a seek.
  */
 bool
-mdextend(SMgrRelation reln, BlockNumber blocknum, char *buffer)
+mdextend(SMgrRelation reln, BlockNumber blocknum, char *buffer, bool isTemp)
 {
 	long		seekpos;
 	int			nbytes;
@@ -311,8 +311,11 @@ mdextend(SMgrRelation reln, BlockNumber blocknum, char *buffer)
 		return false;
 	}
 
-	if (!register_dirty_segment(reln, v))
-		return false;
+	if (!isTemp)
+	{
+		if (!register_dirty_segment(reln, v))
+			return false;
+	}
 
 #ifndef LET_OS_MANAGE_FILESIZE
 	Assert(_mdnblocks(v->mdfd_vfd, BLCKSZ) <= ((BlockNumber) RELSEG_SIZE));
@@ -465,7 +468,7 @@ mdread(SMgrRelation reln, BlockNumber blocknum, char *buffer)
  *	mdwrite() -- Write the supplied block at the appropriate location.
  */
 bool
-mdwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer)
+mdwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer, bool isTemp)
 {
 	long		seekpos;
 	MdfdVec    *v;
@@ -485,8 +488,11 @@ mdwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer)
 	if (FileWrite(v->mdfd_vfd, buffer, BLCKSZ) != BLCKSZ)
 		return false;
 
-	if (!register_dirty_segment(reln, v))
-		return false;
+	if (!isTemp)
+	{
+		if (!register_dirty_segment(reln, v))
+			return false;
+	}
 
 	return true;
 }
@@ -565,7 +571,7 @@ mdnblocks(SMgrRelation reln)
  *		Returns # of blocks or InvalidBlockNumber on error.
  */
 BlockNumber
-mdtruncate(SMgrRelation reln, BlockNumber nblocks)
+mdtruncate(SMgrRelation reln, BlockNumber nblocks, bool isTemp)
 {
 	MdfdVec    *v;
 	BlockNumber curnblk;
@@ -624,6 +630,11 @@ mdtruncate(SMgrRelation reln, BlockNumber nblocks)
 
 			if (FileTruncate(v->mdfd_vfd, lastsegblocks * BLCKSZ) < 0)
 				return InvalidBlockNumber;
+			if (!isTemp)
+			{
+				if (!register_dirty_segment(reln, v))
+					return InvalidBlockNumber;
+			}
 			v = v->mdfd_chain;
 			ov->mdfd_chain = NULL;
 		}
@@ -640,6 +651,11 @@ mdtruncate(SMgrRelation reln, BlockNumber nblocks)
 #else
 	if (FileTruncate(v->mdfd_vfd, nblocks * BLCKSZ) < 0)
 		return InvalidBlockNumber;
+	if (!isTemp)
+	{
+		if (!register_dirty_segment(reln, v))
+			return InvalidBlockNumber;
+	}
 #endif
 
 	return nblocks;
diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c
index c204e2796c4b2125b5f83a1a3fb574e2a9bd85a1..5320532be4b5dd61b0b1517543f1d93d7fc8a8e3 100644
--- a/src/backend/storage/smgr/smgr.c
+++ b/src/backend/storage/smgr/smgr.c
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.71 2004/05/31 03:48:06 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.72 2004/05/31 20:31:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -40,13 +40,14 @@ typedef struct f_smgr
 	bool		(*smgr_create) (SMgrRelation reln, bool isRedo);
 	bool		(*smgr_unlink) (RelFileNode rnode, bool isRedo);
 	bool		(*smgr_extend) (SMgrRelation reln, BlockNumber blocknum,
-											char *buffer);
+								char *buffer, bool isTemp);
 	bool		(*smgr_read) (SMgrRelation reln, BlockNumber blocknum,
-										  char *buffer);
+							  char *buffer);
 	bool		(*smgr_write) (SMgrRelation reln, BlockNumber blocknum,
-										   char *buffer);
+							   char *buffer, bool isTemp);
 	BlockNumber (*smgr_nblocks) (SMgrRelation reln);
-	BlockNumber (*smgr_truncate) (SMgrRelation reln, BlockNumber nblocks);
+	BlockNumber (*smgr_truncate) (SMgrRelation reln, BlockNumber nblocks,
+								  bool isTemp);
 	bool		(*smgr_commit) (void);			/* may be NULL */
 	bool		(*smgr_abort) (void);			/* may be NULL */
 	bool		(*smgr_sync) (void);			/* may be NULL */
@@ -438,9 +439,10 @@ smgr_internal_unlink(RelFileNode rnode, int which, bool isTemp, bool isRedo)
  *		failure we clean up by truncating.
  */
 void
-smgrextend(SMgrRelation reln, BlockNumber blocknum, char *buffer)
+smgrextend(SMgrRelation reln, BlockNumber blocknum, char *buffer, bool isTemp)
 {
-	if (! (*(smgrsw[reln->smgr_which].smgr_extend)) (reln, blocknum, buffer))
+	if (! (*(smgrsw[reln->smgr_which].smgr_extend)) (reln, blocknum, buffer,
+													 isTemp))
 		ereport(ERROR,
 				(errcode_for_file_access(),
 				 errmsg("could not extend relation %u/%u: %m",
@@ -473,12 +475,18 @@ smgrread(SMgrRelation reln, BlockNumber blocknum, char *buffer)
  *	smgrwrite() -- Write the supplied buffer out.
  *
  *		This is not a synchronous write -- the block is not necessarily
- *		on disk at return, only dumped out to the kernel.
+ *		on disk at return, only dumped out to the kernel.  However,
+ *		provisions will be made to fsync the write before the next checkpoint.
+ *
+ *		isTemp indicates that the relation is a temp table (ie, is managed
+ *		by the local-buffer manager).  In this case no provisions need be
+ *		made to fsync the write before checkpointing.
  */
 void
-smgrwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer)
+smgrwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer, bool isTemp)
 {
-	if (! (*(smgrsw[reln->smgr_which].smgr_write)) (reln, blocknum, buffer))
+	if (! (*(smgrsw[reln->smgr_which].smgr_write)) (reln, blocknum, buffer,
+													isTemp))
 		ereport(ERROR,
 				(errcode_for_file_access(),
 				 errmsg("could not write block %u of relation %u/%u: %m",
@@ -525,12 +533,9 @@ smgrnblocks(SMgrRelation reln)
  *		transaction on failure.
  */
 BlockNumber
-smgrtruncate(SMgrRelation reln, BlockNumber nblocks)
+smgrtruncate(SMgrRelation reln, BlockNumber nblocks, bool isTemp)
 {
 	BlockNumber newblks;
-	XLogRecPtr		lsn;
-	XLogRecData		rdata;
-	xl_smgr_truncate xlrec;
 
 	/*
 	 * Tell the free space map to forget anything it may have stored
@@ -540,7 +545,8 @@ smgrtruncate(SMgrRelation reln, BlockNumber nblocks)
 	FreeSpaceMapTruncateRel(&reln->smgr_rnode, nblocks);
 
 	/* Do the truncation */
-	newblks = (*(smgrsw[reln->smgr_which].smgr_truncate)) (reln, nblocks);
+	newblks = (*(smgrsw[reln->smgr_which].smgr_truncate)) (reln, nblocks,
+														   isTemp);
 	if (newblks == InvalidBlockNumber)
 		ereport(ERROR,
 				(errcode_for_file_access(),
@@ -549,20 +555,29 @@ smgrtruncate(SMgrRelation reln, BlockNumber nblocks)
 						reln->smgr_rnode.relNode,
 						nblocks)));
 
-	/*
-	 * Make a non-transactional XLOG entry showing the file truncation.  It's
-	 * non-transactional because we should replay it whether the transaction
-	 * commits or not; the underlying file change is certainly not reversible.
-	 */
-	xlrec.blkno = newblks;
-	xlrec.rnode = reln->smgr_rnode;
+	if (!isTemp)
+	{
+		/*
+		 * Make a non-transactional XLOG entry showing the file truncation.
+		 * It's non-transactional because we should replay it whether the
+		 * transaction commits or not; the underlying file change is certainly
+		 * not reversible.
+		 */
+		XLogRecPtr		lsn;
+		XLogRecData		rdata;
+		xl_smgr_truncate xlrec;
 
-	rdata.buffer = InvalidBuffer;
-	rdata.data = (char *) &xlrec;
-	rdata.len = sizeof(xlrec);
-	rdata.next = NULL;
+		xlrec.blkno = newblks;
+		xlrec.rnode = reln->smgr_rnode;
 
-	lsn = XLogInsert(RM_SMGR_ID, XLOG_SMGR_TRUNCATE | XLOG_NO_TRAN, &rdata);
+		rdata.buffer = InvalidBuffer;
+		rdata.data = (char *) &xlrec;
+		rdata.len = sizeof(xlrec);
+		rdata.next = NULL;
+
+		lsn = XLogInsert(RM_SMGR_ID, XLOG_SMGR_TRUNCATE | XLOG_NO_TRAN,
+						 &rdata);
+	}
 
 	return newblks;
 }
@@ -725,7 +740,8 @@ smgr_redo(XLogRecPtr lsn, XLogRecord *record)
 
 		/* Do the truncation */
 		newblks = (*(smgrsw[reln->smgr_which].smgr_truncate)) (reln,
-															   xlrec->blkno);
+															   xlrec->blkno,
+															   false);
 		if (newblks == InvalidBlockNumber)
 			ereport(WARNING,
 					(errcode_for_file_access(),
diff --git a/src/include/storage/smgr.h b/src/include/storage/smgr.h
index 6a28c3824fad8e6b5f1a90cabb455e8219b8b53f..6999635dc468b2b672ce141f449364a5ce3d43b9 100644
--- a/src/include/storage/smgr.h
+++ b/src/include/storage/smgr.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/storage/smgr.h,v 1.42 2004/05/31 03:48:10 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/storage/smgr.h,v 1.43 2004/05/31 20:31:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -55,11 +55,14 @@ extern void smgrclosenode(RelFileNode rnode);
 extern void smgrcreate(SMgrRelation reln, bool isTemp, bool isRedo);
 extern void smgrscheduleunlink(SMgrRelation reln, bool isTemp);
 extern void smgrdounlink(SMgrRelation reln, bool isTemp, bool isRedo);
-extern void smgrextend(SMgrRelation reln, BlockNumber blocknum, char *buffer);
+extern void smgrextend(SMgrRelation reln, BlockNumber blocknum, char *buffer,
+					   bool isTemp);
 extern void smgrread(SMgrRelation reln, BlockNumber blocknum, char *buffer);
-extern void smgrwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer);
+extern void smgrwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer,
+					  bool isTemp);
 extern BlockNumber smgrnblocks(SMgrRelation reln);
-extern BlockNumber smgrtruncate(SMgrRelation reln, BlockNumber nblocks);
+extern BlockNumber smgrtruncate(SMgrRelation reln, BlockNumber nblocks,
+								bool isTemp);
 extern void smgrDoPendingDeletes(bool isCommit);
 extern int	smgrGetPendingDeletes(bool forCommit, RelFileNode **ptr);
 extern void smgrcommit(void);
@@ -78,11 +81,14 @@ extern bool mdinit(void);
 extern bool mdclose(SMgrRelation reln);
 extern bool mdcreate(SMgrRelation reln, bool isRedo);
 extern bool mdunlink(RelFileNode rnode, bool isRedo);
-extern bool mdextend(SMgrRelation reln, BlockNumber blocknum, char *buffer);
+extern bool mdextend(SMgrRelation reln, BlockNumber blocknum, char *buffer,
+					 bool isTemp);
 extern bool mdread(SMgrRelation reln, BlockNumber blocknum, char *buffer);
-extern bool mdwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer);
+extern bool mdwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer,
+					bool isTemp);
 extern BlockNumber mdnblocks(SMgrRelation reln);
-extern BlockNumber mdtruncate(SMgrRelation reln, BlockNumber nblocks);
+extern BlockNumber mdtruncate(SMgrRelation reln, BlockNumber nblocks,
+							  bool isTemp);
 extern bool mdsync(void);
 
 extern void RememberFsyncRequest(RelFileNode rnode, BlockNumber segno);