88 * Portions Copyright (c) 1994, Regents of the University of California
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/storage/freespace/freespace.c,v 1.67 2008/11/19 10:34:52 heikki Exp $
11+ * $PostgreSQL: pgsql/src/backend/storage/freespace/freespace.c,v 1.68 2008/11/26 17:08:57 heikki Exp $
1212 *
1313 *
1414 * NOTES:
@@ -101,7 +101,7 @@ static BlockNumber fsm_get_heap_blk(FSMAddress addr, uint16 slot);
101101static BlockNumber fsm_logical_to_physical (FSMAddress addr );
102102
103103static Buffer fsm_readbuf (Relation rel ,FSMAddress addr ,bool extend );
104- static void fsm_extend (Relation rel ,BlockNumber nfsmblocks , bool createstorage );
104+ static void fsm_extend (Relation rel ,BlockNumber fsm_nblocks );
105105
106106/* functions to convert amount of free space to a FSM category */
107107static uint8 fsm_space_avail_to_cat (Size avail );
@@ -303,13 +303,13 @@ FreeSpaceMapTruncateRel(Relation rel, BlockNumber nblocks)
303303smgrtruncate (rel -> rd_smgr ,FSM_FORKNUM ,new_nfsmblocks ,rel -> rd_istemp );
304304
305305/*
306- * Need to invalidate the relcache entry, becauserd_fsm_nblocks_cache
306+ * Need to invalidate the relcache entry, becauserd_fsm_nblocks
307307 * seen by other backends is no longer valid.
308308 */
309309if (!InRecovery )
310310CacheInvalidateRelcache (rel );
311311
312- rel -> rd_fsm_nblocks_cache = new_nfsmblocks ;
312+ rel -> rd_fsm_nblocks = new_nfsmblocks ;
313313}
314314
315315/*
@@ -503,19 +503,20 @@ fsm_readbuf(Relation rel, FSMAddress addr, bool extend)
503503
504504RelationOpenSmgr (rel );
505505
506- if ( rel -> rd_fsm_nblocks_cache == InvalidBlockNumber ||
507- rel -> rd_fsm_nblocks_cache <= blkno )
506+ /* If we haven't cached the size of the FSM yet, check it first */
507+ if ( rel -> rd_fsm_nblocks == InvalidBlockNumber )
508508{
509- if (! smgrexists (rel -> rd_smgr ,FSM_FORKNUM ))
510- fsm_extend ( rel , blkno + 1 , true );
509+ if (smgrexists (rel -> rd_smgr ,FSM_FORKNUM ))
510+ rel -> rd_fsm_nblocks = smgrnblocks ( rel -> rd_smgr , FSM_FORKNUM );
511511else
512- rel -> rd_fsm_nblocks_cache = smgrnblocks ( rel -> rd_smgr , FSM_FORKNUM ) ;
512+ rel -> rd_fsm_nblocks = 0 ;
513513}
514514
515- if (blkno >=rel -> rd_fsm_nblocks_cache )
515+ /* Handle requests beyond EOF */
516+ if (blkno >=rel -> rd_fsm_nblocks )
516517{
517518if (extend )
518- fsm_extend (rel ,blkno + 1 , false );
519+ fsm_extend (rel ,blkno + 1 );
519520else
520521return InvalidBuffer ;
521522}
@@ -536,13 +537,12 @@ fsm_readbuf(Relation rel, FSMAddress addr, bool extend)
536537/*
537538 * Ensure that the FSM fork is at least n_fsmblocks long, extending
538539 * it if necessary with empty pages. And by empty, I mean pages filled
539- * with zeros, meaning there's no free space. If createstorage is true,
540- * the FSM file might need to be created first.
540+ * with zeros, meaning there's no free space.
541541 */
542542static void
543- fsm_extend (Relation rel ,BlockNumber n_fsmblocks , bool createstorage )
543+ fsm_extend (Relation rel ,BlockNumber fsm_nblocks )
544544{
545- BlockNumber n_fsmblocks_now ;
545+ BlockNumber fsm_nblocks_now ;
546546Page pg ;
547547
548548pg = (Page )palloc (BLCKSZ );
@@ -561,27 +561,30 @@ fsm_extend(Relation rel, BlockNumber n_fsmblocks, bool createstorage)
561561LockRelationForExtension (rel ,ExclusiveLock );
562562
563563/* Create the FSM file first if it doesn't exist */
564- if (createstorage && !smgrexists (rel -> rd_smgr ,FSM_FORKNUM ))
564+ if ((rel -> rd_fsm_nblocks == 0 || rel -> rd_fsm_nblocks == InvalidBlockNumber )
565+ && !smgrexists (rel -> rd_smgr ,FSM_FORKNUM ))
565566{
566567smgrcreate (rel -> rd_smgr ,FSM_FORKNUM , false);
567- n_fsmblocks_now = 0 ;
568+ fsm_nblocks_now = 0 ;
568569}
569570else
570- n_fsmblocks_now = smgrnblocks (rel -> rd_smgr ,FSM_FORKNUM );
571+ fsm_nblocks_now = smgrnblocks (rel -> rd_smgr ,FSM_FORKNUM );
571572
572- while (n_fsmblocks_now < n_fsmblocks )
573+ while (fsm_nblocks_now < fsm_nblocks )
573574{
574- smgrextend (rel -> rd_smgr ,FSM_FORKNUM ,n_fsmblocks_now ,
575+ smgrextend (rel -> rd_smgr ,FSM_FORKNUM ,fsm_nblocks_now ,
575576 (char * )pg ,rel -> rd_istemp );
576- n_fsmblocks_now ++ ;
577+ fsm_nblocks_now ++ ;
577578}
578579
579580UnlockRelationForExtension (rel ,ExclusiveLock );
580581
581582pfree (pg );
582583
583- /* update the cache with the up-to-date size */
584- rel -> rd_fsm_nblocks_cache = n_fsmblocks_now ;
584+ /* Update the relcache with the up-to-date size */
585+ if (!InRecovery )
586+ CacheInvalidateRelcache (rel );
587+ rel -> rd_fsm_nblocks = fsm_nblocks_now ;
585588}
586589
587590/*