diff -rcN postgresql-CVS-01-19.org/src/backend/access/transam/readahead.c postgresql-CVS-01-19/src/backend/access/transam/readahead.c
*** postgresql-CVS-01-19.org/src/backend/access/transam/readahead.c	2009-01-20 14:27:45.000000000 +0900
--- postgresql-CVS-01-19/src/backend/access/transam/readahead.c	2009-01-20 17:03:38.000000000 +0900
***************
*** 20,25 ****
--- 20,26 ----
  #include "catalog/catalog.h"
  #include "storage/relfilenode.h"
  #include "storage/block.h"
+ #include "storage/bufmgr.h"
  #include "storage/smgr.h"
  
  /*
***************
*** 135,141 ****
  ReadAheadExecute(void)
  {
  	int i;
- 	SMgrRelation reln;
  	XLogReadAhead last_entry = { { 0, 0, 0, }, 0, 0, false };
  
  	ereport(DEBUG1, (errmsg("%d blocks are prefetch candidate",
--- 136,141 ----
***************
*** 155,166 ****
  			continue;
  		}
  
- 		/* Create SMgrRelation object */
- 		reln = smgropen(ReadAheadQueue[i].node);
- 
  		/* Read ahead with prefetch API */
! 		smgrprefetch(reln, MAIN_FORKNUM, ReadAheadQueue[i].blkno);
! 			
  		/* Store XLogReadAhead to skip duplicate pages. */
  		last_entry = ReadAheadQueue[i];
  	}
--- 155,164 ----
  			continue;
  		}
  
  		/* Read ahead with prefetch API */
! 		PrefetchBufferWithoutRelcache(ReadAheadQueue[i].node, false,
! 								MAIN_FORKNUM, ReadAheadQueue[i].blkno);
! 
  		/* Store XLogReadAhead to skip duplicate pages. */
  		last_entry = ReadAheadQueue[i];
  	}
diff -rcN postgresql-CVS-01-19.org/src/backend/storage/buffer/bufmgr.c postgresql-CVS-01-19/src/backend/storage/buffer/bufmgr.c
*** postgresql-CVS-01-19.org/src/backend/storage/buffer/bufmgr.c	2009-01-20 14:23:15.000000000 +0900
--- postgresql-CVS-01-19/src/backend/storage/buffer/bufmgr.c	2009-01-20 17:59:27.000000000 +0900
***************
*** 79,85 ****
  /* local state for LockBufferForCleanup */
  static volatile BufferDesc *PinCountWaitBuf = NULL;
  
! 
  static Buffer ReadBuffer_common(SMgrRelation reln, bool isLocalBuf,
  					ForkNumber forkNum, BlockNumber blockNum,
  					ReadBufferMode mode , BufferAccessStrategy strategy,
--- 79,86 ----
  /* local state for LockBufferForCleanup */
  static volatile BufferDesc *PinCountWaitBuf = NULL;
  
! static void PrefetchBuffer_common(SMgrRelation smgr, bool isTemp,
!                         ForkNumber forkNum, BlockNumber blockNum);
  static Buffer ReadBuffer_common(SMgrRelation reln, bool isLocalBuf,
  					ForkNumber forkNum, BlockNumber blockNum,
  					ReadBufferMode mode , BufferAccessStrategy strategy,
***************
*** 109,114 ****
--- 110,119 ----
   * buffer.  Instead it tries to ensure that a future ReadBuffer for the given
   * block will not be delayed by the I/O.  Prefetching is optional.
   * No-op if prefetching isn't compiled in.
+  *
+  * To provide the prefetch API for during recovery, prepare interfaces
+  * and a prefetch API call separately.  This is based on ReadBuffer(),
+  * ReadBufferExtended(), and ReadBuffer_common().
   */
  void
  PrefetchBuffer(Relation reln, ForkNumber forkNum, BlockNumber blockNum)
***************
*** 119,129 ****
  
  	/* Open it at the smgr level if not already done */
  	RelationOpenSmgr(reln);
  
! 	if (reln->rd_istemp)
  	{
  		/* pass it off to localbuf.c */
! 		LocalPrefetchBuffer(reln->rd_smgr, forkNum, blockNum);
  	}
  	else
  	{
--- 124,165 ----
  
  	/* Open it at the smgr level if not already done */
  	RelationOpenSmgr(reln);
+ 	
+ 	/* Prefetch the buffer */
+ 	PrefetchBuffer_common(reln->rd_smgr, reln->rd_istemp, forkNum, blockNum);
+ #endif /* USE_PREFETCH */
+ }
+ 
+ /*
+  * PrefetchBufferWithoutRelcache -- like ReadBufferWithoutRelcache, it doesn't
+  * require relcache entry for the relation.
+  */
+ void
+ PrefetchBufferWithoutRelcache(RelFileNode rnode, bool isTemp,
+ 							  ForkNumber forkNum, BlockNumber blockNum)
+ {
+ #ifdef USE_PREFETCH
+ 	SMgrRelation smgr;
  
! 	/* Create SMgrRelation object */
! 	smgr = smgropen(rnode);
! 	
! 	/* Prefetch the buffer */
! 	PrefetchBuffer_common(smgr, isTemp, forkNum, blockNum);
! #endif /* USE_PREFETCH */
! }
! 
! /*
!  * PrefetchBuffer_common -- common logic for all PrefetchBuffer variants
!  */
! static void
! PrefetchBuffer_common(SMgrRelation smgr, bool isTemp, ForkNumber forkNum,
! 						BlockNumber blockNum)
! {
! 	if (isTemp)
  	{
  		/* pass it off to localbuf.c */
! 		LocalPrefetchBuffer(smgr, forkNum, blockNum);
  	}
  	else
  	{
***************
*** 133,139 ****
  		int			buf_id;
  
  		/* create a tag so we can lookup the buffer */
! 		INIT_BUFFERTAG(newTag, reln->rd_smgr->smgr_rnode, forkNum, blockNum);
  
  		/* determine its hash code and partition lock ID */
  		newHash = BufTableHashCode(&newTag);
--- 169,175 ----
  		int			buf_id;
  
  		/* create a tag so we can lookup the buffer */
! 		INIT_BUFFERTAG(newTag, smgr->smgr_rnode, forkNum, blockNum);
  
  		/* determine its hash code and partition lock ID */
  		newHash = BufTableHashCode(&newTag);
***************
*** 146,157 ****
  
  		/* If not in buffers, initiate prefetch */
  		if (buf_id < 0)
! 			smgrprefetch(reln->rd_smgr, forkNum, blockNum);
  	}
- #endif /* USE_PREFETCH */
  }
  
- 
  /*
   * ReadBuffer -- a shorthand for ReadBufferExtended, for reading from main
   *		fork with RBM_NORMAL mode and default strategy.
--- 182,191 ----
  
  		/* If not in buffers, initiate prefetch */
  		if (buf_id < 0)
! 			smgrprefetch(smgr, forkNum, blockNum);
  	}
  }
  
  /*
   * ReadBuffer -- a shorthand for ReadBufferExtended, for reading from main
   *		fork with RBM_NORMAL mode and default strategy.
diff -rcN postgresql-CVS-01-19.org/src/include/storage/bufmgr.h postgresql-CVS-01-19/src/include/storage/bufmgr.h
*** postgresql-CVS-01-19.org/src/include/storage/bufmgr.h	2009-01-20 14:23:14.000000000 +0900
--- postgresql-CVS-01-19/src/include/storage/bufmgr.h	2009-01-20 17:07:25.000000000 +0900
***************
*** 155,160 ****
--- 155,162 ----
   */
  extern void PrefetchBuffer(Relation reln, ForkNumber forkNum,
  						   BlockNumber blockNum);
+ extern void PrefetchBufferWithoutRelcache(RelFileNode rnode, bool isTemp,
+ 								ForkNumber forkNum, BlockNumber blockNum);
  extern Buffer ReadBuffer(Relation reln, BlockNumber blockNum);
  extern Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum,
  								 BlockNumber blockNum, ReadBufferMode mode,