mirror of
https://github.com/postgres/postgres.git
synced 2025-06-26 12:21:12 +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:
@ -589,9 +589,6 @@ PrefetchBuffer(Relation reln, ForkNumber forkNum, BlockNumber blockNum)
|
||||
Assert(RelationIsValid(reln));
|
||||
Assert(BlockNumberIsValid(blockNum));
|
||||
|
||||
/* Open it at the smgr level if not already done */
|
||||
RelationOpenSmgr(reln);
|
||||
|
||||
if (RelationUsesLocalBuffers(reln))
|
||||
{
|
||||
/* see comments in ReadBufferExtended */
|
||||
@ -601,12 +598,12 @@ PrefetchBuffer(Relation reln, ForkNumber forkNum, BlockNumber blockNum)
|
||||
errmsg("cannot access temporary tables of other sessions")));
|
||||
|
||||
/* pass it off to localbuf.c */
|
||||
return PrefetchLocalBuffer(reln->rd_smgr, forkNum, blockNum);
|
||||
return PrefetchLocalBuffer(RelationGetSmgr(reln), forkNum, blockNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* pass it to the shared buffer version */
|
||||
return PrefetchSharedBuffer(reln->rd_smgr, forkNum, blockNum);
|
||||
return PrefetchSharedBuffer(RelationGetSmgr(reln), forkNum, blockNum);
|
||||
}
|
||||
}
|
||||
|
||||
@ -747,9 +744,6 @@ ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum,
|
||||
bool hit;
|
||||
Buffer buf;
|
||||
|
||||
/* Open it at the smgr level if not already done */
|
||||
RelationOpenSmgr(reln);
|
||||
|
||||
/*
|
||||
* Reject attempts to read non-local temporary relations; we would be
|
||||
* likely to get wrong data since we have no visibility into the owning
|
||||
@ -765,7 +759,7 @@ ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum,
|
||||
* miss.
|
||||
*/
|
||||
pgstat_count_buffer_read(reln);
|
||||
buf = ReadBuffer_common(reln->rd_smgr, reln->rd_rel->relpersistence,
|
||||
buf = ReadBuffer_common(RelationGetSmgr(reln), reln->rd_rel->relpersistence,
|
||||
forkNum, blockNum, mode, strategy, &hit);
|
||||
if (hit)
|
||||
pgstat_count_buffer_hit(reln);
|
||||
@ -2949,10 +2943,7 @@ RelationGetNumberOfBlocksInFork(Relation relation, ForkNumber forkNum)
|
||||
case RELKIND_SEQUENCE:
|
||||
case RELKIND_INDEX:
|
||||
case RELKIND_PARTITIONED_INDEX:
|
||||
/* Open it at the smgr level if not already done */
|
||||
RelationOpenSmgr(relation);
|
||||
|
||||
return smgrnblocks(relation->rd_smgr, forkNum);
|
||||
return smgrnblocks(RelationGetSmgr(relation), forkNum);
|
||||
|
||||
case RELKIND_RELATION:
|
||||
case RELKIND_TOASTVALUE:
|
||||
@ -3527,9 +3518,6 @@ FlushRelationBuffers(Relation rel)
|
||||
int i;
|
||||
BufferDesc *bufHdr;
|
||||
|
||||
/* Open rel at the smgr level if not already done */
|
||||
RelationOpenSmgr(rel);
|
||||
|
||||
if (RelationUsesLocalBuffers(rel))
|
||||
{
|
||||
for (i = 0; i < NLocBuffer; i++)
|
||||
@ -3554,7 +3542,7 @@ FlushRelationBuffers(Relation rel)
|
||||
|
||||
PageSetChecksumInplace(localpage, bufHdr->tag.blockNum);
|
||||
|
||||
smgrwrite(rel->rd_smgr,
|
||||
smgrwrite(RelationGetSmgr(rel),
|
||||
bufHdr->tag.forkNum,
|
||||
bufHdr->tag.blockNum,
|
||||
localpage,
|
||||
@ -3595,7 +3583,7 @@ FlushRelationBuffers(Relation rel)
|
||||
{
|
||||
PinBuffer_Locked(bufHdr);
|
||||
LWLockAcquire(BufferDescriptorGetContentLock(bufHdr), LW_SHARED);
|
||||
FlushBuffer(bufHdr, rel->rd_smgr);
|
||||
FlushBuffer(bufHdr, RelationGetSmgr(rel));
|
||||
LWLockRelease(BufferDescriptorGetContentLock(bufHdr));
|
||||
UnpinBuffer(bufHdr, true);
|
||||
}
|
||||
|
Reference in New Issue
Block a user