aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/dbcommands.c
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2022-08-12 08:25:41 -0400
committerRobert Haas <rhaas@postgresql.org>2022-08-12 08:25:41 -0400
commit76733b399c490885564a560718de23d98bb5e66d (patch)
tree45f1fcf1650e4b4b02af7b0d062f10d2232d4eef /src/backend/commands/dbcommands.c
parent3d895bc846f25859bd6dd242fbf204e6c5166e6f (diff)
downloadpostgresql-76733b399c490885564a560718de23d98bb5e66d.tar.gz
postgresql-76733b399c490885564a560718de23d98bb5e66d.zip
Avoid using a fake relcache entry to own an SmgrRelation.
If an error occurs before we close the fake relcache entry, the the fake relcache entry will be destroyed by the SmgrRelation will survive until end of transaction. Its smgr_owner pointer ends up pointing to already-freed memory. The original reason for using a fake relcache entry here was to try to avoid reusing an SMgrRelation across a relevant invalidation. To avoid that problem, just call smgropen() again each time we need a reference to it. Hopefully someday we will come up with a more elegant approach, but accessing uninitialized memory is bad so let's do this for now. Dilip Kumar, reviewed by Andres Freund and Tom Lane. Report by Justin Pryzby. Discussion: http://postgr.es/m/20220802175043.GA13682@telsasoft.com Discussion: http://postgr.es/m/CAFiTN-vSFeE6_W9z698XNtFROOA_nSqUXWqLcG0emob_kJ+dEQ@mail.gmail.com
Diffstat (limited to 'src/backend/commands/dbcommands.c')
-rw-r--r--src/backend/commands/dbcommands.c15
1 files changed, 4 insertions, 11 deletions
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 9f990a8d68f..b31a30550b0 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -258,8 +258,8 @@ ScanSourceDatabasePgClass(Oid tbid, Oid dbid, char *srcpath)
Page page;
List *rlocatorlist = NIL;
LockRelId relid;
- Relation rel;
Snapshot snapshot;
+ SMgrRelation smgr;
BufferAccessStrategy bstrategy;
/* Get pg_class relfilenumber. */
@@ -276,16 +276,9 @@ ScanSourceDatabasePgClass(Oid tbid, Oid dbid, char *srcpath)
rlocator.dbOid = dbid;
rlocator.relNumber = relfilenumber;
- /*
- * We can't use a real relcache entry for a relation in some other
- * database, but since we're only going to access the fields related to
- * physical storage, a fake one is good enough. If we didn't do this and
- * used the smgr layer directly, we would have to worry about
- * invalidations.
- */
- rel = CreateFakeRelcacheEntry(rlocator);
- nblocks = smgrnblocks(RelationGetSmgr(rel), MAIN_FORKNUM);
- FreeFakeRelcacheEntry(rel);
+ smgr = smgropen(rlocator, InvalidBackendId);
+ nblocks = smgrnblocks(smgr, MAIN_FORKNUM);
+ smgrclose(smgr);
/* Use a buffer access strategy since this is a bulk read operation. */
bstrategy = GetAccessStrategy(BAS_BULKREAD);