diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 56095b32501efef651b0e650c5938de9b16d46f9..bdcbe47ac9e9f5ce0db5f90b8ddb567bf34ade00 100644
*** a/src/backend/storage/buffer/bufmgr.c
--- b/src/backend/storage/buffer/bufmgr.c
*************** BufferGetTag(Buffer buffer, RelFileNode 
*** 1882,1891 ****
   * written.)
   *
   * If the caller has an smgr reference for the buffer's relation, pass it
!  * as the second parameter.  If not, pass NULL.  In the latter case, the
!  * relation will be marked as "transient" so that the corresponding
!  * kernel-level file descriptors are closed when the current transaction ends,
!  * if any.
   */
  static void
  FlushBuffer(volatile BufferDesc *buf, SMgrRelation reln)
--- 1882,1888 ----
   * written.)
   *
   * If the caller has an smgr reference for the buffer's relation, pass it
!  * as the second parameter.  If not, pass NULL.
   */
  static void
  FlushBuffer(volatile BufferDesc *buf, SMgrRelation reln)
*************** FlushBuffer(volatile BufferDesc *buf, SM
*** 1909,1920 ****
  	errcontext.previous = error_context_stack;
  	error_context_stack = &errcontext;
  
! 	/* Find smgr relation for buffer, and mark it as transient */
  	if (reln == NULL)
- 	{
  		reln = smgropen(buf->tag.rnode, InvalidBackendId);
- 		smgrsettransient(reln);
- 	}
  
  	TRACE_POSTGRESQL_BUFFER_FLUSH_START(buf->tag.forkNum,
  										buf->tag.blockNum,
--- 1906,1914 ----
  	errcontext.previous = error_context_stack;
  	error_context_stack = &errcontext;
  
! 	/* Find smgr relation for buffer */
  	if (reln == NULL)
  		reln = smgropen(buf->tag.rnode, InvalidBackendId);
  
  	TRACE_POSTGRESQL_BUFFER_FLUSH_START(buf->tag.forkNum,
  										buf->tag.blockNum,
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index fed25fd7e7cdda9aaa2c5b646f2e40cf50f000ed..ecb62ba01aeb968aedab3260d95ce07a44aa61fb 100644
*** a/src/backend/storage/file/fd.c
--- b/src/backend/storage/file/fd.c
*************** int			max_safe_fds = 32;	/* default if n
*** 126,133 ****
  /* these are the assigned bits in fdstate below: */
  #define FD_TEMPORARY		(1 << 0)	/* T = delete when closed */
  #define FD_XACT_TEMPORARY	(1 << 1)	/* T = delete at eoXact */
- #define FD_XACT_TRANSIENT	(1 << 2)	/* T = close (not delete) at aoXact,
- 										 * but keep VFD */
  
  typedef struct vfd
  {
--- 126,131 ----
*************** static Size SizeVfdCache = 0;
*** 158,165 ****
   */
  static int	nfile = 0;
  
! /* True if there are files to close/delete at end of transaction */
! static bool have_pending_fd_cleanup = false;
  
  /*
   * Tracks the total size of all temporary files.  Note: when temp_file_limit
--- 156,166 ----
   */
  static int	nfile = 0;
  
! /*
!  * Flag to tell whether it's worth scanning VfdCache looking for temp files
!  * to close
!  */
! static bool have_xact_temporary_files = false;
  
  /*
   * Tracks the total size of all temporary files.  Note: when temp_file_limit
*************** LruDelete(File file)
*** 607,613 ****
  	Vfd		   *vfdP;
  
  	Assert(file != 0);
- 	Assert(!FileIsNotOpen(file));
  
  	DO_DB(elog(LOG, "LruDelete %d (%s)",
  			   file, VfdCache[file].fileName));
--- 608,613 ----
*************** OpenTemporaryFile(bool interXact)
*** 971,977 ****
  		VfdCache[file].resowner = CurrentResourceOwner;
  
  		/* ensure cleanup happens at eoxact */
! 		have_pending_fd_cleanup = true;
  	}
  
  	return file;
--- 971,977 ----
  		VfdCache[file].resowner = CurrentResourceOwner;
  
  		/* ensure cleanup happens at eoxact */
! 		have_xact_temporary_files = true;
  	}
  
  	return file;
*************** OpenTemporaryFileInTablespace(Oid tblspc
*** 1045,1069 ****
  }
  
  /*
-  * Set the transient flag on a file
-  *
-  * This flag tells CleanupTempFiles to close the kernel-level file descriptor
-  * (but not the VFD itself) at end of transaction.
-  */
- void
- FileSetTransient(File file)
- {
- 	Vfd		   *vfdP;
- 
- 	Assert(FileIsValid(file));
- 
- 	vfdP = &VfdCache[file];
- 	vfdP->fdstate |= FD_XACT_TRANSIENT;
- 
- 	have_pending_fd_cleanup = true;
- }
- 
- /*
   * close a file when done with it
   */
  void
--- 1045,1050 ----
*************** AtEOSubXact_Files(bool isCommit, SubTran
*** 1863,1871 ****
   * particularly care which).  All still-open per-transaction temporary file
   * VFDs are closed, which also causes the underlying files to be deleted
   * (although they should've been closed already by the ResourceOwner
!  * cleanup). Transient files have their kernel file descriptors closed.
!  * Furthermore, all "allocated" stdio files are closed. We also forget any
!  * transaction-local temp tablespace list.
   */
  void
  AtEOXact_Files(void)
--- 1844,1851 ----
   * particularly care which).  All still-open per-transaction temporary file
   * VFDs are closed, which also causes the underlying files to be deleted
   * (although they should've been closed already by the ResourceOwner
!  * cleanup). Furthermore, all "allocated" stdio files are closed. We also
!  * forget any transaction-local temp tablespace list.
   */
  void
  AtEOXact_Files(void)
*************** AtProcExit_Files(int code, Datum arg)
*** 1888,1897 ****
  }
  
  /*
!  * General cleanup routine for fd.c.
!  *
!  * Temporary files are closed, and their underlying files deleted.
!  * Transient files are closed.
   *
   * isProcExit: if true, this is being called as the backend process is
   * exiting. If that's the case, we should remove all temporary files; if
--- 1868,1874 ----
  }
  
  /*
!  * Close temporary files and delete their underlying files.
   *
   * isProcExit: if true, this is being called as the backend process is
   * exiting. If that's the case, we should remove all temporary files; if
*************** CleanupTempFiles(bool isProcExit)
*** 1908,1958 ****
  	 * Careful here: at proc_exit we need extra cleanup, not just
  	 * xact_temporary files.
  	 */
! 	if (isProcExit || have_pending_fd_cleanup)
  	{
  		Assert(FileIsNotOpen(0));		/* Make sure ring not corrupted */
  		for (i = 1; i < SizeVfdCache; i++)
  		{
  			unsigned short fdstate = VfdCache[i].fdstate;
  
! 			if (VfdCache[i].fileName != NULL)
  			{
! 				if (fdstate & FD_TEMPORARY)
! 				{
! 					/*
! 					 * If we're in the process of exiting a backend process,
! 					 * close all temporary files. Otherwise, only close
! 					 * temporary files local to the current transaction. They
! 					 * should be closed by the ResourceOwner mechanism
! 					 * already, so this is just a debugging cross-check.
! 					 */
! 					if (isProcExit)
! 						FileClose(i);
! 					else if (fdstate & FD_XACT_TEMPORARY)
! 					{
! 						elog(WARNING,
! 						"temporary file %s not closed at end-of-transaction",
! 							 VfdCache[i].fileName);
! 						FileClose(i);
! 					}
! 				}
! 				else if (fdstate & FD_XACT_TRANSIENT)
  				{
! 					/*
! 					 * Close the FD, and remove the entry from the LRU ring,
! 					 * but also remove the flag from the VFD.  This is to
! 					 * ensure that if the VFD is reused in the future for
! 					 * non-transient access, we don't close it inappropriately
! 					 * then.
! 					 */
! 					if (!FileIsNotOpen(i))
! 						LruDelete(i);
! 					VfdCache[i].fdstate &= ~FD_XACT_TRANSIENT;
  				}
  			}
  		}
  
! 		have_pending_fd_cleanup = false;
  	}
  
  	/* Clean up "allocated" stdio files and dirs. */
--- 1885,1919 ----
  	 * Careful here: at proc_exit we need extra cleanup, not just
  	 * xact_temporary files.
  	 */
! 	if (isProcExit || have_xact_temporary_files)
  	{
  		Assert(FileIsNotOpen(0));		/* Make sure ring not corrupted */
  		for (i = 1; i < SizeVfdCache; i++)
  		{
  			unsigned short fdstate = VfdCache[i].fdstate;
  
! 			if ((fdstate & FD_TEMPORARY) && VfdCache[i].fileName != NULL)
  			{
! 				/*
! 				 * If we're in the process of exiting a backend process, close
! 				 * all temporary files. Otherwise, only close temporary files
! 				 * local to the current transaction. They should be closed by
! 				 * the ResourceOwner mechanism already, so this is just a
! 				 * debugging cross-check.
! 				 */
! 				if (isProcExit)
! 					FileClose(i);
! 				else if (fdstate & FD_XACT_TEMPORARY)
  				{
! 					elog(WARNING,
! 						 "temporary file %s not closed at end-of-transaction",
! 						 VfdCache[i].fileName);
! 					FileClose(i);
  				}
  			}
  		}
  
! 		have_xact_temporary_files = false;
  	}
  
  	/* Clean up "allocated" stdio files and dirs. */
diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c
index 97742b92bb4ffa33db3554658511911955f47550..3f4ab49dab4a5a8d92c9673120f2d4964c29fdac 100644
*** a/src/backend/storage/smgr/md.c
--- b/src/backend/storage/smgr/md.c
*************** mdcreate(SMgrRelation reln, ForkNumber f
*** 300,308 ****
  
  	pfree(path);
  
- 	if (reln->smgr_transient)
- 		FileSetTransient(fd);
- 
  	reln->md_fd[forkNum] = _fdvec_alloc();
  
  	reln->md_fd[forkNum]->mdfd_vfd = fd;
--- 300,305 ----
*************** mdopen(SMgrRelation reln, ForkNumber for
*** 585,593 ****
  
  	pfree(path);
  
- 	if (reln->smgr_transient)
- 		FileSetTransient(fd);
- 
  	reln->md_fd[forknum] = mdfd = _fdvec_alloc();
  
  	mdfd->mdfd_vfd = fd;
--- 582,587 ----
*************** _mdfd_openseg(SMgrRelation reln, ForkNum
*** 1680,1688 ****
  	if (fd < 0)
  		return NULL;
  
- 	if (reln->smgr_transient)
- 		FileSetTransient(fd);
- 
  	/* allocate an mdfdvec entry for it */
  	v = _fdvec_alloc();
  
--- 1674,1679 ----
diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c
index 0cec1477f3faf6551ad141b5107da1ea70b8b54b..6319d1e8589138be32e498e77cc4ce484211c1a1 100644
*** a/src/backend/storage/smgr/smgr.c
--- b/src/backend/storage/smgr/smgr.c
*************** smgropen(RelFileNode rnode, BackendId ba
*** 163,196 ****
  		reln->smgr_targblock = InvalidBlockNumber;
  		reln->smgr_fsm_nblocks = InvalidBlockNumber;
  		reln->smgr_vm_nblocks = InvalidBlockNumber;
- 		reln->smgr_transient = false;
  		reln->smgr_which = 0;	/* we only have md.c at present */
  
  		/* mark it not open */
  		for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
  			reln->md_fd[forknum] = NULL;
  	}
- 	else
- 		/* if it was transient before, it no longer is */
- 		reln->smgr_transient = false;
  
  	return reln;
  }
  
  /*
-  * smgrsettransient() -- mark an SMgrRelation object as transaction-bound
-  *
-  * The main effect of this is that all opened files are marked to be
-  * kernel-level closed (but not necessarily VFD-closed) when the current
-  * transaction ends.
-  */
- void
- smgrsettransient(SMgrRelation reln)
- {
- 	reln->smgr_transient = true;
- }
- 
- /*
   * smgrsetowner() -- Establish a long-lived reference to an SMgrRelation object
   *
   * There can be only one owner at a time; this is sufficient since currently
--- 163,179 ----
diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h
index bad9f10c62ec84351bf191eecde7ad99d433d867..849bb1025d9d483916784378e7beb8370e647e51 100644
*** a/src/include/storage/fd.h
--- b/src/include/storage/fd.h
*************** extern int	max_safe_fds;
*** 66,72 ****
  /* Operations on virtual Files --- equivalent to Unix kernel file ops */
  extern File PathNameOpenFile(FileName fileName, int fileFlags, int fileMode);
  extern File OpenTemporaryFile(bool interXact);
- extern void FileSetTransient(File file);
  extern void FileClose(File file);
  extern int	FilePrefetch(File file, off_t offset, int amount);
  extern int	FileRead(File file, char *buffer, int amount);
--- 66,71 ----
diff --git a/src/include/storage/smgr.h b/src/include/storage/smgr.h
index 3560d539076da83a3f2897f3109fcabc4b72d5d0..92b9198d5428c1f51617f595d062da1bc8af5106 100644
*** a/src/include/storage/smgr.h
--- b/src/include/storage/smgr.h
*************** typedef struct SMgrRelationData
*** 60,66 ****
  	 * submodules.	Do not touch them from elsewhere.
  	 */
  	int			smgr_which;		/* storage manager selector */
- 	bool		smgr_transient; /* T if files are to be closed at EOXact */
  
  	/* for md.c; NULL for forks that are not open */
  	struct _MdfdVec *md_fd[MAX_FORKNUM + 1];
--- 60,65 ----
*************** typedef SMgrRelationData *SMgrRelation;
*** 73,79 ****
  
  extern void smgrinit(void);
  extern SMgrRelation smgropen(RelFileNode rnode, BackendId backend);
- extern void smgrsettransient(SMgrRelation reln);
  extern bool smgrexists(SMgrRelation reln, ForkNumber forknum);
  extern void smgrsetowner(SMgrRelation *owner, SMgrRelation reln);
  extern void smgrclose(SMgrRelation reln);
--- 72,77 ----
