@@ -455,13 +455,11 @@ visibilitymap_prepare_truncate(Relation rel, BlockNumber nheapblocks)
455455 elog (DEBUG1 , "vm_truncate %s %d" , RelationGetRelationName (rel ), nheapblocks );
456456#endif
457457
458- RelationOpenSmgr (rel );
459-
460458 /*
461459 * If no visibility map has been created yet for this relation, there's
462460 * nothing to truncate.
463461 */
464- if (!smgrexists (rel -> rd_smgr , VISIBILITYMAP_FORKNUM ))
462+ if (!smgrexists (RelationGetSmgr ( rel ) , VISIBILITYMAP_FORKNUM ))
465463 return InvalidBlockNumber ;
466464
467465 /*
@@ -528,7 +526,7 @@ visibilitymap_prepare_truncate(Relation rel, BlockNumber nheapblocks)
528526 else
529527 newnblocks = truncBlock ;
530528
531- if (smgrnblocks (rel -> rd_smgr , VISIBILITYMAP_FORKNUM ) <= newnblocks )
529+ if (smgrnblocks (RelationGetSmgr ( rel ) , VISIBILITYMAP_FORKNUM ) <= newnblocks )
532530 {
533531 /* nothing to do, the file was already smaller than requested size */
534532 return InvalidBlockNumber ;
@@ -547,30 +545,29 @@ static Buffer
547545vm_readbuf (Relation rel , BlockNumber blkno , bool extend )
548546{
549547 Buffer buf ;
548+ SMgrRelation reln ;
550549
551550 /*
552- * We might not have opened the relation at the smgr level yet, or we
553- * might have been forced to close it by a sinval message. The code below
554- * won't necessarily notice relation extension immediately when extend =
555- * false, so we rely on sinval messages to ensure that our ideas about the
556- * size of the map aren't too far out of date.
551+ * Caution: re-using this smgr pointer could fail if the relcache entry
552+ * gets closed. It's safe as long as we only do smgr-level operations
553+ * between here and the last use of the pointer.
557554 */
558- RelationOpenSmgr (rel );
555+ reln = RelationGetSmgr (rel );
559556
560557 /*
561558 * If we haven't cached the size of the visibility map fork yet, check it
562559 * first.
563560 */
564- if (rel -> rd_smgr -> smgr_cached_nblocks [VISIBILITYMAP_FORKNUM ] == InvalidBlockNumber )
561+ if (reln -> smgr_cached_nblocks [VISIBILITYMAP_FORKNUM ] == InvalidBlockNumber )
565562 {
566- if (smgrexists (rel -> rd_smgr , VISIBILITYMAP_FORKNUM ))
567- smgrnblocks (rel -> rd_smgr , VISIBILITYMAP_FORKNUM );
563+ if (smgrexists (reln , VISIBILITYMAP_FORKNUM ))
564+ smgrnblocks (reln , VISIBILITYMAP_FORKNUM );
568565 else
569- rel -> rd_smgr -> smgr_cached_nblocks [VISIBILITYMAP_FORKNUM ] = 0 ;
566+ reln -> smgr_cached_nblocks [VISIBILITYMAP_FORKNUM ] = 0 ;
570567 }
571568
572569 /* Handle requests beyond EOF */
573- if (blkno >= rel -> rd_smgr -> smgr_cached_nblocks [VISIBILITYMAP_FORKNUM ])
570+ if (blkno >= reln -> smgr_cached_nblocks [VISIBILITYMAP_FORKNUM ])
574571 {
575572 if (extend )
576573 vm_extend (rel , blkno + 1 );
@@ -618,6 +615,7 @@ vm_extend(Relation rel, BlockNumber vm_nblocks)
618615{
619616 BlockNumber vm_nblocks_now ;
620617 PGAlignedBlock pg ;
618+ SMgrRelation reln ;
621619
622620 PageInit ((Page ) pg .data , BLCKSZ , 0 );
623621
@@ -633,29 +631,32 @@ vm_extend(Relation rel, BlockNumber vm_nblocks)
633631 */
634632 LockRelationForExtension (rel , ExclusiveLock );
635633
636- /* Might have to re-open if a cache flush happened */
637- RelationOpenSmgr (rel );
634+ /*
635+ * Caution: re-using this smgr pointer could fail if the relcache entry
636+ * gets closed. It's safe as long as we only do smgr-level operations
637+ * between here and the last use of the pointer.
638+ */
639+ reln = RelationGetSmgr (rel );
638640
639641 /*
640642 * Create the file first if it doesn't exist. If smgr_vm_nblocks is
641643 * positive then it must exist, no need for an smgrexists call.
642644 */
643- if ((rel -> rd_smgr -> smgr_cached_nblocks [VISIBILITYMAP_FORKNUM ] == 0 ||
644- rel -> rd_smgr -> smgr_cached_nblocks [VISIBILITYMAP_FORKNUM ] == InvalidBlockNumber ) &&
645- !smgrexists (rel -> rd_smgr , VISIBILITYMAP_FORKNUM ))
646- smgrcreate (rel -> rd_smgr , VISIBILITYMAP_FORKNUM , false);
645+ if ((reln -> smgr_cached_nblocks [VISIBILITYMAP_FORKNUM ] == 0 ||
646+ reln -> smgr_cached_nblocks [VISIBILITYMAP_FORKNUM ] == InvalidBlockNumber ) &&
647+ !smgrexists (reln , VISIBILITYMAP_FORKNUM ))
648+ smgrcreate (reln , VISIBILITYMAP_FORKNUM , false);
647649
648650 /* Invalidate cache so that smgrnblocks() asks the kernel. */
649- rel -> rd_smgr -> smgr_cached_nblocks [VISIBILITYMAP_FORKNUM ] = InvalidBlockNumber ;
650- vm_nblocks_now = smgrnblocks (rel -> rd_smgr , VISIBILITYMAP_FORKNUM );
651+ reln -> smgr_cached_nblocks [VISIBILITYMAP_FORKNUM ] = InvalidBlockNumber ;
652+ vm_nblocks_now = smgrnblocks (reln , VISIBILITYMAP_FORKNUM );
651653
652654 /* Now extend the file */
653655 while (vm_nblocks_now < vm_nblocks )
654656 {
655657 PageSetChecksumInplace ((Page ) pg .data , vm_nblocks_now );
656658
657- smgrextend (rel -> rd_smgr , VISIBILITYMAP_FORKNUM , vm_nblocks_now ,
658- pg .data , false);
659+ smgrextend (reln , VISIBILITYMAP_FORKNUM , vm_nblocks_now , pg .data , false);
659660 vm_nblocks_now ++ ;
660661 }
661662
@@ -666,7 +667,7 @@ vm_extend(Relation rel, BlockNumber vm_nblocks)
666667 * to keep checking for creation or extension of the file, which happens
667668 * infrequently.
668669 */
669- CacheInvalidateSmgr (rel -> rd_smgr -> smgr_rnode );
670+ CacheInvalidateSmgr (reln -> smgr_rnode );
670671
671672 UnlockRelationForExtension (rel , ExclusiveLock );
672673}
0 commit comments