diff --git a/src/backend/access/transam/xlogutils.c b/src/backend/access/transam/xlogutils.c
index f1918f6b078e224d81a1bbb327b2c2b995c1a935..05e74de92119fadbaad275ecaac40981d79ed971 100644
--- a/src/backend/access/transam/xlogutils.c
+++ b/src/backend/access/transam/xlogutils.c
@@ -445,6 +445,9 @@ CreateFakeRelcacheEntry(RelFileNode rnode)
 void
 FreeFakeRelcacheEntry(Relation fakerel)
 {
+	/* make sure the fakerel is not referenced by the SmgrRelation anymore */
+	if (fakerel->rd_smgr != NULL)
+		smgrclearowner(&fakerel->rd_smgr, fakerel->rd_smgr);
 	pfree(fakerel);
 }
 
diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c
index 37be3081803c69bc20ae9a9818c51dd2416dd0fd..fcbdc4117a56692e81f18cc7c3c5c2ac842d33f5 100644
--- a/src/backend/storage/smgr/smgr.c
+++ b/src/backend/storage/smgr/smgr.c
@@ -84,6 +84,7 @@ static SMgrRelation first_unowned_reln = NULL;
 
 /* local function prototypes */
 static void smgrshutdown(int code, Datum arg);
+static void add_to_unowned_list(SMgrRelation reln);
 static void remove_from_unowned_list(SMgrRelation reln);
 
 
@@ -174,9 +175,8 @@ smgropen(RelFileNode rnode, BackendId backend)
 		for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
 			reln->md_fd[forknum] = NULL;
 
-		/* place it at head of unowned list (to make smgrsetowner cheap) */
-		reln->next_unowned_reln = first_unowned_reln;
-		first_unowned_reln = reln;
+		/* it has no owner yet */
+		add_to_unowned_list(reln);
 	}
 
 	return reln;
@@ -191,7 +191,7 @@ smgropen(RelFileNode rnode, BackendId backend)
 void
 smgrsetowner(SMgrRelation *owner, SMgrRelation reln)
 {
-	/* We don't currently support "disowning" an SMgrRelation here */
+	/* We don't support "disowning" an SMgrRelation here, use smgrclearowner */
 	Assert(owner != NULL);
 
 	/*
@@ -213,6 +213,40 @@ smgrsetowner(SMgrRelation *owner, SMgrRelation reln)
 	*owner = reln;
 }
 
+/*
+ * smgrclearowner() -- Remove long-lived reference to an SMgrRelation object
+ *					   if one exists
+ */
+void
+smgrclearowner(SMgrRelation *owner, SMgrRelation reln)
+{
+	/* Do nothing if the SMgrRelation object is not owned by the owner */
+	if (reln->smgr_owner != owner)
+		return;
+
+	/* unset the owner's reference */
+	*owner = NULL;
+
+	/* unset our reference to the owner */
+	reln->smgr_owner = NULL;
+
+	add_to_unowned_list(reln);
+}
+
+/*
+ * add_to_unowned_list -- link an SMgrRelation onto the unowned list
+ *
+ * Check remove_from_unowned_list()'s comments for performance
+ * considerations.
+ */
+static void
+add_to_unowned_list(SMgrRelation reln)
+{
+	/* place it at head of the list (to make smgrsetowner cheap) */
+	reln->next_unowned_reln = first_unowned_reln;
+	first_unowned_reln = reln;
+}
+
 /*
  * remove_from_unowned_list -- unlink an SMgrRelation from the unowned list
  *
diff --git a/src/include/storage/smgr.h b/src/include/storage/smgr.h
index 8f523a61288fd35b80eccbc53b2e32feaec0ef2f..c7ab235ba42bfd22dead49409a83076ca8ad7f63 100644
--- a/src/include/storage/smgr.h
+++ b/src/include/storage/smgr.h
@@ -80,6 +80,7 @@ extern void smgrinit(void);
 extern SMgrRelation smgropen(RelFileNode rnode, BackendId backend);
 extern bool smgrexists(SMgrRelation reln, ForkNumber forknum);
 extern void smgrsetowner(SMgrRelation *owner, SMgrRelation reln);
+extern void smgrclearowner(SMgrRelation *owner, SMgrRelation reln);
 extern void smgrclose(SMgrRelation reln);
 extern void smgrcloseall(void);
 extern void smgrclosenode(RelFileNodeBackend rnode);