Skip to content

Commit

Permalink
Use RelationGetSmgr instead of rd_smgr
Browse files Browse the repository at this point in the history
rd_smgr should not be accessed directly but RelationGetSmgr should
be used instead. Accessing it directly can lead to segfaults when
parallel relcache flushes are happening.

postgres/postgres@f10f0ae
  • Loading branch information
svenklemm committed Nov 28, 2022
1 parent 2d0087a commit 52b0fbe
Showing 1 changed file with 26 additions and 1 deletion.
27 changes: 26 additions & 1 deletion src/copy.c
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,31 @@ has_other_before_insert_row_trigger_than_ts(ResultRelInfo *resultRelInfo)
return false;
}

#if PG13_GE
/*
* RelationGetSmgr
* Returns smgr file handle for a relation, opening it if needed.
*
* Very little code is authorized to touch rel->rd_smgr directly. Instead
* use this function to fetch its value.
*
* Note: since a relcache flush can cause the file handle to be closed again,
* it's unwise to hold onto the pointer returned by this function for any
* long period. Recommended practice is to just re-execute RelationGetSmgr
* each time you need to access the SMgrRelation. It's quite cheap in
* comparison to whatever an smgr function is going to do.
*
* copied verbatim from postgres because it is a static function
*/
static inline SMgrRelation
RelationGetSmgr(Relation rel)
{
if (unlikely(rel->rd_smgr == NULL))
smgrsetowner(&(rel->rd_smgr), smgropen(rel->rd_node, rel->rd_backend));
return rel->rd_smgr;
}
#endif

/*
* Use COPY FROM to copy data from file to relation.
*/
Expand Down Expand Up @@ -1237,7 +1262,7 @@ copyfrom(CopyChunkState *ccstate, List *range_table, Hypertable *ht, MemoryConte
heap_sync(ccstate->rel);
#else
if (!RelationNeedsWAL(ccstate->rel))
smgrimmedsync(ccstate->rel->rd_smgr, MAIN_FORKNUM);
smgrimmedsync(RelationGetSmgr(ccstate->rel), MAIN_FORKNUM);
#endif

return processed;
Expand Down

0 comments on commit 52b0fbe

Please sign in to comment.