Commit 386f1809 authored by Tom Lane's avatar Tom Lane

Fix logic error in insert_fsm_page_entry: because compact_fsm_page_list

removes any empty chunks, the chunk previously added won't be there
anymore, so it's possible there is zero free space in the rel's page list
afterwards.  Must loop back and rerun the part that adds a chunk to
the list.
parent cf77a2a0
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/freespace/freespace.c,v 1.10 2001/11/05 17:46:27 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/freespace/freespace.c,v 1.11 2002/01/24 15:31:43 tgl Exp $
* *
* *
* NOTES: * NOTES:
...@@ -841,12 +841,14 @@ static bool ...@@ -841,12 +841,14 @@ static bool
insert_fsm_page_entry(FSMRelation *fsmrel, BlockNumber page, Size spaceAvail, insert_fsm_page_entry(FSMRelation *fsmrel, BlockNumber page, Size spaceAvail,
FSMChunk *chunk, int chunkRelIndex) FSMChunk *chunk, int chunkRelIndex)
{ {
FSMChunk *newChunk; /* Outer loop handles retry after compacting rel's page list */
int newChunkRelIndex; for (;;)
{
if (fsmrel->numPages >= fsmrel->numChunks * CHUNKPAGES) if (fsmrel->numPages >= fsmrel->numChunks * CHUNKPAGES)
{ {
/* No free space within chunk list, so need another chunk */ /* No free space within chunk list, so need another chunk */
FSMChunk *newChunk;
if ((newChunk = FreeSpaceMap->freeChunks) == NULL) if ((newChunk = FreeSpaceMap->freeChunks) == NULL)
return false; /* can't do it */ return false; /* can't do it */
FreeSpaceMap->freeChunks = newChunk->next; FreeSpaceMap->freeChunks = newChunk->next;
...@@ -885,20 +887,13 @@ insert_fsm_page_entry(FSMRelation *fsmrel, BlockNumber page, Size spaceAvail, ...@@ -885,20 +887,13 @@ insert_fsm_page_entry(FSMRelation *fsmrel, BlockNumber page, Size spaceAvail,
* There is space available, but evidently it's before the place where * There is space available, but evidently it's before the place where
* the page entry needs to go. Compact the list and try again. This * the page entry needs to go. Compact the list and try again. This
* will require us to redo the search for the appropriate place. * will require us to redo the search for the appropriate place.
* Furthermore, compact_fsm_page_list deletes empty end chunks, so
* we may need to repeat the action of grabbing a new end chunk.
*/ */
compact_fsm_page_list(fsmrel); compact_fsm_page_list(fsmrel);
if (lookup_fsm_page_entry(fsmrel, page, &newChunk, &newChunkRelIndex)) if (lookup_fsm_page_entry(fsmrel, page, &chunk, &chunkRelIndex))
elog(ERROR, "insert_fsm_page_entry: entry already exists!"); elog(ERROR, "insert_fsm_page_entry: entry already exists!");
if (newChunk &&
push_fsm_page_entry(page, spaceAvail, newChunk, newChunkRelIndex))
{
fsmrel->numPages++;
fsmrel->nextPage++; /* don't return same page twice running */
return true;
} }
/* Shouldn't get here given the initial if-test for space available */
elog(ERROR, "insert_fsm_page_entry: failed to insert entry!");
return false; /* keep compiler quiet */
} }
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment