mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Replace RelationOpenSmgr() with RelationGetSmgr().
The idea behind this patch is to design out bugs like the one fixed
by commit 9d523119f
. Previously, once one did RelationOpenSmgr(rel),
it was considered okay to access rel->rd_smgr directly for some
not-very-clear interval. But since that pointer will be cleared by
relcache flushes, we had bugs arising from overreliance on a previous
RelationOpenSmgr call still being effective.
Now, very little code except that in rel.h and relcache.c should ever
touch the rd_smgr field directly. The normal coding rule is to use
RelationGetSmgr(rel) and not expect the result to be valid for longer
than one smgr function call. There are a couple of places where using
the function every single time seemed like overkill, but they are now
annotated with large warning comments.
Amul Sul, after an idea of mine.
Discussion: https://postgr.es/m/CANiYTQsU7yMFpQYnv=BrcRVqK_3U3mtAzAsJCaqtzsDHfsUbdQ@mail.gmail.com
This commit is contained in:
@ -301,8 +301,7 @@ bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed,
|
||||
bool heapkeyspace,
|
||||
allequalimage;
|
||||
|
||||
RelationOpenSmgr(indrel);
|
||||
if (!smgrexists(indrel->rd_smgr, MAIN_FORKNUM))
|
||||
if (!smgrexists(RelationGetSmgr(indrel), MAIN_FORKNUM))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INDEX_CORRUPTED),
|
||||
errmsg("index \"%s\" lacks a main relation fork",
|
||||
|
@ -177,9 +177,9 @@ blbuildempty(Relation index)
|
||||
* this even when wal_level=minimal.
|
||||
*/
|
||||
PageSetChecksumInplace(metapage, BLOOM_METAPAGE_BLKNO);
|
||||
smgrwrite(index->rd_smgr, INIT_FORKNUM, BLOOM_METAPAGE_BLKNO,
|
||||
smgrwrite(RelationGetSmgr(index), INIT_FORKNUM, BLOOM_METAPAGE_BLKNO,
|
||||
(char *) metapage, true);
|
||||
log_newpage(&index->rd_smgr->smgr_rnode.node, INIT_FORKNUM,
|
||||
log_newpage(&(RelationGetSmgr(index))->smgr_rnode.node, INIT_FORKNUM,
|
||||
BLOOM_METAPAGE_BLKNO, metapage, true);
|
||||
|
||||
/*
|
||||
@ -187,7 +187,7 @@ blbuildempty(Relation index)
|
||||
* write did not go through shared_buffers and therefore a concurrent
|
||||
* checkpoint may have moved the redo pointer past our xlog record.
|
||||
*/
|
||||
smgrimmedsync(index->rd_smgr, INIT_FORKNUM);
|
||||
smgrimmedsync(RelationGetSmgr(index), INIT_FORKNUM);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -514,15 +514,13 @@ autoprewarm_database_main(Datum main_arg)
|
||||
old_blk->filenode != blk->filenode ||
|
||||
old_blk->forknum != blk->forknum)
|
||||
{
|
||||
RelationOpenSmgr(rel);
|
||||
|
||||
/*
|
||||
* smgrexists is not safe for illegal forknum, hence check whether
|
||||
* the passed forknum is valid before using it in smgrexists.
|
||||
*/
|
||||
if (blk->forknum > InvalidForkNumber &&
|
||||
blk->forknum <= MAX_FORKNUM &&
|
||||
smgrexists(rel->rd_smgr, blk->forknum))
|
||||
smgrexists(RelationGetSmgr(rel), blk->forknum))
|
||||
nblocks = RelationGetNumberOfBlocksInFork(rel, blk->forknum);
|
||||
else
|
||||
nblocks = 0;
|
||||
|
@ -109,8 +109,7 @@ pg_prewarm(PG_FUNCTION_ARGS)
|
||||
aclcheck_error(aclresult, get_relkind_objtype(rel->rd_rel->relkind), get_rel_name(relOid));
|
||||
|
||||
/* Check that the fork exists. */
|
||||
RelationOpenSmgr(rel);
|
||||
if (!smgrexists(rel->rd_smgr, forkNumber))
|
||||
if (!smgrexists(RelationGetSmgr(rel), forkNumber))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("fork \"%s\" does not exist for this relation",
|
||||
@ -178,7 +177,7 @@ pg_prewarm(PG_FUNCTION_ARGS)
|
||||
for (block = first_block; block <= last_block; ++block)
|
||||
{
|
||||
CHECK_FOR_INTERRUPTS();
|
||||
smgrread(rel->rd_smgr, forkNumber, block, blockbuffer.data);
|
||||
smgrread(RelationGetSmgr(rel), forkNumber, block, blockbuffer.data);
|
||||
++blocks_done;
|
||||
}
|
||||
}
|
||||
|
@ -391,14 +391,14 @@ pg_truncate_visibility_map(PG_FUNCTION_ARGS)
|
||||
/* Only some relkinds have a visibility map */
|
||||
check_relation_relkind(rel);
|
||||
|
||||
RelationOpenSmgr(rel);
|
||||
rel->rd_smgr->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] = InvalidBlockNumber;
|
||||
/* Forcibly reset cached file size */
|
||||
RelationGetSmgr(rel)->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] = InvalidBlockNumber;
|
||||
|
||||
block = visibilitymap_prepare_truncate(rel, 0);
|
||||
if (BlockNumberIsValid(block))
|
||||
{
|
||||
fork = VISIBILITYMAP_FORKNUM;
|
||||
smgrtruncate(rel->rd_smgr, &fork, 1, &block);
|
||||
smgrtruncate(RelationGetSmgr(rel), &fork, 1, &block);
|
||||
}
|
||||
|
||||
if (RelationNeedsWAL(rel))
|
||||
|
Reference in New Issue
Block a user