diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 11e83812d0c0712053995fd7347a04e29f7a9912..41ca4c14495f88983f344d2ae29c9a5271dfbcaf 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.202 2006/01/06 00:04:20 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.203 2006/03/03 00:02:01 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -42,6 +42,7 @@
 
 #include "lib/stringinfo.h"
 #include "miscadmin.h"
+#include "postmaster/bgwriter.h"
 #include "storage/buf_internals.h"
 #include "storage/bufmgr.h"
 #include "storage/bufpage.h"
@@ -61,6 +62,9 @@
 #define LocalBufHdrGetBlock(bufHdr) \
 	LocalBufferBlockPointers[-((bufHdr)->buf_id + 2)]
 
+/* interval for calling AbsorbFsyncRequests in BufferSync */
+#define WRITES_PER_ABSORB		1000
+
 
 /* GUC variables */
 bool		zero_damaged_pages = false;
@@ -892,6 +896,7 @@ BufferSync(void)
 {
 	int			buf_id;
 	int			num_to_scan;
+	int			absorb_counter;
 
 	/*
 	 * Find out where to start the circular scan.
@@ -905,9 +910,23 @@ BufferSync(void)
 	 * Loop over all buffers.
 	 */
 	num_to_scan = NBuffers;
+	absorb_counter = WRITES_PER_ABSORB;
 	while (num_to_scan-- > 0)
 	{
-		(void) SyncOneBuffer(buf_id, false);
+		if (SyncOneBuffer(buf_id, false))
+		{
+			/*
+			 * If in bgwriter, absorb pending fsync requests after each
+			 * WRITES_PER_ABSORB write operations, to prevent overflow of
+			 * the fsync request queue.  If not in bgwriter process, this is
+			 * a no-op.
+			 */
+			if (--absorb_counter <= 0)
+			{
+				AbsorbFsyncRequests();
+				absorb_counter = WRITES_PER_ABSORB;
+			}
+		}
 		if (++buf_id >= NBuffers)
 			buf_id = 0;
 	}
diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c
index f8d15ee3ff85206e1bd9349463aa114ce8c64a91..60d8a229639eb455deac2f065c64381af4f81fd4 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.118 2005/10/15 02:49:26 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/storage/smgr/md.c,v 1.119 2006/03/03 00:02:02 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -28,6 +28,9 @@
 #include "utils/memutils.h"
 
 
+/* interval for calling AbsorbFsyncRequests in mdsync */
+#define FSYNCS_PER_ABSORB		10
+
 /*
  *	The magnetic disk storage manager keeps track of open file
  *	descriptors in its own descriptor pool.  This is done to make it
@@ -702,6 +705,7 @@ mdsync(void)
 {
 	HASH_SEQ_STATUS hstat;
 	PendingOperationEntry *entry;
+	int			absorb_counter;
 
 	if (!pendingOpsTable)
 		return false;
@@ -714,6 +718,7 @@ mdsync(void)
 	 */
 	AbsorbFsyncRequests();
 
+	absorb_counter = FSYNCS_PER_ABSORB;
 	hash_seq_init(&hstat, pendingOpsTable);
 	while ((entry = (PendingOperationEntry *) hash_seq_search(&hstat)) != NULL)
 	{
@@ -727,6 +732,19 @@ mdsync(void)
 			SMgrRelation reln;
 			MdfdVec    *seg;
 
+			/*
+			 * If in bgwriter, absorb pending requests every so often to
+			 * prevent overflow of the fsync request queue.  The hashtable
+			 * code does not specify whether entries added by this will be
+			 * visited by our search, but we don't really care: it's OK if
+			 * we do, and OK if we don't.
+			 */
+			if (--absorb_counter <= 0)
+			{
+				AbsorbFsyncRequests();
+				absorb_counter = FSYNCS_PER_ABSORB;
+			}
+
 			/*
 			 * Find or create an smgr hash entry for this relation. This may
 			 * seem a bit unclean -- md calling smgr?  But it's really the