* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/freespace/freespace.c,v 1.67 2008/11/19 10:34:52 heikki Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/freespace/freespace.c,v 1.68 2008/11/26 17:08:57 heikki Exp $
*
*
* NOTES:
static BlockNumber fsm_logical_to_physical(FSMAddress addr);
static Buffer fsm_readbuf(Relation rel, FSMAddress addr, bool extend);
-static void fsm_extend(Relation rel, BlockNumber nfsmblocks, bool createstorage);
+static void fsm_extend(Relation rel, BlockNumber fsm_nblocks);
/* functions to convert amount of free space to a FSM category */
static uint8 fsm_space_avail_to_cat(Size avail);
smgrtruncate(rel->rd_smgr, FSM_FORKNUM, new_nfsmblocks, rel->rd_istemp);
/*
- * Need to invalidate the relcache entry, because rd_fsm_nblocks_cache
+ * Need to invalidate the relcache entry, because rd_fsm_nblocks
* seen by other backends is no longer valid.
*/
if (!InRecovery)
CacheInvalidateRelcache(rel);
- rel->rd_fsm_nblocks_cache = new_nfsmblocks;
+ rel->rd_fsm_nblocks = new_nfsmblocks;
}
/*
RelationOpenSmgr(rel);
- if (rel->rd_fsm_nblocks_cache == InvalidBlockNumber ||
- rel->rd_fsm_nblocks_cache <= blkno)
+ /* If we haven't cached the size of the FSM yet, check it first */
+ if (rel->rd_fsm_nblocks == InvalidBlockNumber)
{
- if (!smgrexists(rel->rd_smgr, FSM_FORKNUM))
- fsm_extend(rel, blkno + 1, true);
+ if (smgrexists(rel->rd_smgr, FSM_FORKNUM))
+ rel->rd_fsm_nblocks = smgrnblocks(rel->rd_smgr, FSM_FORKNUM);
else
- rel->rd_fsm_nblocks_cache = smgrnblocks(rel->rd_smgr, FSM_FORKNUM);
+ rel->rd_fsm_nblocks = 0;
}
- if (blkno >= rel->rd_fsm_nblocks_cache)
+ /* Handle requests beyond EOF */
+ if (blkno >= rel->rd_fsm_nblocks)
{
if (extend)
- fsm_extend(rel, blkno + 1, false);
+ fsm_extend(rel, blkno + 1);
else
return InvalidBuffer;
}
/*
* Ensure that the FSM fork is at least n_fsmblocks long, extending
* it if necessary with empty pages. And by empty, I mean pages filled
- * with zeros, meaning there's no free space. If createstorage is true,
- * the FSM file might need to be created first.
+ * with zeros, meaning there's no free space.
*/
static void
-fsm_extend(Relation rel, BlockNumber n_fsmblocks, bool createstorage)
+fsm_extend(Relation rel, BlockNumber fsm_nblocks)
{
- BlockNumber n_fsmblocks_now;
+ BlockNumber fsm_nblocks_now;
Page pg;
pg = (Page) palloc(BLCKSZ);
LockRelationForExtension(rel, ExclusiveLock);
/* Create the FSM file first if it doesn't exist */
- if (createstorage && !smgrexists(rel->rd_smgr, FSM_FORKNUM))
+ if ((rel->rd_fsm_nblocks == 0 || rel->rd_fsm_nblocks == InvalidBlockNumber)
+ && !smgrexists(rel->rd_smgr, FSM_FORKNUM))
{
smgrcreate(rel->rd_smgr, FSM_FORKNUM, false);
- n_fsmblocks_now = 0;
+ fsm_nblocks_now = 0;
}
else
- n_fsmblocks_now = smgrnblocks(rel->rd_smgr, FSM_FORKNUM);
+ fsm_nblocks_now = smgrnblocks(rel->rd_smgr, FSM_FORKNUM);
- while (n_fsmblocks_now < n_fsmblocks)
+ while (fsm_nblocks_now < fsm_nblocks)
{
- smgrextend(rel->rd_smgr, FSM_FORKNUM, n_fsmblocks_now,
+ smgrextend(rel->rd_smgr, FSM_FORKNUM, fsm_nblocks_now,
(char *) pg, rel->rd_istemp);
- n_fsmblocks_now++;
+ fsm_nblocks_now++;
}
UnlockRelationForExtension(rel, ExclusiveLock);
pfree(pg);
- /* update the cache with the up-to-date size */
- rel->rd_fsm_nblocks_cache = n_fsmblocks_now;
+ /* Update the relcache with the up-to-date size */
+ if (!InRecovery)
+ CacheInvalidateRelcache(rel);
+ rel->rd_fsm_nblocks = fsm_nblocks_now;
}
/*
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.276 2008/11/10 00:49:37 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.277 2008/11/26 17:08:57 heikki Exp $
*
*-------------------------------------------------------------------------
*/
*/
MemSet(relation, 0, sizeof(RelationData));
relation->rd_targblock = InvalidBlockNumber;
- relation->rd_fsm_nblocks_cache = InvalidBlockNumber;
+ relation->rd_fsm_nblocks = InvalidBlockNumber;
/* make sure relation is marked as having no open file yet */
relation->rd_smgr = NULL;
*/
relation = (Relation) palloc0(sizeof(RelationData));
relation->rd_targblock = InvalidBlockNumber;
- relation->rd_fsm_nblocks_cache = InvalidBlockNumber;
+ relation->rd_fsm_nblocks = InvalidBlockNumber;
/* make sure relation is marked as having no open file yet */
relation->rd_smgr = NULL;
heap_freetuple(pg_class_tuple);
/* We must recalculate physical address in case it changed */
RelationInitPhysicalAddr(relation);
- /* Must reset targblock and fsm_nblocks_cache in case rel was truncated */
+ /* Must reset targblock and fsm_nblocks in case rel was truncated */
relation->rd_targblock = InvalidBlockNumber;
- relation->rd_fsm_nblocks_cache = InvalidBlockNumber;
+ relation->rd_fsm_nblocks = InvalidBlockNumber;
/* Must free any AM cached data, too */
if (relation->rd_amcache)
pfree(relation->rd_amcache);
if (relation->rd_isnailed)
{
relation->rd_targblock = InvalidBlockNumber;
- relation->rd_fsm_nblocks_cache = InvalidBlockNumber;
+ relation->rd_fsm_nblocks = InvalidBlockNumber;
if (relation->rd_rel->relkind == RELKIND_INDEX)
{
relation->rd_isvalid = false; /* needs to be revalidated */
rel = (Relation) palloc0(sizeof(RelationData));
rel->rd_targblock = InvalidBlockNumber;
- rel->rd_fsm_nblocks_cache = InvalidBlockNumber;
+ rel->rd_fsm_nblocks = InvalidBlockNumber;
/* make sure relation is marked as having no open file yet */
rel->rd_smgr = NULL;
*/
rel->rd_smgr = NULL;
rel->rd_targblock = InvalidBlockNumber;
- rel->rd_fsm_nblocks_cache = InvalidBlockNumber;
+ rel->rd_fsm_nblocks = InvalidBlockNumber;
if (rel->rd_isnailed)
rel->rd_refcnt = 1;
else
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/rel.h,v 1.108 2008/09/30 10:52:14 heikki Exp $
+ * $PostgreSQL: pgsql/src/include/utils/rel.h,v 1.109 2008/11/26 17:08:58 heikki Exp $
*
*-------------------------------------------------------------------------
*/
List *rd_indpred; /* index predicate tree, if any */
void *rd_amcache; /* available for use by index AM */
- /* Cached last-seen size of the FSM */
- BlockNumber rd_fsm_nblocks_cache;
+ /* size of the FSM, or InvalidBlockNumber if not known yet */
+ BlockNumber rd_fsm_nblocks;
/* use "struct" here to avoid needing to include pgstat.h: */
struct PgStat_TableStatus *pgstat_info; /* statistics collection area */