On Tue, Apr 20, 2021 at 6:59 AM Kyotaro Horiguchi <horikyota....@gmail.com> wrote: > > At Mon, 19 Apr 2021 16:27:25 +0530, Amul Sul <sula...@gmail.com> wrote in > > On Mon, Apr 19, 2021 at 2:05 PM Kyotaro Horiguchi > > <horikyota....@gmail.com> wrote: > > > + 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, > > > > > > At the log_newpage, index is guaranteed to have rd_smgr. So I prefer > > > to leave the line alone.. I don't mind other sccessive calls if any > > > since what I don't like is the notation there. > > > > > > > Perhaps, isn't that bad. It is good to follow the practice of using > > RelationGetSmgr() for rd_smgr access, IMHO. > > I don't mind RelationGetSmgr(index)->smgr_rnode alone or > &variable->member alone and there's not the previous call to > RelationGetSmgr just above. How about using a temporary variable? > > SMgrRelation srel = RelationGetSmgr(index); > smgrwrite(srel, ...); > log_newpage(srel->..); >
Understood. Used a temporary variable for the place where RelationGetSmgr() calls are placed too close or in a loop. Please have a look at the attached version, thanks for the review. Regards, Amul
From d3043a97044d506ab9255c6d6d446ad962ee308c Mon Sep 17 00:00:00 2001 From: Amul Sul <amul.sul@enterprisedb.com> Date: Mon, 19 Apr 2021 03:16:27 -0400 Subject: [PATCH] Add RelationGetSmgr inline function --- contrib/amcheck/verify_nbtree.c | 3 +- contrib/bloom/blinsert.c | 7 ++-- contrib/pg_prewarm/autoprewarm.c | 4 +- contrib/pg_prewarm/pg_prewarm.c | 5 +-- contrib/pg_visibility/pg_visibility.c | 7 ++-- src/backend/access/gist/gistbuild.c | 15 ++++---- src/backend/access/hash/hashpage.c | 4 +- src/backend/access/heap/heapam_handler.c | 9 +++-- src/backend/access/heap/rewriteheap.c | 11 ++---- src/backend/access/heap/visibilitymap.c | 46 +++++++++-------------- src/backend/access/nbtree/nbtree.c | 7 ++-- src/backend/access/nbtree/nbtsort.c | 16 +++----- src/backend/access/spgist/spginsert.c | 15 ++++---- src/backend/access/table/tableam.c | 8 ++-- src/backend/catalog/heap.c | 2 - src/backend/catalog/index.c | 5 +-- src/backend/catalog/storage.c | 18 ++++----- src/backend/commands/tablecmds.c | 9 +++-- src/backend/storage/buffer/bufmgr.c | 25 ++++-------- src/backend/storage/freespace/freespace.c | 40 ++++++++++---------- src/include/utils/rel.h | 21 ++++++----- 21 files changed, 122 insertions(+), 155 deletions(-) diff --git a/contrib/amcheck/verify_nbtree.c b/contrib/amcheck/verify_nbtree.c index b31906cbcfd..7f34eed04ba 100644 --- a/contrib/amcheck/verify_nbtree.c +++ b/contrib/amcheck/verify_nbtree.c @@ -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", diff --git a/contrib/bloom/blinsert.c b/contrib/bloom/blinsert.c index c34a640d1c4..ae10174d94a 100644 --- a/contrib/bloom/blinsert.c +++ b/contrib/bloom/blinsert.c @@ -164,6 +164,7 @@ void blbuildempty(Relation index) { Page metapage; + SMgrRelation reln = RelationGetSmgr(index); /* Construct metapage. */ metapage = (Page) palloc(BLCKSZ); @@ -177,9 +178,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(reln, INIT_FORKNUM, BLOOM_METAPAGE_BLKNO, (char *) metapage, true); - log_newpage(&index->rd_smgr->smgr_rnode.node, INIT_FORKNUM, + log_newpage(&reln->smgr_rnode.node, INIT_FORKNUM, BLOOM_METAPAGE_BLKNO, metapage, true); /* @@ -187,7 +188,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(reln, INIT_FORKNUM); } /* diff --git a/contrib/pg_prewarm/autoprewarm.c b/contrib/pg_prewarm/autoprewarm.c index b3f73ea92d6..0289ea657cb 100644 --- a/contrib/pg_prewarm/autoprewarm.c +++ b/contrib/pg_prewarm/autoprewarm.c @@ -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; diff --git a/contrib/pg_prewarm/pg_prewarm.c b/contrib/pg_prewarm/pg_prewarm.c index a8554529361..c8f8c214ace 100644 --- a/contrib/pg_prewarm/pg_prewarm.c +++ b/contrib/pg_prewarm/pg_prewarm.c @@ -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; } } diff --git a/contrib/pg_visibility/pg_visibility.c b/contrib/pg_visibility/pg_visibility.c index dd0c124e625..a869d2bc666 100644 --- a/contrib/pg_visibility/pg_visibility.c +++ b/contrib/pg_visibility/pg_visibility.c @@ -385,20 +385,21 @@ pg_truncate_visibility_map(PG_FUNCTION_ARGS) Relation rel; ForkNumber fork; BlockNumber block; + SMgrRelation reln; rel = relation_open(relid, AccessExclusiveLock); /* Only some relkinds have a visibility map */ check_relation_relkind(rel); - RelationOpenSmgr(rel); - rel->rd_smgr->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] = InvalidBlockNumber; + reln = RelationGetSmgr(rel); + reln->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(reln, &fork, 1, &block); } if (RelationNeedsWAL(rel)) diff --git a/src/backend/access/gist/gistbuild.c b/src/backend/access/gist/gistbuild.c index 1054f6f1f2e..2af0a29ae3e 100644 --- a/src/backend/access/gist/gistbuild.c +++ b/src/backend/access/gist/gistbuild.c @@ -409,8 +409,7 @@ gist_indexsortbuild(GISTBuildState *state) * replaced with the real root page at the end. */ page = palloc0(BLCKSZ); - RelationOpenSmgr(state->indexrel); - smgrextend(state->indexrel->rd_smgr, MAIN_FORKNUM, GIST_ROOT_BLKNO, + smgrextend(RelationGetSmgr(state->indexrel), MAIN_FORKNUM, GIST_ROOT_BLKNO, page, true); state->pages_allocated++; state->pages_written++; @@ -450,10 +449,9 @@ gist_indexsortbuild(GISTBuildState *state) gist_indexsortbuild_flush_ready_pages(state); /* Write out the root */ - RelationOpenSmgr(state->indexrel); PageSetLSN(pagestate->page, GistBuildLSN); PageSetChecksumInplace(pagestate->page, GIST_ROOT_BLKNO); - smgrwrite(state->indexrel->rd_smgr, MAIN_FORKNUM, GIST_ROOT_BLKNO, + smgrwrite(RelationGetSmgr(state->indexrel), MAIN_FORKNUM, GIST_ROOT_BLKNO, pagestate->page, true); if (RelationNeedsWAL(state->indexrel)) log_newpage(&state->indexrel->rd_node, MAIN_FORKNUM, GIST_ROOT_BLKNO, @@ -559,10 +557,12 @@ gist_indexsortbuild_pagestate_flush(GISTBuildState *state, static void gist_indexsortbuild_flush_ready_pages(GISTBuildState *state) { + SMgrRelation reln; + if (state->ready_num_pages == 0) return; - RelationOpenSmgr(state->indexrel); + reln = RelationGetSmgr(state->indexrel); for (int i = 0; i < state->ready_num_pages; i++) { @@ -575,7 +575,7 @@ gist_indexsortbuild_flush_ready_pages(GISTBuildState *state) PageSetLSN(page, GistBuildLSN); PageSetChecksumInplace(page, blkno); - smgrextend(state->indexrel->rd_smgr, MAIN_FORKNUM, blkno, page, true); + smgrextend(reln, MAIN_FORKNUM, blkno, page, true); state->pages_written++; } @@ -860,7 +860,8 @@ gistBuildCallback(Relation index, */ if ((buildstate->buildMode == GIST_BUFFERING_AUTO && buildstate->indtuples % BUFFERING_MODE_SWITCH_CHECK_STEP == 0 && - effective_cache_size < smgrnblocks(index->rd_smgr, MAIN_FORKNUM)) || + effective_cache_size < smgrnblocks(RelationGetSmgr(index), + MAIN_FORKNUM)) || (buildstate->buildMode == GIST_BUFFERING_STATS && buildstate->indtuples >= BUFFERING_MODE_TUPLE_SIZE_STATS_TARGET)) { diff --git a/src/backend/access/hash/hashpage.c b/src/backend/access/hash/hashpage.c index 49a98677876..b5ca02f0927 100644 --- a/src/backend/access/hash/hashpage.c +++ b/src/backend/access/hash/hashpage.c @@ -1024,9 +1024,9 @@ _hash_alloc_buckets(Relation rel, BlockNumber firstblock, uint32 nblocks) zerobuf.data, true); - RelationOpenSmgr(rel); PageSetChecksumInplace(page, lastblock); - smgrextend(rel->rd_smgr, MAIN_FORKNUM, lastblock, zerobuf.data, false); + smgrextend(RelationGetSmgr(rel), MAIN_FORKNUM, lastblock, zerobuf.data, + false); return true; } diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index 7a9a640989a..5a8d64c2884 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -625,9 +625,10 @@ static void heapam_relation_copy_data(Relation rel, const RelFileNode *newrnode) { SMgrRelation dstrel; + SMgrRelation srcrel; dstrel = smgropen(*newrnode, rel->rd_backend); - RelationOpenSmgr(rel); + srcrel = RelationGetSmgr(rel); /* * Since we copy the file directly without looking at the shared buffers, @@ -647,14 +648,14 @@ heapam_relation_copy_data(Relation rel, const RelFileNode *newrnode) RelationCreateStorage(*newrnode, rel->rd_rel->relpersistence); /* copy main fork */ - RelationCopyStorage(rel->rd_smgr, dstrel, MAIN_FORKNUM, + RelationCopyStorage(srcrel, dstrel, MAIN_FORKNUM, rel->rd_rel->relpersistence); /* copy those extra forks that exist */ for (ForkNumber forkNum = MAIN_FORKNUM + 1; forkNum <= MAX_FORKNUM; forkNum++) { - if (smgrexists(rel->rd_smgr, forkNum)) + if (smgrexists(srcrel, forkNum)) { smgrcreate(dstrel, forkNum, false); @@ -666,7 +667,7 @@ heapam_relation_copy_data(Relation rel, const RelFileNode *newrnode) (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED && forkNum == INIT_FORKNUM)) log_smgrcreate(newrnode, forkNum); - RelationCopyStorage(rel->rd_smgr, dstrel, forkNum, + RelationCopyStorage(srcrel, dstrel, forkNum, rel->rd_rel->relpersistence); } } diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c index 1aff62cd423..18af11c6b9a 100644 --- a/src/backend/access/heap/rewriteheap.c +++ b/src/backend/access/heap/rewriteheap.c @@ -326,9 +326,8 @@ end_heap_rewrite(RewriteState state) PageSetChecksumInplace(state->rs_buffer, state->rs_blockno); - RelationOpenSmgr(state->rs_new_rel); - smgrextend(state->rs_new_rel->rd_smgr, MAIN_FORKNUM, state->rs_blockno, - (char *) state->rs_buffer, true); + smgrextend(RelationGetSmgr(state->rs_new_rel), MAIN_FORKNUM, + state->rs_blockno, (char *) state->rs_buffer, true); } /* @@ -341,8 +340,7 @@ end_heap_rewrite(RewriteState state) if (RelationNeedsWAL(state->rs_new_rel)) { /* for an empty table, this could be first smgr access */ - RelationOpenSmgr(state->rs_new_rel); - smgrimmedsync(state->rs_new_rel->rd_smgr, MAIN_FORKNUM); + smgrimmedsync(RelationGetSmgr(state->rs_new_rel), MAIN_FORKNUM); } logical_end_heap_rewrite(state); @@ -695,11 +693,10 @@ raw_heap_insert(RewriteState state, HeapTuple tup) * need for smgr to schedule an fsync for this write; we'll do it * ourselves in end_heap_rewrite. */ - RelationOpenSmgr(state->rs_new_rel); PageSetChecksumInplace(page, state->rs_blockno); - smgrextend(state->rs_new_rel->rd_smgr, MAIN_FORKNUM, + smgrextend(RelationGetSmgr(state->rs_new_rel), MAIN_FORKNUM, state->rs_blockno, (char *) page, true); state->rs_blockno++; diff --git a/src/backend/access/heap/visibilitymap.c b/src/backend/access/heap/visibilitymap.c index e198df65d82..097235bc2cf 100644 --- a/src/backend/access/heap/visibilitymap.c +++ b/src/backend/access/heap/visibilitymap.c @@ -455,13 +455,11 @@ visibilitymap_prepare_truncate(Relation rel, BlockNumber nheapblocks) elog(DEBUG1, "vm_truncate %s %d", RelationGetRelationName(rel), nheapblocks); #endif - RelationOpenSmgr(rel); - /* * If no visibility map has been created yet for this relation, there's * nothing to truncate. */ - if (!smgrexists(rel->rd_smgr, VISIBILITYMAP_FORKNUM)) + if (!smgrexists(RelationGetSmgr(rel), VISIBILITYMAP_FORKNUM)) return InvalidBlockNumber; /* @@ -528,7 +526,7 @@ visibilitymap_prepare_truncate(Relation rel, BlockNumber nheapblocks) else newnblocks = truncBlock; - if (smgrnblocks(rel->rd_smgr, VISIBILITYMAP_FORKNUM) <= newnblocks) + if (smgrnblocks(RelationGetSmgr(rel), VISIBILITYMAP_FORKNUM) <= newnblocks) { /* nothing to do, the file was already smaller than requested size */ return InvalidBlockNumber; @@ -547,30 +545,22 @@ static Buffer vm_readbuf(Relation rel, BlockNumber blkno, bool extend) { Buffer buf; - - /* - * We might not have opened the relation at the smgr level yet, or we - * might have been forced to close it by a sinval message. The code below - * won't necessarily notice relation extension immediately when extend = - * false, so we rely on sinval messages to ensure that our ideas about the - * size of the map aren't too far out of date. - */ - RelationOpenSmgr(rel); + SMgrRelation reln = RelationGetSmgr(rel); /* * If we haven't cached the size of the visibility map fork yet, check it * first. */ - if (rel->rd_smgr->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] == InvalidBlockNumber) + if (reln->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] == InvalidBlockNumber) { - if (smgrexists(rel->rd_smgr, VISIBILITYMAP_FORKNUM)) - smgrnblocks(rel->rd_smgr, VISIBILITYMAP_FORKNUM); + if (smgrexists(reln, VISIBILITYMAP_FORKNUM)) + smgrnblocks(reln, VISIBILITYMAP_FORKNUM); else - rel->rd_smgr->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] = 0; + reln->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] = 0; } /* Handle requests beyond EOF */ - if (blkno >= rel->rd_smgr->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM]) + if (blkno >= reln->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM]) { if (extend) vm_extend(rel, blkno + 1); @@ -618,6 +608,7 @@ vm_extend(Relation rel, BlockNumber vm_nblocks) { BlockNumber vm_nblocks_now; PGAlignedBlock pg; + SMgrRelation reln; PageInit((Page) pg.data, BLCKSZ, 0); @@ -634,28 +625,27 @@ vm_extend(Relation rel, BlockNumber vm_nblocks) LockRelationForExtension(rel, ExclusiveLock); /* Might have to re-open if a cache flush happened */ - RelationOpenSmgr(rel); + reln = RelationGetSmgr(rel); /* * Create the file first if it doesn't exist. If smgr_vm_nblocks is * positive then it must exist, no need for an smgrexists call. */ - if ((rel->rd_smgr->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] == 0 || - rel->rd_smgr->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] == InvalidBlockNumber) && - !smgrexists(rel->rd_smgr, VISIBILITYMAP_FORKNUM)) - smgrcreate(rel->rd_smgr, VISIBILITYMAP_FORKNUM, false); + if ((reln->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] == 0 || + reln->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] == InvalidBlockNumber) && + !smgrexists(reln, VISIBILITYMAP_FORKNUM)) + smgrcreate(reln, VISIBILITYMAP_FORKNUM, false); /* Invalidate cache so that smgrnblocks() asks the kernel. */ - rel->rd_smgr->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] = InvalidBlockNumber; - vm_nblocks_now = smgrnblocks(rel->rd_smgr, VISIBILITYMAP_FORKNUM); + reln->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] = InvalidBlockNumber; + vm_nblocks_now = smgrnblocks(reln, VISIBILITYMAP_FORKNUM); /* Now extend the file */ while (vm_nblocks_now < vm_nblocks) { PageSetChecksumInplace((Page) pg.data, vm_nblocks_now); - smgrextend(rel->rd_smgr, VISIBILITYMAP_FORKNUM, vm_nblocks_now, - pg.data, false); + smgrextend(reln, VISIBILITYMAP_FORKNUM, vm_nblocks_now, pg.data, false); vm_nblocks_now++; } @@ -666,7 +656,7 @@ vm_extend(Relation rel, BlockNumber vm_nblocks) * to keep checking for creation or extension of the file, which happens * infrequently. */ - CacheInvalidateSmgr(rel->rd_smgr->smgr_rnode); + CacheInvalidateSmgr(reln->smgr_rnode); UnlockRelationForExtension(rel, ExclusiveLock); } diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index 1360ab80c1e..236e3b5976b 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -150,6 +150,7 @@ void btbuildempty(Relation index) { Page metapage; + SMgrRelation reln = RelationGetSmgr(index); /* Construct metapage. */ metapage = (Page) palloc(BLCKSZ); @@ -163,9 +164,9 @@ btbuildempty(Relation index) * this even when wal_level=minimal. */ PageSetChecksumInplace(metapage, BTREE_METAPAGE); - smgrwrite(index->rd_smgr, INIT_FORKNUM, BTREE_METAPAGE, + smgrwrite(reln, INIT_FORKNUM, BTREE_METAPAGE, (char *) metapage, true); - log_newpage(&index->rd_smgr->smgr_rnode.node, INIT_FORKNUM, + log_newpage(&reln->smgr_rnode.node, INIT_FORKNUM, BTREE_METAPAGE, metapage, true); /* @@ -173,7 +174,7 @@ btbuildempty(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(reln, INIT_FORKNUM); } /* diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c index 2c4d7f6e25a..b2ba15dc3c3 100644 --- a/src/backend/access/nbtree/nbtsort.c +++ b/src/backend/access/nbtree/nbtsort.c @@ -636,8 +636,7 @@ _bt_blnewpage(uint32 level) static void _bt_blwritepage(BTWriteState *wstate, Page page, BlockNumber blkno) { - /* Ensure rd_smgr is open (could have been closed by relcache flush!) */ - RelationOpenSmgr(wstate->index); + SMgrRelation reln = RelationGetSmgr(wstate->index); /* XLOG stuff */ if (wstate->btws_use_wal) @@ -658,7 +657,7 @@ _bt_blwritepage(BTWriteState *wstate, Page page, BlockNumber blkno) if (!wstate->btws_zeropage) wstate->btws_zeropage = (Page) palloc0(BLCKSZ); /* don't set checksum for all-zero page */ - smgrextend(wstate->index->rd_smgr, MAIN_FORKNUM, + smgrextend(reln, MAIN_FORKNUM, wstate->btws_pages_written++, (char *) wstate->btws_zeropage, true); @@ -673,15 +672,13 @@ _bt_blwritepage(BTWriteState *wstate, Page page, BlockNumber blkno) if (blkno == wstate->btws_pages_written) { /* extending the file... */ - smgrextend(wstate->index->rd_smgr, MAIN_FORKNUM, blkno, - (char *) page, true); + smgrextend(reln, MAIN_FORKNUM, blkno, (char *) page, true); wstate->btws_pages_written++; } else { /* overwriting a block we zero-filled before */ - smgrwrite(wstate->index->rd_smgr, MAIN_FORKNUM, blkno, - (char *) page, true); + smgrwrite(reln, MAIN_FORKNUM, blkno, (char *) page, true); } pfree(page); @@ -1427,10 +1424,7 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2) * still not be on disk when the crash occurs. */ if (wstate->btws_use_wal) - { - RelationOpenSmgr(wstate->index); - smgrimmedsync(wstate->index->rd_smgr, MAIN_FORKNUM); - } + smgrimmedsync(RelationGetSmgr(wstate->index), MAIN_FORKNUM); } /* diff --git a/src/backend/access/spgist/spginsert.c b/src/backend/access/spgist/spginsert.c index 1af0af7da21..dabe07d7e64 100644 --- a/src/backend/access/spgist/spginsert.c +++ b/src/backend/access/spgist/spginsert.c @@ -156,6 +156,7 @@ void spgbuildempty(Relation index) { Page page; + SMgrRelation reln = RelationGetSmgr(index); /* Construct metapage. */ page = (Page) palloc(BLCKSZ); @@ -169,27 +170,27 @@ spgbuildempty(Relation index) * replayed. */ PageSetChecksumInplace(page, SPGIST_METAPAGE_BLKNO); - smgrwrite(index->rd_smgr, INIT_FORKNUM, SPGIST_METAPAGE_BLKNO, + smgrwrite(reln, INIT_FORKNUM, SPGIST_METAPAGE_BLKNO, (char *) page, true); - log_newpage(&index->rd_smgr->smgr_rnode.node, INIT_FORKNUM, + log_newpage(&reln->smgr_rnode.node, INIT_FORKNUM, SPGIST_METAPAGE_BLKNO, page, true); /* Likewise for the root page. */ SpGistInitPage(page, SPGIST_LEAF); PageSetChecksumInplace(page, SPGIST_ROOT_BLKNO); - smgrwrite(index->rd_smgr, INIT_FORKNUM, SPGIST_ROOT_BLKNO, + smgrwrite(reln, INIT_FORKNUM, SPGIST_ROOT_BLKNO, (char *) page, true); - log_newpage(&index->rd_smgr->smgr_rnode.node, INIT_FORKNUM, + log_newpage(&reln->smgr_rnode.node, INIT_FORKNUM, SPGIST_ROOT_BLKNO, page, true); /* Likewise for the null-tuples root page. */ SpGistInitPage(page, SPGIST_LEAF | SPGIST_NULLS); PageSetChecksumInplace(page, SPGIST_NULL_BLKNO); - smgrwrite(index->rd_smgr, INIT_FORKNUM, SPGIST_NULL_BLKNO, + smgrwrite(reln, INIT_FORKNUM, SPGIST_NULL_BLKNO, (char *) page, true); - log_newpage(&index->rd_smgr->smgr_rnode.node, INIT_FORKNUM, + log_newpage(&reln->smgr_rnode.node, INIT_FORKNUM, SPGIST_NULL_BLKNO, page, true); /* @@ -197,7 +198,7 @@ spgbuildempty(Relation index) * writes 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(reln, INIT_FORKNUM); } /* diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 5ea5bdd8104..d15b7aa4174 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -628,18 +628,16 @@ uint64 table_block_relation_size(Relation rel, ForkNumber forkNumber) { uint64 nblocks = 0; - - /* Open it at the smgr level if not already done */ - RelationOpenSmgr(rel); + SMgrRelation reln = RelationGetSmgr(rel); /* InvalidForkNumber indicates returning the size for all forks */ if (forkNumber == InvalidForkNumber) { for (int i = 0; i < MAX_FORKNUM; i++) - nblocks += smgrnblocks(rel->rd_smgr, i); + nblocks += smgrnblocks(reln, i); } else - nblocks = smgrnblocks(rel->rd_smgr, forkNumber); + nblocks = smgrnblocks(reln, forkNumber); return nblocks * BLCKSZ; } diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index ba03e8aa8f3..e77e579b6aa 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -414,8 +414,6 @@ heap_create(const char *relname, */ if (create_storage) { - RelationOpenSmgr(rel); - switch (rel->rd_rel->relkind) { case RELKIND_VIEW: diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index a628b3281ce..489bd1bf109 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3147,10 +3147,9 @@ index_build(Relation heapRelation, * relfilenode won't change, and nothing needs to be done here. */ if (indexRelation->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED && - !smgrexists(indexRelation->rd_smgr, INIT_FORKNUM)) + !smgrexists(RelationGetSmgr(indexRelation), INIT_FORKNUM)) { - RelationOpenSmgr(indexRelation); - smgrcreate(indexRelation->rd_smgr, INIT_FORKNUM, false); + smgrcreate(RelationGetSmgr(indexRelation), INIT_FORKNUM, false); indexRelation->rd_indam->ambuildempty(indexRelation); } diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c index cba7a9ada07..b288d85f4f6 100644 --- a/src/backend/catalog/storage.c +++ b/src/backend/catalog/storage.c @@ -282,16 +282,14 @@ RelationTruncate(Relation rel, BlockNumber nblocks) ForkNumber forks[MAX_FORKNUM]; BlockNumber blocks[MAX_FORKNUM]; int nforks = 0; - - /* Open it at the smgr level if not already done */ - RelationOpenSmgr(rel); + SMgrRelation reln = RelationGetSmgr(rel); /* * Make sure smgr_targblock etc aren't pointing somewhere past new end */ - rel->rd_smgr->smgr_targblock = InvalidBlockNumber; + reln->smgr_targblock = InvalidBlockNumber; for (int i = 0; i <= MAX_FORKNUM; ++i) - rel->rd_smgr->smgr_cached_nblocks[i] = InvalidBlockNumber; + reln->smgr_cached_nblocks[i] = InvalidBlockNumber; /* Prepare for truncation of MAIN fork of the relation */ forks[nforks] = MAIN_FORKNUM; @@ -299,7 +297,7 @@ RelationTruncate(Relation rel, BlockNumber nblocks) nforks++; /* Prepare for truncation of the FSM if it exists */ - fsm = smgrexists(rel->rd_smgr, FSM_FORKNUM); + fsm = smgrexists(reln, FSM_FORKNUM); if (fsm) { blocks[nforks] = FreeSpaceMapPrepareTruncateRel(rel, nblocks); @@ -312,7 +310,7 @@ RelationTruncate(Relation rel, BlockNumber nblocks) } /* Prepare for truncation of the visibility map too if it exists */ - vm = smgrexists(rel->rd_smgr, VISIBILITYMAP_FORKNUM); + vm = smgrexists(reln, VISIBILITYMAP_FORKNUM); if (vm) { blocks[nforks] = visibilitymap_prepare_truncate(rel, nblocks); @@ -364,7 +362,7 @@ RelationTruncate(Relation rel, BlockNumber nblocks) } /* Do the real work to truncate relation forks */ - smgrtruncate(rel->rd_smgr, forks, nforks, blocks); + smgrtruncate(reln, forks, nforks, blocks); /* * Update upper-level FSM pages to account for the truncation. This is @@ -389,9 +387,9 @@ RelationPreTruncate(Relation rel) if (!pendingSyncHash) return; - RelationOpenSmgr(rel); - pending = hash_search(pendingSyncHash, &(rel->rd_smgr->smgr_rnode.node), + pending = hash_search(pendingSyncHash, + &(RelationGetSmgr(rel)->smgr_rnode.node), HASH_FIND, NULL); if (pending) pending->is_truncated = true; diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 096a6f28915..5311c79772d 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -13997,9 +13997,10 @@ static void index_copy_data(Relation rel, RelFileNode newrnode) { SMgrRelation dstrel; + SMgrRelation srcrel; dstrel = smgropen(newrnode, rel->rd_backend); - RelationOpenSmgr(rel); + srcrel = RelationGetSmgr(rel); /* * Since we copy the file directly without looking at the shared buffers, @@ -14019,14 +14020,14 @@ index_copy_data(Relation rel, RelFileNode newrnode) RelationCreateStorage(newrnode, rel->rd_rel->relpersistence); /* copy main fork */ - RelationCopyStorage(rel->rd_smgr, dstrel, MAIN_FORKNUM, + RelationCopyStorage(srcrel, dstrel, MAIN_FORKNUM, rel->rd_rel->relpersistence); /* copy those extra forks that exist */ for (ForkNumber forkNum = MAIN_FORKNUM + 1; forkNum <= MAX_FORKNUM; forkNum++) { - if (smgrexists(rel->rd_smgr, forkNum)) + if (smgrexists(srcrel, forkNum)) { smgrcreate(dstrel, forkNum, false); @@ -14038,7 +14039,7 @@ index_copy_data(Relation rel, RelFileNode newrnode) (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED && forkNum == INIT_FORKNUM)) log_smgrcreate(&newrnode, forkNum); - RelationCopyStorage(rel->rd_smgr, dstrel, forkNum, + RelationCopyStorage(srcrel, dstrel, forkNum, rel->rd_rel->relpersistence); } } diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 0c5b87864b9..853e87b64c9 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -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: @@ -3526,9 +3517,7 @@ FlushRelationBuffers(Relation rel) { int i; BufferDesc *bufHdr; - - /* Open rel at the smgr level if not already done */ - RelationOpenSmgr(rel); + SMgrRelation reln = RelationGetSmgr(rel); if (RelationUsesLocalBuffers(rel)) { @@ -3554,7 +3543,7 @@ FlushRelationBuffers(Relation rel) PageSetChecksumInplace(localpage, bufHdr->tag.blockNum); - smgrwrite(rel->rd_smgr, + smgrwrite(reln, bufHdr->tag.forkNum, bufHdr->tag.blockNum, localpage, @@ -3595,7 +3584,7 @@ FlushRelationBuffers(Relation rel) { PinBuffer_Locked(bufHdr); LWLockAcquire(BufferDescriptorGetContentLock(bufHdr), LW_SHARED); - FlushBuffer(bufHdr, rel->rd_smgr); + FlushBuffer(bufHdr, reln); LWLockRelease(BufferDescriptorGetContentLock(bufHdr)); UnpinBuffer(bufHdr, true); } diff --git a/src/backend/storage/freespace/freespace.c b/src/backend/storage/freespace/freespace.c index cfa0414e5ab..684d37cce8e 100644 --- a/src/backend/storage/freespace/freespace.c +++ b/src/backend/storage/freespace/freespace.c @@ -266,13 +266,11 @@ FreeSpaceMapPrepareTruncateRel(Relation rel, BlockNumber nblocks) uint16 first_removed_slot; Buffer buf; - RelationOpenSmgr(rel); - /* * If no FSM has been created yet for this relation, there's nothing to * truncate. */ - if (!smgrexists(rel->rd_smgr, FSM_FORKNUM)) + if (!smgrexists(RelationGetSmgr(rel), FSM_FORKNUM)) return InvalidBlockNumber; /* Get the location in the FSM of the first removed heap block */ @@ -318,7 +316,7 @@ FreeSpaceMapPrepareTruncateRel(Relation rel, BlockNumber nblocks) else { new_nfsmblocks = fsm_logical_to_physical(first_removed_address); - if (smgrnblocks(rel->rd_smgr, FSM_FORKNUM) <= new_nfsmblocks) + if (smgrnblocks(RelationGetSmgr(rel), FSM_FORKNUM) <= new_nfsmblocks) return InvalidBlockNumber; /* nothing to do; the FSM was already * smaller */ } @@ -533,8 +531,7 @@ fsm_readbuf(Relation rel, FSMAddress addr, bool extend) { BlockNumber blkno = fsm_logical_to_physical(addr); Buffer buf; - - RelationOpenSmgr(rel); + SMgrRelation reln = RelationGetSmgr(rel); /* * If we haven't cached the size of the FSM yet, check it first. Also @@ -542,19 +539,19 @@ fsm_readbuf(Relation rel, FSMAddress addr, bool extend) * value might be stale. (We send smgr inval messages on truncation, but * not on extension.) */ - if (rel->rd_smgr->smgr_cached_nblocks[FSM_FORKNUM] == InvalidBlockNumber || - blkno >= rel->rd_smgr->smgr_cached_nblocks[FSM_FORKNUM]) + if (reln->smgr_cached_nblocks[FSM_FORKNUM] == InvalidBlockNumber || + blkno >= reln->smgr_cached_nblocks[FSM_FORKNUM]) { /* Invalidate the cache so smgrnblocks asks the kernel. */ - rel->rd_smgr->smgr_cached_nblocks[FSM_FORKNUM] = InvalidBlockNumber; - if (smgrexists(rel->rd_smgr, FSM_FORKNUM)) - smgrnblocks(rel->rd_smgr, FSM_FORKNUM); + reln->smgr_cached_nblocks[FSM_FORKNUM] = InvalidBlockNumber; + if (smgrexists(reln, FSM_FORKNUM)) + smgrnblocks(reln, FSM_FORKNUM); else - rel->rd_smgr->smgr_cached_nblocks[FSM_FORKNUM] = 0; + reln->smgr_cached_nblocks[FSM_FORKNUM] = 0; } /* Handle requests beyond EOF */ - if (blkno >= rel->rd_smgr->smgr_cached_nblocks[FSM_FORKNUM]) + if (blkno >= reln->smgr_cached_nblocks[FSM_FORKNUM]) { if (extend) fsm_extend(rel, blkno + 1); @@ -604,6 +601,7 @@ fsm_extend(Relation rel, BlockNumber fsm_nblocks) { BlockNumber fsm_nblocks_now; PGAlignedBlock pg; + SMgrRelation reln; PageInit((Page) pg.data, BLCKSZ, 0); @@ -620,27 +618,27 @@ fsm_extend(Relation rel, BlockNumber fsm_nblocks) LockRelationForExtension(rel, ExclusiveLock); /* Might have to re-open if a cache flush happened */ - RelationOpenSmgr(rel); + reln = RelationGetSmgr(rel); /* * Create the FSM file first if it doesn't exist. If * smgr_cached_nblocks[FSM_FORKNUM] is positive then it must exist, no * need for an smgrexists call. */ - if ((rel->rd_smgr->smgr_cached_nblocks[FSM_FORKNUM] == 0 || - rel->rd_smgr->smgr_cached_nblocks[FSM_FORKNUM] == InvalidBlockNumber) && - !smgrexists(rel->rd_smgr, FSM_FORKNUM)) - smgrcreate(rel->rd_smgr, FSM_FORKNUM, false); + if ((reln->smgr_cached_nblocks[FSM_FORKNUM] == 0 || + reln->smgr_cached_nblocks[FSM_FORKNUM] == InvalidBlockNumber) && + !smgrexists(reln, FSM_FORKNUM)) + smgrcreate(reln, FSM_FORKNUM, false); /* Invalidate cache so that smgrnblocks() asks the kernel. */ - rel->rd_smgr->smgr_cached_nblocks[FSM_FORKNUM] = InvalidBlockNumber; - fsm_nblocks_now = smgrnblocks(rel->rd_smgr, FSM_FORKNUM); + reln->smgr_cached_nblocks[FSM_FORKNUM] = InvalidBlockNumber; + fsm_nblocks_now = smgrnblocks(reln, FSM_FORKNUM); while (fsm_nblocks_now < fsm_nblocks) { PageSetChecksumInplace((Page) pg.data, fsm_nblocks_now); - smgrextend(rel->rd_smgr, FSM_FORKNUM, fsm_nblocks_now, + smgrextend(reln, FSM_FORKNUM, fsm_nblocks_now, pg.data, false); fsm_nblocks_now++; } diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index 34e25eb5978..2f2d1c8c720 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -24,6 +24,7 @@ #include "rewrite/prs2lock.h" #include "storage/block.h" #include "storage/relfilenode.h" +#include "storage/smgr.h" #include "utils/relcache.h" #include "utils/reltrigger.h" @@ -508,14 +509,17 @@ typedef struct ViewOptions ((relation)->rd_rel->relfilenode == InvalidOid)) /* - * RelationOpenSmgr - * Open the relation at the smgr level, if not already done. + * RelationGetSmgr + * Returns smgr file handle for a relation. Open the relation at the smgr + * level, if not already done. */ -#define RelationOpenSmgr(relation) \ - do { \ - if ((relation)->rd_smgr == NULL) \ - smgrsetowner(&((relation)->rd_smgr), smgropen((relation)->rd_node, (relation)->rd_backend)); \ - } while (0) +static inline struct SMgrRelationData * +RelationGetSmgr(Relation rel) +{ + if (unlikely(rel->rd_smgr == NULL)) + smgrsetowner(&(rel->rd_smgr), smgropen(rel->rd_node, rel->rd_backend)); + return rel->rd_smgr; +} /* * RelationCloseSmgr @@ -548,8 +552,7 @@ typedef struct ViewOptions */ #define RelationSetTargetBlock(relation, targblock) \ do { \ - RelationOpenSmgr(relation); \ - (relation)->rd_smgr->smgr_targblock = (targblock); \ + (RelationGetSmgr(relation))->smgr_targblock = (targblock); \ } while (0) /* -- 2.18.0