I posted some bufmgr cleanup a few weeks ago, but it conflicted with
some concurrent changes Jan was making to the bufmgr. Here's an
updated version of the patch -- it should apply cleanly to CVS
HEAD and passes the regression tests.

This patch makes the following changes:

     - remove the UnlockAndReleaseBuffer() and UnlockAndWriteBuffer()
       macros, and replace uses of them with calls to the appropriate
       functions.

     - remove a bunch of #ifdef BMTRACE code: it is ugly & broken
       (i.e. it doesn't compile)

     - make BufferReplace() return a bool, not an int

     - cleanup some logic in bufmgr.c; should be functionality
       equivalent to the previous code, just cleaner now

     - remove the BM_PRIVATE flag as it is unused

     - improve a few comments, etc.

-Neil
Index: src/backend/access/heap/heapam.c
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/backend/access/heap/heapam.c,v
retrieving revision 1.158
diff -c -r1.158 heapam.c
*** src/backend/access/heap/heapam.c	29 Nov 2003 19:51:40 -0000	1.158
--- src/backend/access/heap/heapam.c	10 Dec 2003 22:34:31 -0000
***************
*** 2110,2116 ****
  
  	if (XLByteLE(lsn, PageGetLSN(page)))
  	{
! 		UnlockAndReleaseBuffer(buffer);
  		return;
  	}
  
--- 2110,2117 ----
  
  	if (XLByteLE(lsn, PageGetLSN(page)))
  	{
! 		LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 		ReleaseBuffer(buffer);
  		return;
  	}
  
***************
*** 2135,2141 ****
  
  	PageSetLSN(page, lsn);
  	PageSetSUI(page, ThisStartUpID);	/* prev sui */
! 	UnlockAndWriteBuffer(buffer);
  }
  
  static void
--- 2136,2143 ----
  
  	PageSetLSN(page, lsn);
  	PageSetSUI(page, ThisStartUpID);	/* prev sui */
! 	LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 	WriteBuffer(buffer);
  }
  
  static void
***************
*** 2170,2176 ****
  	{
  		if (XLByteLE(lsn, PageGetLSN(page)))	/* changes are applied */
  		{
! 			UnlockAndReleaseBuffer(buffer);
  			return;
  		}
  	}
--- 2172,2179 ----
  	{
  		if (XLByteLE(lsn, PageGetLSN(page)))	/* changes are applied */
  		{
! 			LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 			ReleaseBuffer(buffer);
  			return;
  		}
  	}
***************
*** 2199,2205 ****
  		htup->t_ctid = xlrec->target.tid;
  		PageSetLSN(page, lsn);
  		PageSetSUI(page, ThisStartUpID);
! 		UnlockAndWriteBuffer(buffer);
  		return;
  	}
  
--- 2202,2209 ----
  		htup->t_ctid = xlrec->target.tid;
  		PageSetLSN(page, lsn);
  		PageSetSUI(page, ThisStartUpID);
! 		LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 		WriteBuffer(buffer);
  		return;
  	}
  
***************
*** 2249,2255 ****
  
  		if (XLByteLE(lsn, PageGetLSN(page)))	/* changes are applied */
  		{
! 			UnlockAndReleaseBuffer(buffer);
  			return;
  		}
  
--- 2253,2260 ----
  
  		if (XLByteLE(lsn, PageGetLSN(page)))	/* changes are applied */
  		{
! 			LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 			ReleaseBuffer(buffer);
  			return;
  		}
  
***************
*** 2282,2288 ****
  			elog(PANIC, "heap_insert_redo: failed to add tuple");
  		PageSetLSN(page, lsn);
  		PageSetSUI(page, ThisStartUpID);		/* prev sui */
! 		UnlockAndWriteBuffer(buffer);
  		return;
  	}
  
--- 2287,2294 ----
  			elog(PANIC, "heap_insert_redo: failed to add tuple");
  		PageSetLSN(page, lsn);
  		PageSetSUI(page, ThisStartUpID);		/* prev sui */
! 		LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 		WriteBuffer(buffer);
  		return;
  	}
  
***************
*** 2332,2338 ****
  	{
  		if (XLByteLE(lsn, PageGetLSN(page)))	/* changes are applied */
  		{
! 			UnlockAndReleaseBuffer(buffer);
  			if (samepage)
  				return;
  			goto newt;
--- 2338,2345 ----
  	{
  		if (XLByteLE(lsn, PageGetLSN(page)))	/* changes are applied */
  		{
! 			LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 			ReleaseBuffer(buffer);
  			if (samepage)
  				return;
  			goto newt;
***************
*** 2378,2384 ****
  			goto newsame;
  		PageSetLSN(page, lsn);
  		PageSetSUI(page, ThisStartUpID);
! 		UnlockAndWriteBuffer(buffer);
  		goto newt;
  	}
  
--- 2385,2392 ----
  			goto newsame;
  		PageSetLSN(page, lsn);
  		PageSetSUI(page, ThisStartUpID);
! 		LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 		WriteBuffer(buffer);
  		goto newt;
  	}
  
***************
*** 2421,2427 ****
  
  		if (XLByteLE(lsn, PageGetLSN(page)))	/* changes are applied */
  		{
! 			UnlockAndReleaseBuffer(buffer);
  			return;
  		}
  
--- 2429,2436 ----
  
  		if (XLByteLE(lsn, PageGetLSN(page)))	/* changes are applied */
  		{
! 			LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 			ReleaseBuffer(buffer);
  			return;
  		}
  
***************
*** 2474,2480 ****
  			elog(PANIC, "heap_update_redo: failed to add tuple");
  		PageSetLSN(page, lsn);
  		PageSetSUI(page, ThisStartUpID);		/* prev sui */
! 		UnlockAndWriteBuffer(buffer);
  		return;
  	}
  
--- 2483,2490 ----
  			elog(PANIC, "heap_update_redo: failed to add tuple");
  		PageSetLSN(page, lsn);
  		PageSetSUI(page, ThisStartUpID);		/* prev sui */
! 		LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 		WriteBuffer(buffer);
  		return;
  	}
  
***************
*** 2523,2529 ****
  		elog(PANIC, "_heap_unlock_tuple: invalid xmax in rollback");
  	htup->t_infomask &= ~HEAP_XMAX_UNLOGGED;
  	htup->t_infomask |= HEAP_XMAX_INVALID;
! 	UnlockAndWriteBuffer(buffer);
  	return;
  }
  
--- 2533,2540 ----
  		elog(PANIC, "_heap_unlock_tuple: invalid xmax in rollback");
  	htup->t_infomask &= ~HEAP_XMAX_UNLOGGED;
  	htup->t_infomask |= HEAP_XMAX_INVALID;
! 	LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 	WriteBuffer(buffer);
  	return;
  }
  
Index: src/backend/access/nbtree/nbtxlog.c
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/backend/access/nbtree/nbtxlog.c,v
retrieving revision 1.8
diff -c -r1.8 nbtxlog.c
*** src/backend/access/nbtree/nbtxlog.c	29 Nov 2003 19:51:40 -0000	1.8
--- src/backend/access/nbtree/nbtxlog.c	10 Dec 2003 22:34:31 -0000
***************
*** 69,75 ****
  	btitem = (BTItem) PageGetItem(page, PageGetItemId(page, offnum));
  	rightblk = ItemPointerGetBlockNumber(&(btitem->bti_itup.t_tid));
  	Assert(ItemPointerGetOffsetNumber(&(btitem->bti_itup.t_tid)) == P_HIKEY);
! 	UnlockAndReleaseBuffer(buffer);
  
  	foreach(l, incomplete_splits)
  	{
--- 69,76 ----
  	btitem = (BTItem) PageGetItem(page, PageGetItemId(page, offnum));
  	rightblk = ItemPointerGetBlockNumber(&(btitem->bti_itup.t_tid));
  	Assert(ItemPointerGetOffsetNumber(&(btitem->bti_itup.t_tid)) == P_HIKEY);
! 	LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 	ReleaseBuffer(buffer);
  
  	foreach(l, incomplete_splits)
  	{
***************
*** 137,143 ****
  
  	PageSetLSN(metapg, lsn);
  	PageSetSUI(metapg, ThisStartUpID);
! 	UnlockAndWriteBuffer(metabuf);
  }
  
  static void
--- 138,145 ----
  
  	PageSetLSN(metapg, lsn);
  	PageSetSUI(metapg, ThisStartUpID);
! 	LockBuffer(metabuf, BUFFER_LOCK_UNLOCK);
! 	WriteBuffer(metabuf);
  }
  
  static void
***************
*** 184,190 ****
  		if (redo)
  		{
  			if (XLByteLE(lsn, PageGetLSN(page)))
! 				UnlockAndReleaseBuffer(buffer);
  			else
  			{
  				if (PageAddItem(page, (Item) datapos, datalen,
--- 186,195 ----
  		if (redo)
  		{
  			if (XLByteLE(lsn, PageGetLSN(page)))
! 			{
! 				LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 				ReleaseBuffer(buffer);
! 			}
  			else
  			{
  				if (PageAddItem(page, (Item) datapos, datalen,
***************
*** 194,200 ****
  
  				PageSetLSN(page, lsn);
  				PageSetSUI(page, ThisStartUpID);
! 				UnlockAndWriteBuffer(buffer);
  			}
  		}
  		else
--- 199,206 ----
  
  				PageSetLSN(page, lsn);
  				PageSetSUI(page, ThisStartUpID);
! 				LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 				WriteBuffer(buffer);
  			}
  		}
  		else
***************
*** 203,209 ****
  				elog(PANIC, "btree_insert_undo: bad page LSN");
  
  			if (!P_ISLEAF(pageop))
! 				UnlockAndReleaseBuffer(buffer);
  			else
  				elog(PANIC, "btree_insert_undo: unimplemented");
  		}
--- 209,218 ----
  				elog(PANIC, "btree_insert_undo: bad page LSN");
  
  			if (!P_ISLEAF(pageop))
! 			{
! 				LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 				ReleaseBuffer(buffer);
! 			}
  			else
  				elog(PANIC, "btree_insert_undo: unimplemented");
  		}
***************
*** 275,281 ****
  
  		PageSetLSN(page, lsn);
  		PageSetSUI(page, ThisStartUpID);
! 		UnlockAndWriteBuffer(buffer);
  	}
  	else
  	{
--- 284,291 ----
  
  		PageSetLSN(page, lsn);
  		PageSetSUI(page, ThisStartUpID);
! 		LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 		WriteBuffer(buffer);
  	}
  	else
  	{
***************
*** 310,316 ****
  
  		PageSetLSN(page, lsn);
  		PageSetSUI(page, ThisStartUpID);
! 		UnlockAndWriteBuffer(buffer);
  	}
  	else
  	{
--- 320,327 ----
  
  		PageSetLSN(page, lsn);
  		PageSetSUI(page, ThisStartUpID);
! 		LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 		WriteBuffer(buffer);
  	}
  	else
  	{
***************
*** 334,340 ****
  				elog(PANIC, "btree_split_redo: uninitialized next right page");
  
  			if (XLByteLE(lsn, PageGetLSN(page)))
! 				UnlockAndReleaseBuffer(buffer);
  			else
  			{
  				pageop = (BTPageOpaque) PageGetSpecialPointer(page);
--- 345,354 ----
  				elog(PANIC, "btree_split_redo: uninitialized next right page");
  
  			if (XLByteLE(lsn, PageGetLSN(page)))
! 			{
! 				LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 				ReleaseBuffer(buffer);
! 			}
  			else
  			{
  				pageop = (BTPageOpaque) PageGetSpecialPointer(page);
***************
*** 342,348 ****
  
  				PageSetLSN(page, lsn);
  				PageSetSUI(page, ThisStartUpID);
! 				UnlockAndWriteBuffer(buffer);
  			}
  		}
  	}
--- 356,363 ----
  
  				PageSetLSN(page, lsn);
  				PageSetSUI(page, ThisStartUpID);
! 				LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 				WriteBuffer(buffer);
  			}
  		}
  	}
***************
*** 385,391 ****
  
  	if (XLByteLE(lsn, PageGetLSN(page)))
  	{
! 		UnlockAndReleaseBuffer(buffer);
  		return;
  	}
  
--- 400,407 ----
  
  	if (XLByteLE(lsn, PageGetLSN(page)))
  	{
! 		LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 		ReleaseBuffer(buffer);
  		return;
  	}
  
***************
*** 407,413 ****
  
  	PageSetLSN(page, lsn);
  	PageSetSUI(page, ThisStartUpID);
! 	UnlockAndWriteBuffer(buffer);
  }
  
  static void
--- 423,430 ----
  
  	PageSetLSN(page, lsn);
  	PageSetSUI(page, ThisStartUpID);
! 	LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 	WriteBuffer(buffer);
  }
  
  static void
***************
*** 445,451 ****
  		if (PageIsNew((PageHeader) page))
  			elog(PANIC, "btree_delete_page_redo: uninitialized parent page");
  		if (XLByteLE(lsn, PageGetLSN(page)))
! 			UnlockAndReleaseBuffer(buffer);
  		else
  		{
  			OffsetNumber poffset;
--- 462,471 ----
  		if (PageIsNew((PageHeader) page))
  			elog(PANIC, "btree_delete_page_redo: uninitialized parent page");
  		if (XLByteLE(lsn, PageGetLSN(page)))
! 		{
! 			LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 			ReleaseBuffer(buffer);
! 		}
  		else
  		{
  			OffsetNumber poffset;
***************
*** 472,478 ****
  
  			PageSetLSN(page, lsn);
  			PageSetSUI(page, ThisStartUpID);
! 			UnlockAndWriteBuffer(buffer);
  		}
  	}
  
--- 492,499 ----
  
  			PageSetLSN(page, lsn);
  			PageSetSUI(page, ThisStartUpID);
! 			LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 			WriteBuffer(buffer);
  		}
  	}
  
***************
*** 486,492 ****
  		if (PageIsNew((PageHeader) page))
  			elog(PANIC, "btree_delete_page_redo: uninitialized right sibling");
  		if (XLByteLE(lsn, PageGetLSN(page)))
! 			UnlockAndReleaseBuffer(buffer);
  		else
  		{
  			pageop = (BTPageOpaque) PageGetSpecialPointer(page);
--- 507,516 ----
  		if (PageIsNew((PageHeader) page))
  			elog(PANIC, "btree_delete_page_redo: uninitialized right sibling");
  		if (XLByteLE(lsn, PageGetLSN(page)))
! 		{
! 			LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 			ReleaseBuffer(buffer);
! 		}
  		else
  		{
  			pageop = (BTPageOpaque) PageGetSpecialPointer(page);
***************
*** 494,500 ****
  
  			PageSetLSN(page, lsn);
  			PageSetSUI(page, ThisStartUpID);
! 			UnlockAndWriteBuffer(buffer);
  		}
  	}
  
--- 518,525 ----
  
  			PageSetLSN(page, lsn);
  			PageSetSUI(page, ThisStartUpID);
! 			LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 			WriteBuffer(buffer);
  		}
  	}
  
***************
*** 510,516 ****
  			if (PageIsNew((PageHeader) page))
  				elog(PANIC, "btree_delete_page_redo: uninitialized left sibling");
  			if (XLByteLE(lsn, PageGetLSN(page)))
! 				UnlockAndReleaseBuffer(buffer);
  			else
  			{
  				pageop = (BTPageOpaque) PageGetSpecialPointer(page);
--- 535,544 ----
  			if (PageIsNew((PageHeader) page))
  				elog(PANIC, "btree_delete_page_redo: uninitialized left sibling");
  			if (XLByteLE(lsn, PageGetLSN(page)))
! 			{
! 				LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 				ReleaseBuffer(buffer);
! 			}
  			else
  			{
  				pageop = (BTPageOpaque) PageGetSpecialPointer(page);
***************
*** 518,524 ****
  
  				PageSetLSN(page, lsn);
  				PageSetSUI(page, ThisStartUpID);
! 				UnlockAndWriteBuffer(buffer);
  			}
  		}
  	}
--- 546,553 ----
  
  				PageSetLSN(page, lsn);
  				PageSetSUI(page, ThisStartUpID);
! 				LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 				WriteBuffer(buffer);
  			}
  		}
  	}
***************
*** 543,549 ****
  
  		PageSetLSN(page, lsn);
  		PageSetSUI(page, ThisStartUpID);
! 		UnlockAndWriteBuffer(buffer);
  	}
  	else
  	{
--- 572,579 ----
  
  		PageSetLSN(page, lsn);
  		PageSetSUI(page, ThisStartUpID);
! 		LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 		WriteBuffer(buffer);
  	}
  	else
  	{
***************
*** 606,612 ****
  
  	PageSetLSN(page, lsn);
  	PageSetSUI(page, ThisStartUpID);
! 	UnlockAndWriteBuffer(buffer);
  
  	_bt_restore_meta(reln, lsn,
  					 xlrec->rootblk, xlrec->level,
--- 636,643 ----
  
  	PageSetLSN(page, lsn);
  	PageSetSUI(page, ThisStartUpID);
! 	LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 	WriteBuffer(buffer);
  
  	_bt_restore_meta(reln, lsn,
  					 xlrec->rootblk, xlrec->level,
***************
*** 668,674 ****
  
  	PageSetLSN(page, lsn);
  	PageSetSUI(page, ThisStartUpID);
! 	UnlockAndWriteBuffer(buffer);
  }
  
  
--- 699,706 ----
  
  	PageSetLSN(page, lsn);
  	PageSetSUI(page, ThisStartUpID);
! 	LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 	WriteBuffer(buffer);
  }
  
  
Index: src/backend/access/transam/xlog.c
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/backend/access/transam/xlog.c,v
retrieving revision 1.126
diff -c -r1.126 xlog.c
*** src/backend/access/transam/xlog.c	29 Nov 2003 19:51:40 -0000	1.126
--- src/backend/access/transam/xlog.c	10 Dec 2003 22:34:31 -0000
***************
*** 1712,1718 ****
  				memcpy((char *) page, blk, BLCKSZ);
  				PageSetLSN(page, lsn);
  				PageSetSUI(page, ThisStartUpID);
! 				UnlockAndWriteBuffer(buffer);
  			}
  		}
  
--- 1712,1719 ----
  				memcpy((char *) page, blk, BLCKSZ);
  				PageSetLSN(page, lsn);
  				PageSetSUI(page, ThisStartUpID);
! 				LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 				WriteBuffer(buffer);
  			}
  		}
  
Index: src/backend/access/transam/xlogutils.c
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/backend/access/transam/xlogutils.c,v
retrieving revision 1.27
diff -c -r1.27 xlogutils.c
*** src/backend/access/transam/xlogutils.c	29 Nov 2003 19:51:40 -0000	1.27
--- src/backend/access/transam/xlogutils.c	10 Dec 2003 22:34:31 -0000
***************
*** 60,72 ****
  	if (PageIsNew((PageHeader) page) ||
  		ItemPointerGetOffsetNumber(iptr) > PageGetMaxOffsetNumber(page))
  	{
! 		UnlockAndReleaseBuffer(buffer);
  		return (0);
  	}
  	lp = PageGetItemId(page, ItemPointerGetOffsetNumber(iptr));
  	if (!ItemIdIsUsed(lp) || ItemIdDeleted(lp))
  	{
! 		UnlockAndReleaseBuffer(buffer);
  		return (0);
  	}
  
--- 60,74 ----
  	if (PageIsNew((PageHeader) page) ||
  		ItemPointerGetOffsetNumber(iptr) > PageGetMaxOffsetNumber(page))
  	{
! 		LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 		ReleaseBuffer(buffer);
  		return (0);
  	}
  	lp = PageGetItemId(page, ItemPointerGetOffsetNumber(iptr));
  	if (!ItemIdIsUsed(lp) || ItemIdDeleted(lp))
  	{
! 		LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 		ReleaseBuffer(buffer);
  		return (0);
  	}
  
***************
*** 76,86 ****
  	if (!TransactionIdEquals(HeapTupleHeaderGetXmin(htup), xid) ||
  		HeapTupleHeaderGetCmin(htup) != cid)
  	{
! 		UnlockAndReleaseBuffer(buffer);
  		return (-1);
  	}
  
! 	UnlockAndReleaseBuffer(buffer);
  	return (1);
  }
  
--- 78,90 ----
  	if (!TransactionIdEquals(HeapTupleHeaderGetXmin(htup), xid) ||
  		HeapTupleHeaderGetCmin(htup) != cid)
  	{
! 		LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 		ReleaseBuffer(buffer);
  		return (-1);
  	}
  
! 	LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 	ReleaseBuffer(buffer);
  	return (1);
  }
  
***************
*** 112,132 ****
  	if (PageIsNew((PageHeader) page) ||
  		ItemPointerGetOffsetNumber(iptr) > PageGetMaxOffsetNumber(page))
  	{
! 		UnlockAndReleaseBuffer(buffer);
  		return (false);
  	}
  
  	if (PageGetSUI(page) != ThisStartUpID)
  	{
  		Assert(PageGetSUI(page) < ThisStartUpID);
! 		UnlockAndReleaseBuffer(buffer);
  		return (true);
  	}
  
  	lp = PageGetItemId(page, ItemPointerGetOffsetNumber(iptr));
  	if (!ItemIdIsUsed(lp) || ItemIdDeleted(lp))
  	{
! 		UnlockAndReleaseBuffer(buffer);
  		return (false);
  	}
  
--- 116,139 ----
  	if (PageIsNew((PageHeader) page) ||
  		ItemPointerGetOffsetNumber(iptr) > PageGetMaxOffsetNumber(page))
  	{
! 		LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 		ReleaseBuffer(buffer);
  		return (false);
  	}
  
  	if (PageGetSUI(page) != ThisStartUpID)
  	{
  		Assert(PageGetSUI(page) < ThisStartUpID);
! 		LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 		ReleaseBuffer(buffer);
  		return (true);
  	}
  
  	lp = PageGetItemId(page, ItemPointerGetOffsetNumber(iptr));
  	if (!ItemIdIsUsed(lp) || ItemIdDeleted(lp))
  	{
! 		LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 		ReleaseBuffer(buffer);
  		return (false);
  	}
  
***************
*** 141,152 ****
  			 TransactionIdDidAbort(HeapTupleHeaderGetXvac(htup))) ||
  			TransactionIdDidAbort(HeapTupleHeaderGetXmin(htup)))
  		{
! 			UnlockAndReleaseBuffer(buffer);
  			return (false);
  		}
  	}
  
! 	UnlockAndReleaseBuffer(buffer);
  	return (true);
  }
  
--- 148,161 ----
  			 TransactionIdDidAbort(HeapTupleHeaderGetXvac(htup))) ||
  			TransactionIdDidAbort(HeapTupleHeaderGetXmin(htup)))
  		{
! 			LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 			ReleaseBuffer(buffer);
  			return (false);
  		}
  	}
  
! 	LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 	ReleaseBuffer(buffer);
  	return (true);
  }
  
Index: src/backend/commands/sequence.c
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/backend/commands/sequence.c,v
retrieving revision 1.105
diff -c -r1.105 sequence.c
*** src/backend/commands/sequence.c	29 Nov 2003 19:51:47 -0000	1.105
--- src/backend/commands/sequence.c	10 Dec 2003 22:34:31 -0000
***************
*** 1104,1110 ****
  
  	PageSetLSN(page, lsn);
  	PageSetSUI(page, ThisStartUpID);
! 	UnlockAndWriteBuffer(buffer);
  }
  
  void
--- 1104,1111 ----
  
  	PageSetLSN(page, lsn);
  	PageSetSUI(page, ThisStartUpID);
! 	LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
! 	WriteBuffer(buffer);
  }
  
  void
Index: src/backend/storage/buffer/buf_init.c
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/backend/storage/buffer/buf_init.c,v
retrieving revision 1.58
diff -c -r1.58 buf_init.c
*** src/backend/storage/buffer/buf_init.c	29 Nov 2003 19:51:56 -0000	1.58
--- src/backend/storage/buffer/buf_init.c	10 Dec 2003 22:34:31 -0000
***************
*** 34,50 ****
  #include "utils/hsearch.h"
  #include "utils/memutils.h"
  
- 
- /*
-  *	if BMTRACE is defined, we trace the last 200 buffer allocations and
-  *	deallocations in a circular buffer in shared memory.
-  */
- #ifdef	BMTRACE
- bmtrace    *TraceBuf;
- long	   *CurTraceBuf;
- 
- #define BMT_LIMIT		200
- #endif   /* BMTRACE */
  int			ShowPinTrace = 0;
  
  int			Data_Descriptors;
--- 34,39 ----
***************
*** 138,153 ****
  	 */
  	LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
  
- #ifdef BMTRACE
- 	CurTraceBuf = (long *) ShmemInitStruct("Buffer trace",
- 							(BMT_LIMIT * sizeof(bmtrace)) + sizeof(long),
- 										   &foundDescs);
- 	if (!foundDescs)
- 		MemSet(CurTraceBuf, 0, (BMT_LIMIT * sizeof(bmtrace)) + sizeof(long));
- 
- 	TraceBuf = (bmtrace *) & (CurTraceBuf[1]);
- #endif
- 
  	BufferDescriptors = (BufferDesc *)
  		ShmemInitStruct("Buffer Descriptors",
  					  Data_Descriptors * sizeof(BufferDesc), &foundDescs);
--- 127,132 ----
***************
*** 256,264 ****
  	/* size of buffer hash table */
  	size += hash_estimate_size(NBuffers, sizeof(BufferLookupEnt));
  
- #ifdef BMTRACE
- 	size += (BMT_LIMIT * sizeof(bmtrace)) + sizeof(long);
- #endif
- 
  	return size;
  }
--- 235,239 ----
Index: src/backend/storage/buffer/buf_table.c
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/backend/storage/buffer/buf_table.c,v
retrieving revision 1.33
diff -c -r1.33 buf_table.c
*** src/backend/storage/buffer/buf_table.c	29 Nov 2003 19:51:56 -0000	1.33
--- src/backend/storage/buffer/buf_table.c	10 Dec 2003 22:34:31 -0000
***************
*** 117,131 ****
  
  	return TRUE;
  }
- 
- /* prints out collision stats for the buf table */
- #ifdef NOT_USED
- void
- DBG_LookupListCheck(int nlookup)
- {
- 	nlookup = 10;
- 
- 	hash_stats("Shared", SharedBufHash);
- }
- 
- #endif
--- 117,119 ----
Index: src/backend/storage/buffer/bufmgr.c
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/backend/storage/buffer/bufmgr.c,v
retrieving revision 1.148
diff -c -r1.148 bufmgr.c
*** src/backend/storage/buffer/bufmgr.c	1 Dec 2003 16:53:19 -0000	1.148
--- src/backend/storage/buffer/bufmgr.c	10 Dec 2003 22:44:51 -0000
***************
*** 84,90 ****
  				   bool bufferLockHeld);
  static BufferDesc *BufferAlloc(Relation reln, BlockNumber blockNum,
  			bool *foundPtr);
! static int	BufferReplace(BufferDesc *bufHdr);
  
  #ifdef NOT_USED
  void		PrintBufferDescs(void);
--- 84,90 ----
  				   bool bufferLockHeld);
  static BufferDesc *BufferAlloc(Relation reln, BlockNumber blockNum,
  			bool *foundPtr);
! static bool BufferReplace(BufferDesc *bufHdr);
  
  #ifdef NOT_USED
  void		PrintBufferDescs(void);
***************
*** 109,121 ****
   *
   * Note: a side effect of a P_NEW call is to update reln->rd_nblocks.
   */
- 
- #undef ReadBuffer				/* conflicts with macro when BUFMGR_DEBUG
- 								 * defined */
- 
- /*
-  * ReadBuffer
-  */
  Buffer
  ReadBuffer(Relation reln, BlockNumber blockNum)
  {
--- 109,114 ----
***************
*** 363,377 ****
  			 * This is never going to happen, don't worry about it.
  			 */
  			*foundPtr = FALSE;
  		}
- #ifdef BMTRACE
- 		_bm_trace((reln->rd_rel->relisshared ? 0 : MyDatabaseId), RelationGetRelid(reln), blockNum, BufferDescriptorGetBuffer(buf), BMT_ALLOCFND);
- #endif   /* BMTRACE */
  
- 		if (!(*foundPtr))
- 			StartBufferIO(buf, true);
  		LWLockRelease(BufMgrLock);
- 
  		return buf;
  	}
  
--- 356,365 ----
  			 * This is never going to happen, don't worry about it.
  			 */
  			*foundPtr = FALSE;
+ 			StartBufferIO(buf, true);
  		}
  
  		LWLockRelease(BufMgrLock);
  		return buf;
  	}
  
***************
*** 402,408 ****
  
  		if (buf->flags & BM_DIRTY || buf->cntxDirty)
  		{
! 			bool		smok;
  
  			/*
  			 * skip write error buffers
--- 390,396 ----
  
  		if (buf->flags & BM_DIRTY || buf->cntxDirty)
  		{
! 			bool	replace_ok;
  
  			/*
  			 * skip write error buffers
***************
*** 436,444 ****
  			 * Write the buffer out, being careful to release BufMgrLock
  			 * before starting the I/O.
  			 */
! 			smok = BufferReplace(buf);
  
! 			if (smok == FALSE)
  			{
  				ereport(WARNING,
  						(errcode(ERRCODE_IO_ERROR),
--- 424,432 ----
  			 * Write the buffer out, being careful to release BufMgrLock
  			 * before starting the I/O.
  			 */
! 			replace_ok = BufferReplace(buf);
  
! 			if (replace_ok == false)
  			{
  				ereport(WARNING,
  						(errcode(ERRCODE_IO_ERROR),
***************
*** 465,472 ****
  						 buf->tag.blockNum,
  						 buf->tag.rnode.tblNode, buf->tag.rnode.relNode);
  				}
! 				else
! 					buf->flags &= ~BM_DIRTY;
  				buf->cntxDirty = false;
  			}
  
--- 453,460 ----
  						 buf->tag.blockNum,
  						 buf->tag.rnode.tblNode, buf->tag.rnode.relNode);
  				}
! 
! 				buf->flags &= ~BM_DIRTY;
  				buf->cntxDirty = false;
  			}
  
***************
*** 523,535 ****
  					WaitIO(buf2);
  					inProgress = (buf2->flags & BM_IO_IN_PROGRESS);
  				}
  				if (BUFFER_IS_BROKEN(buf2))
  					*foundPtr = FALSE;
- 
- 				if (!(*foundPtr))
  					StartBufferIO(buf2, true);
! 				LWLockRelease(BufMgrLock);
  
  				return buf2;
  			}
  		}
--- 511,524 ----
  					WaitIO(buf2);
  					inProgress = (buf2->flags & BM_IO_IN_PROGRESS);
  				}
+ 
  				if (BUFFER_IS_BROKEN(buf2))
+ 				{
  					*foundPtr = FALSE;
  					StartBufferIO(buf2, true);
! 				}
  
+ 				LWLockRelease(BufMgrLock);
  				return buf2;
  			}
  		}
***************
*** 558,567 ****
  	else
  		ContinueBufferIO(buf, true);
  
- #ifdef BMTRACE
- 	_bm_trace((reln->rd_rel->relisshared ? 0 : MyDatabaseId), RelationGetRelid(reln), blockNum, BufferDescriptorGetBuffer(buf), BMT_ALLOCNOTFND);
- #endif   /* BMTRACE */
- 
  	LWLockRelease(BufMgrLock);
  
  	return buf;
--- 547,552 ----
***************
*** 602,616 ****
   *
   *		Marks buffer contents as dirty (actual write happens later).
   *
!  * Assume that buffer is pinned.  Assume that reln is
!  *		valid.
   *
   * Side Effects:
   *		Pin count is decremented.
   */
- 
- #undef WriteBuffer
- 
  void
  WriteBuffer(Buffer buffer)
  {
--- 587,597 ----
   *
   *		Marks buffer contents as dirty (actual write happens later).
   *
!  * Assume that buffer is pinned.  Assume that reln is valid.
   *
   * Side Effects:
   *		Pin count is decremented.
   */
  void
  WriteBuffer(Buffer buffer)
  {
***************
*** 627,634 ****
  	write_buffer(buffer, false);
  }
  
- 
- #undef ReleaseAndReadBuffer
  /*
   * ReleaseAndReadBuffer -- combine ReleaseBuffer() and ReadBuffer()
   *		to save a lock release/acquire.
--- 608,613 ----
***************
*** 638,644 ****
   * Since the passed buffer must be pinned, it's OK to examine its block
   * number without getting the lock first.
   *
!  * Note: it is OK to pass buffer = InvalidBuffer, indicating that no old
   * buffer actually needs to be released.  This case is the same as ReadBuffer,
   * but can save some tests in the caller.
   *
--- 617,623 ----
   * Since the passed buffer must be pinned, it's OK to examine its block
   * number without getting the lock first.
   *
!  * Note: it is OK to pass buffer == InvalidBuffer, indicating that no old
   * buffer actually needs to be released.  This case is the same as ReadBuffer,
   * but can save some tests in the caller.
   *
***************
*** 1092,1102 ****
  /*
   * BufferReplace
   *
!  * Write out the buffer corresponding to 'bufHdr'
   *
   * BufMgrLock must be held at entry, and the buffer must be pinned.
   */
! static int
  BufferReplace(BufferDesc *bufHdr)
  {
  	Relation	reln;
--- 1071,1082 ----
  /*
   * BufferReplace
   *
!  * Write out the buffer corresponding to 'bufHdr'. Returns 'true' if
!  * the buffer was successfully written out, 'false' otherwise.
   *
   * BufMgrLock must be held at entry, and the buffer must be pinned.
   */
! static bool
  BufferReplace(BufferDesc *bufHdr)
  {
  	Relation	reln;
***************
*** 1147,1157 ****
  	LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
  
  	if (status == SM_FAIL)
! 		return FALSE;
  
  	BufferFlushCount++;
  
! 	return TRUE;
  }
  
  /*
--- 1127,1137 ----
  	LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
  
  	if (status == SM_FAIL)
! 		return false;
  
  	BufferFlushCount++;
  
! 	return true;
  }
  
  /*
***************
*** 1167,1173 ****
  	 * new or temp, because no one else should be modifying it.  Otherwise
  	 * we need to ask the smgr for the current physical file length.
  	 *
! 	 * Don't call smgr on a view, either.
  	 */
  	if (relation->rd_rel->relkind == RELKIND_VIEW)
  		relation->rd_nblocks = 0;
--- 1147,1153 ----
  	 * new or temp, because no one else should be modifying it.  Otherwise
  	 * we need to ask the smgr for the current physical file length.
  	 *
! 	 * Don't call smgr on a view or a composite type, either.
  	 */
  	if (relation->rd_rel->relkind == RELKIND_VIEW)
  		relation->rd_nblocks = 0;
***************
*** 1175,1180 ****
--- 1155,1161 ----
  		relation->rd_nblocks = 0;
  	else if (!relation->rd_isnew && !relation->rd_istemp)
  		relation->rd_nblocks = smgrnblocks(DEFAULT_SMGR, relation);
+ 
  	return relation->rd_nblocks;
  }
  
***************
*** 1623,1630 ****
  	return 0;
  }
  
- #undef ReleaseBuffer
- 
  /*
   * ReleaseBuffer -- remove the pin on a buffer without
   *		marking it dirty.
--- 1604,1609 ----
***************
*** 1737,1887 ****
  }
  #endif
  
- #ifdef BMTRACE
- 
- /*
-  *	trace allocations and deallocations in a circular buffer in
-  *	shared memory.	check the buffer before doing the allocation,
-  *	and die if there's anything fishy.
-  */
- 
- void
- _bm_trace(Oid dbId, Oid relId, int blkNo, int bufNo, int allocType)
- {
- 	long		start,
- 				cur;
- 	bmtrace    *tb;
- 
- 	start = *CurTraceBuf;
- 
- 	if (start > 0)
- 		cur = start - 1;
- 	else
- 		cur = BMT_LIMIT - 1;
- 
- 	for (;;)
- 	{
- 		tb = &TraceBuf[cur];
- 		if (tb->bmt_op != BMT_NOTUSED)
- 		{
- 			if (tb->bmt_buf == bufNo)
- 			{
- 				if ((tb->bmt_op == BMT_DEALLOC)
- 					|| (tb->bmt_dbid == dbId && tb->bmt_relid == relId
- 						&& tb->bmt_blkno == blkNo))
- 					goto okay;
- 
- 				/* die holding the buffer lock */
- 				_bm_die(dbId, relId, blkNo, bufNo, allocType, start, cur);
- 			}
- 		}
- 
- 		if (cur == start)
- 			goto okay;
- 
- 		if (cur == 0)
- 			cur = BMT_LIMIT - 1;
- 		else
- 			cur--;
- 	}
- 
- okay:
- 	tb = &TraceBuf[start];
- 	tb->bmt_pid = MyProcPid;
- 	tb->bmt_buf = bufNo;
- 	tb->bmt_dbid = dbId;
- 	tb->bmt_relid = relId;
- 	tb->bmt_blkno = blkNo;
- 	tb->bmt_op = allocType;
- 
- 	*CurTraceBuf = (start + 1) % BMT_LIMIT;
- }
- 
- void
- _bm_die(Oid dbId, Oid relId, int blkNo, int bufNo,
- 		int allocType, long start, long cur)
- {
- 	FILE	   *fp;
- 	bmtrace    *tb;
- 	int			i;
- 
- 	tb = &TraceBuf[cur];
- 
- 	if ((fp = AllocateFile("/tmp/death_notice", "w")) == NULL)
- 		elog(FATAL, "buffer alloc trace error and can't open log file");
- 
- 	fprintf(fp, "buffer alloc trace detected the following error:\n\n");
- 	fprintf(fp, "    buffer %d being %s inconsistently with a previous %s\n\n",
- 		 bufNo, (allocType == BMT_DEALLOC ? "deallocated" : "allocated"),
- 			(tb->bmt_op == BMT_DEALLOC ? "deallocation" : "allocation"));
- 
- 	fprintf(fp, "the trace buffer contains:\n");
- 
- 	i = start;
- 	for (;;)
- 	{
- 		tb = &TraceBuf[i];
- 		if (tb->bmt_op != BMT_NOTUSED)
- 		{
- 			fprintf(fp, "     [%3d]%spid %d buf %2d for <%u,%u,%u> ",
- 					i, (i == cur ? " ---> " : "\t"),
- 					tb->bmt_pid, tb->bmt_buf,
- 					tb->bmt_dbid, tb->bmt_relid, tb->bmt_blkno);
- 
- 			switch (tb->bmt_op)
- 			{
- 				case BMT_ALLOCFND:
- 					fprintf(fp, "allocate (found)\n");
- 					break;
- 
- 				case BMT_ALLOCNOTFND:
- 					fprintf(fp, "allocate (not found)\n");
- 					break;
- 
- 				case BMT_DEALLOC:
- 					fprintf(fp, "deallocate\n");
- 					break;
- 
- 				default:
- 					fprintf(fp, "unknown op type %d\n", tb->bmt_op);
- 					break;
- 			}
- 		}
- 
- 		i = (i + 1) % BMT_LIMIT;
- 		if (i == start)
- 			break;
- 	}
- 
- 	fprintf(fp, "\noperation causing error:\n");
- 	fprintf(fp, "\tpid %d buf %d for <%d,%u,%d> ",
- 			getpid(), bufNo, dbId, relId, blkNo);
- 
- 	switch (allocType)
- 	{
- 		case BMT_ALLOCFND:
- 			fprintf(fp, "allocate (found)\n");
- 			break;
- 
- 		case BMT_ALLOCNOTFND:
- 			fprintf(fp, "allocate (not found)\n");
- 			break;
- 
- 		case BMT_DEALLOC:
- 			fprintf(fp, "deallocate\n");
- 			break;
- 
- 		default:
- 			fprintf(fp, "unknown op type %d\n", allocType);
- 			break;
- 	}
- 
- 	FreeFile(fp);
- 
- 	kill(getpid(), SIGILL);
- }
- #endif   /* BMTRACE */
- 
  /*
   * SetBufferCommitInfoNeedsSave
   *
--- 1716,1721 ----
Index: src/include/storage/buf_internals.h
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/include/storage/buf_internals.h,v
retrieving revision 1.65
diff -c -r1.65 buf_internals.h
*** src/include/storage/buf_internals.h	29 Nov 2003 22:41:13 -0000	1.65
--- src/include/storage/buf_internals.h	10 Dec 2003 22:34:31 -0000
***************
*** 33,46 ****
   * Flags for buffer descriptors
   */
  #define BM_DIRTY				(1 << 0)
! #define BM_PRIVATE				(1 << 1)
! #define BM_VALID				(1 << 2)
! #define BM_DELETED				(1 << 3)
! #define BM_FREE					(1 << 4)
! #define BM_IO_IN_PROGRESS		(1 << 5)
! #define BM_IO_ERROR				(1 << 6)
! #define BM_JUST_DIRTIED			(1 << 7)
! #define BM_PIN_COUNT_WAITER		(1 << 8)
  
  typedef bits16 BufFlags;
  
--- 33,45 ----
   * Flags for buffer descriptors
   */
  #define BM_DIRTY				(1 << 0)
! #define BM_VALID				(1 << 1)
! #define BM_DELETED				(1 << 2)
! #define BM_FREE					(1 << 3)
! #define BM_IO_IN_PROGRESS		(1 << 4)
! #define BM_IO_ERROR				(1 << 5)
! #define BM_JUST_DIRTIED			(1 << 6)
! #define BM_PIN_COUNT_WAITER		(1 << 7)
  
  typedef bits16 BufFlags;
  
***************
*** 136,167 ****
  	Buffer		id;
  } BufferLookupEnt;
  
- /*
-  *	mao tracing buffer allocation
-  */
- 
- /*#define BMTRACE*/
- 
- #ifdef BMTRACE
- 
- typedef struct _bmtrace
- {
- 	int			bmt_pid;
- 	int			bmt_buf;
- 	Oid			bmt_dbid;
- 	Oid			bmt_relid;
- 	BlockNumber bmt_blkno;
- 	int			bmt_op;
- 
- #define BMT_NOTUSED		0
- #define BMT_ALLOCFND	1
- #define BMT_ALLOCNOTFND 2
- #define BMT_DEALLOC		3
- 
- }	bmtrace;
- #endif   /* BMTRACE */
- 
- 
  /* counters in buf_init.c */
  extern long int ReadBufferCount;
  extern long int ReadLocalBufferCount;
--- 135,140 ----
Index: src/include/storage/bufmgr.h
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/include/storage/bufmgr.h,v
retrieving revision 1.72
diff -c -r1.72 bufmgr.h
*** src/include/storage/bufmgr.h	29 Nov 2003 22:41:13 -0000	1.72
--- src/include/storage/bufmgr.h	10 Dec 2003 22:34:31 -0000
***************
*** 57,75 ****
   */
  
  #define BAD_BUFFER_ID(bid) ((bid) < 1 || (bid) > NBuffers)
- #define INVALID_DESCRIPTOR (-3)
- 
- #define UnlockAndReleaseBuffer(buffer)	\
- ( \
- 	LockBuffer(buffer, BUFFER_LOCK_UNLOCK), \
- 	ReleaseBuffer(buffer) \
- )
- 
- #define UnlockAndWriteBuffer(buffer)	\
- ( \
- 	LockBuffer(buffer, BUFFER_LOCK_UNLOCK), \
- 	WriteBuffer(buffer) \
- )
  
  /*
   * BufferIsValid
--- 57,62 ----
---------------------------(end of broadcast)---------------------------
TIP 3: if posting/reading through Usenet, please send an appropriate
      subscribe-nomail command to [EMAIL PROTECTED] so that your
      message can get through to the mailing list cleanly

Reply via email to