*
  *
  * 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 $
  *
  *-------------------------------------------------------------------------
  */
 
 #include "lib/stringinfo.h"
 #include "miscadmin.h"
+#include "postmaster/bgwriter.h"
 #include "storage/buf_internals.h"
 #include "storage/bufmgr.h"
 #include "storage/bufpage.h"
 #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;
 {
    int         buf_id;
    int         num_to_scan;
+   int         absorb_counter;
 
    /*
     * Find out where to start the circular scan.
     * 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;
    }
 
  *
  *
  * 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 $
  *
  *-------------------------------------------------------------------------
  */
 #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
 {
    HASH_SEQ_STATUS hstat;
    PendingOperationEntry *entry;
+   int         absorb_counter;
 
    if (!pendingOpsTable)
        return false;
     */
    AbsorbFsyncRequests();
 
+   absorb_counter = FSYNCS_PER_ABSORB;
    hash_seq_init(&hstat, pendingOpsTable);
    while ((entry = (PendingOperationEntry *) hash_seq_search(&hstat)) != NULL)
    {
            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