diff --git a/src/backend/storage/file/buffile.c b/src/backend/storage/file/buffile.c
index 35e8f12e62..0399f11607 100644
--- a/src/backend/storage/file/buffile.c
+++ b/src/backend/storage/file/buffile.c
@@ -100,7 +100,7 @@ static void extendBufFile(BufFile *file);
 static void BufFileLoadBuffer(BufFile *file);
 static void BufFileDumpBuffer(BufFile *file);
 static int	BufFileFlush(BufFile *file);
-static File MakeNewSharedSegment(BufFile *file, int segment);
+static File MakeNewSharedSegment(BufFile *file, int segment, bool eoxact_close);
 
 /*
  * Create BufFile and perform the common initialization.
@@ -156,7 +156,7 @@ extendBufFile(BufFile *file)
 	if (file->fileset == NULL)
 		pfile = OpenTemporaryFile(file->isInterXact);
 	else
-		pfile = MakeNewSharedSegment(file, file->numFiles);
+		pfile = MakeNewSharedSegment(file, file->numFiles, true);
 
 	Assert(pfile >= 0);
 
@@ -219,7 +219,7 @@ SharedSegmentName(char *name, const char *buffile_name, int segment)
  * Create a new segment file backing a shared BufFile.
  */
 static File
-MakeNewSharedSegment(BufFile *buffile, int segment)
+MakeNewSharedSegment(BufFile *buffile, int segment, bool eoxact_close)
 {
 	char		name[MAXPGPATH];
 	File		file;
@@ -235,7 +235,7 @@ MakeNewSharedSegment(BufFile *buffile, int segment)
 
 	/* Create the new segment. */
 	SharedSegmentName(name, buffile->name, segment);
-	file = SharedFileSetCreate(buffile->fileset, name);
+	file = SharedFileSetCreate(buffile->fileset, name, eoxact_close);
 
 	/* SharedFileSetCreate would've errored out */
 	Assert(file > 0);
@@ -255,7 +255,8 @@ MakeNewSharedSegment(BufFile *buffile, int segment)
  * unrelated SharedFileSet objects.
  */
 BufFile *
-BufFileCreateShared(SharedFileSet *fileset, const char *name)
+BufFileCreateShared(SharedFileSet *fileset, const char *name,
+					bool eoxact_close)
 {
 	BufFile    *file;
 
@@ -263,7 +264,7 @@ BufFileCreateShared(SharedFileSet *fileset, const char *name)
 	file->fileset = fileset;
 	file->name = pstrdup(name);
 	file->files = (File *) palloc(sizeof(File));
-	file->files[0] = MakeNewSharedSegment(file, 0);
+	file->files[0] = MakeNewSharedSegment(file, 0, eoxact_close);
 	file->readOnly = false;
 
 	return file;
@@ -277,7 +278,8 @@ BufFileCreateShared(SharedFileSet *fileset, const char *name)
  * backends and render it read-only.
  */
 BufFile *
-BufFileOpenShared(SharedFileSet *fileset, const char *name)
+BufFileOpenShared(SharedFileSet *fileset, const char *name, bool eoxact_close,
+				  bool read_only)
 {
 	BufFile    *file;
 	char		segment_name[MAXPGPATH];
@@ -301,7 +303,8 @@ BufFileOpenShared(SharedFileSet *fileset, const char *name)
 		}
 		/* Try to load a segment. */
 		SharedSegmentName(segment_name, name, nfiles);
-		files[nfiles] = SharedFileSetOpen(fileset, segment_name);
+		files[nfiles] = SharedFileSetOpen(fileset, segment_name, eoxact_close,
+										  read_only);
 		if (files[nfiles] <= 0)
 			break;
 		++nfiles;
@@ -321,7 +324,7 @@ BufFileOpenShared(SharedFileSet *fileset, const char *name)
 
 	file = makeBufFileCommon(nfiles);
 	file->files = files;
-	file->readOnly = true;		/* Can't write to files opened this way */
+	file->readOnly = read_only;		/* Can't write to files opened this way */
 	file->fileset = fileset;
 	file->name = pstrdup(name);
 
@@ -670,11 +673,14 @@ BufFileSeek(BufFile *file, int fileno, off_t offset, int whence)
 			newFile = file->curFile;
 			newOffset = (file->curOffset + file->pos) + offset;
 			break;
-#ifdef NOT_USED
 		case SEEK_END:
-			/* could be implemented, not needed currently */
+			/*
+			 * Get the file size of the last file to get the last offset
+			 * of that file.
+			 */
+			newFile = file->numFiles - 1;
+			newOffset = FileSize(file->files[file->numFiles - 1]);
 			break;
-#endif
 		default:
 			elog(ERROR, "invalid whence: %d", whence);
 			return EOF;
@@ -843,3 +849,40 @@ BufFileAppend(BufFile *target, BufFile *source)
 
 	return startBlock;
 }
+
+/*
+ * Truncate the file upto the given fileno and the offsets.
+ */
+void
+BufFileTruncateShared(BufFile *file, int fileno, off_t offset)
+{
+	int newFile = file->numFiles;
+	off_t newOffset;
+	char segment_name[MAXPGPATH];
+	int i;
+
+	/* Loop over all the  files upto the fileno which we want to truncate. */
+	for (i = file->numFiles - 1; i >= fileno; i--)
+	{
+		/*
+		 * Except the fileno,  we can directly delete other files.  If the
+		 * offset is 0 then we can delete the fileno file as well unless it
+		 * is the first file.
+		 */
+		if ((i != fileno || offset == 0) && fileno != 0)	
+		{
+			SharedSegmentName(segment_name, file->name, i);
+			SharedFileSetDelete(file->fileset, segment_name, true);
+			newFile--;
+			newOffset = MAX_PHYSICAL_FILESIZE;
+		}
+		else
+		{
+			FileTruncate(file->files[i], offset, WAIT_EVENT_BUFFILE_READ);
+			newOffset = offset;
+		}
+	}
+
+	file->numFiles = newFile;
+	file->curOffset = newOffset;
+}
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index 7dc6dd2f15..0fa98585f9 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -1403,13 +1403,14 @@ ReportTemporaryFileUsage(const char *path, off_t size)
  * before the file was opened.
  */
 static void
-RegisterTemporaryFile(File file)
+RegisterTemporaryFile(File file, bool eoxact_close)
 {
 	ResourceOwnerRememberFile(CurrentResourceOwner, file);
 	VfdCache[file].resowner = CurrentResourceOwner;
 
 	/* Backup mechanism for closing at end of xact. */
-	VfdCache[file].fdstate |= FD_CLOSE_AT_EOXACT;
+	if (eoxact_close)
+		VfdCache[file].fdstate |= FD_CLOSE_AT_EOXACT;
 	have_xact_temporary_files = true;
 }
 
@@ -1616,7 +1617,7 @@ OpenTemporaryFile(bool interXact)
 
 	/* Register it with the current resource owner */
 	if (!interXact)
-		RegisterTemporaryFile(file);
+		RegisterTemporaryFile(file, true);
 
 	return file;
 }
@@ -1707,7 +1708,8 @@ OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError)
  * the prefix isn't needed.
  */
 File
-PathNameCreateTemporaryFile(const char *path, bool error_on_failure)
+PathNameCreateTemporaryFile(const char *path, bool error_on_failure,
+							bool eoxact_close)
 {
 	File		file;
 
@@ -1733,7 +1735,7 @@ PathNameCreateTemporaryFile(const char *path, bool error_on_failure)
 	VfdCache[file].fdstate |= FD_TEMP_FILE_LIMIT;
 
 	/* Register it for automatic close. */
-	RegisterTemporaryFile(file);
+	RegisterTemporaryFile(file, eoxact_close);
 
 	return file;
 }
@@ -1741,18 +1743,22 @@ PathNameCreateTemporaryFile(const char *path, bool error_on_failure)
 /*
  * Open a file that was created with PathNameCreateTemporaryFile, possibly in
  * another backend.  Files opened this way don't count against the
- * temp_file_limit of the caller, are read-only and are automatically closed
- * at the end of the transaction but are not deleted on close.
+ * temp_file_limit of the caller, are read-only if the flag is set and are
+ * automatically closed at the end of the transaction if the eoxact_close is
+ * setbut are not deleted on close.
  */
 File
-PathNameOpenTemporaryFile(const char *path)
+PathNameOpenTemporaryFile(const char *path, bool eoxact_close, bool read_only)
 {
 	File		file;
 
 	ResourceOwnerEnlargeFiles(CurrentResourceOwner);
 
-	/* We open the file read-only. */
-	file = PathNameOpenFile(path, O_RDONLY | PG_BINARY);
+	/* We open the file read-only if instructed by the caller. */
+	if (read_only)
+		file = PathNameOpenFile(path, O_RDONLY | PG_BINARY);
+	else
+		file = PathNameOpenFile(path, O_RDWR | PG_BINARY);
 
 	/* If no such file, then we don't raise an error. */
 	if (file <= 0 && errno != ENOENT)
@@ -1764,7 +1770,7 @@ PathNameOpenTemporaryFile(const char *path)
 	if (file > 0)
 	{
 		/* Register it for automatic close. */
-		RegisterTemporaryFile(file);
+		RegisterTemporaryFile(file, eoxact_close);
 	}
 
 	return file;
diff --git a/src/backend/storage/file/sharedfileset.c b/src/backend/storage/file/sharedfileset.c
index f7206c9175..9b87bcad3d 100644
--- a/src/backend/storage/file/sharedfileset.c
+++ b/src/backend/storage/file/sharedfileset.c
@@ -68,7 +68,8 @@ SharedFileSetInit(SharedFileSet *fileset, dsm_segment *seg)
 	}
 
 	/* Register our cleanup callback. */
-	on_dsm_detach(seg, SharedFileSetOnDetach, PointerGetDatum(fileset));
+	if (seg)
+		on_dsm_detach(seg, SharedFileSetOnDetach, PointerGetDatum(fileset));
 }
 
 /*
@@ -102,13 +103,14 @@ SharedFileSetAttach(SharedFileSet *fileset, dsm_segment *seg)
  * Create a new file in the given set.
  */
 File
-SharedFileSetCreate(SharedFileSet *fileset, const char *name)
+SharedFileSetCreate(SharedFileSet *fileset, const char *name,
+					bool eoxact_close)
 {
 	char		path[MAXPGPATH];
 	File		file;
 
 	SharedFilePath(path, fileset, name);
-	file = PathNameCreateTemporaryFile(path, false);
+	file = PathNameCreateTemporaryFile(path, false, eoxact_close);
 
 	/* If we failed, see if we need to create the directory on demand. */
 	if (file <= 0)
@@ -120,7 +122,7 @@ SharedFileSetCreate(SharedFileSet *fileset, const char *name)
 		TempTablespacePath(tempdirpath, tablespace);
 		SharedFileSetPath(filesetpath, fileset, tablespace);
 		PathNameCreateTemporaryDir(tempdirpath, filesetpath);
-		file = PathNameCreateTemporaryFile(path, true);
+		file = PathNameCreateTemporaryFile(path, true, eoxact_close);
 	}
 
 	return file;
@@ -131,13 +133,14 @@ SharedFileSetCreate(SharedFileSet *fileset, const char *name)
  * another backend.
  */
 File
-SharedFileSetOpen(SharedFileSet *fileset, const char *name)
+SharedFileSetOpen(SharedFileSet *fileset, const char *name, bool eoxact_close,
+				  bool read_only)
 {
 	char		path[MAXPGPATH];
 	File		file;
 
 	SharedFilePath(path, fileset, name);
-	file = PathNameOpenTemporaryFile(path);
+	file = PathNameOpenTemporaryFile(path, eoxact_close, read_only);
 
 	return file;
 }
diff --git a/src/backend/utils/sort/logtape.c b/src/backend/utils/sort/logtape.c
index 666a7c0e81..212a607e63 100644
--- a/src/backend/utils/sort/logtape.c
+++ b/src/backend/utils/sort/logtape.c
@@ -544,7 +544,7 @@ ltsConcatWorkerTapes(LogicalTapeSet *lts, TapeShare *shared,
 		lt = &lts->tapes[i];
 
 		pg_itoa(i, filename);
-		file = BufFileOpenShared(fileset, filename);
+		file = BufFileOpenShared(fileset, filename, true, true);
 		filesize = BufFileSize(file);
 
 		/*
@@ -701,7 +701,7 @@ LogicalTapeSetCreate(int ntapes, TapeShare *shared, SharedFileSet *fileset,
 		char		filename[MAXPGPATH];
 
 		pg_itoa(worker, filename);
-		lts->pfile = BufFileCreateShared(fileset, filename);
+		lts->pfile = BufFileCreateShared(fileset, filename, true);
 	}
 	else
 		lts->pfile = BufFileCreateTemp(false);
diff --git a/src/backend/utils/sort/sharedtuplestore.c b/src/backend/utils/sort/sharedtuplestore.c
index c3ab494a45..6ea52cb5a5 100644
--- a/src/backend/utils/sort/sharedtuplestore.c
+++ b/src/backend/utils/sort/sharedtuplestore.c
@@ -315,7 +315,8 @@ sts_puttuple(SharedTuplestoreAccessor *accessor, void *meta_data,
 
 		/* Create one.  Only this backend will write into it. */
 		sts_filename(name, accessor, accessor->participant);
-		accessor->write_file = BufFileCreateShared(accessor->fileset, name);
+		accessor->write_file = BufFileCreateShared(accessor->fileset, name,
+												   true);
 
 		/* Set up the shared state for this backend's file. */
 		participant = &accessor->sts->participants[accessor->participant];
@@ -563,7 +564,7 @@ sts_parallel_scan_next(SharedTuplestoreAccessor *accessor, void *meta_data)
 
 				sts_filename(name, accessor, accessor->read_participant);
 				accessor->read_file =
-					BufFileOpenShared(accessor->fileset, name);
+					BufFileOpenShared(accessor->fileset, name, true, true);
 			}
 
 			/* Seek and load the chunk header. */
diff --git a/src/include/storage/buffile.h b/src/include/storage/buffile.h
index 60433f35b4..0f628dd2b8 100644
--- a/src/include/storage/buffile.h
+++ b/src/include/storage/buffile.h
@@ -46,9 +46,12 @@ extern int	BufFileSeekBlock(BufFile *file, long blknum);
 extern int64 BufFileSize(BufFile *file);
 extern long BufFileAppend(BufFile *target, BufFile *source);
 
-extern BufFile *BufFileCreateShared(SharedFileSet *fileset, const char *name);
+extern BufFile *BufFileCreateShared(SharedFileSet *fileset, const char *name,
+									bool eoxact_close);
 extern void BufFileExportShared(BufFile *file);
-extern BufFile *BufFileOpenShared(SharedFileSet *fileset, const char *name);
+extern BufFile *BufFileOpenShared(SharedFileSet *fileset, const char *name,
+								  bool eoxact_close, bool read_only);
 extern void BufFileDeleteShared(SharedFileSet *fileset, const char *name);
+extern void BufFileTruncateShared(BufFile *file, int fileno, off_t offset);
 
 #endif							/* BUFFILE_H */
diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h
index 8cd125d7df..8c4e684f51 100644
--- a/src/include/storage/fd.h
+++ b/src/include/storage/fd.h
@@ -93,8 +93,8 @@ extern int	FileGetRawFlags(File file);
 extern mode_t FileGetRawMode(File file);
 
 /* Operations used for sharing named temporary files */
-extern File PathNameCreateTemporaryFile(const char *name, bool error_on_failure);
-extern File PathNameOpenTemporaryFile(const char *name);
+extern File PathNameCreateTemporaryFile(const char *name, bool error_on_failure, bool eoxact_close);
+extern File PathNameOpenTemporaryFile(const char *path, bool eoxact_close, bool read_only);
 extern bool PathNameDeleteTemporaryFile(const char *name, bool error_on_failure);
 extern void PathNameCreateTemporaryDir(const char *base, const char *name);
 extern void PathNameDeleteTemporaryDir(const char *name);
diff --git a/src/include/storage/sharedfileset.h b/src/include/storage/sharedfileset.h
index 2d6cf077e5..c661efaaaa 100644
--- a/src/include/storage/sharedfileset.h
+++ b/src/include/storage/sharedfileset.h
@@ -36,8 +36,10 @@ typedef struct SharedFileSet
 
 extern void SharedFileSetInit(SharedFileSet *fileset, dsm_segment *seg);
 extern void SharedFileSetAttach(SharedFileSet *fileset, dsm_segment *seg);
-extern File SharedFileSetCreate(SharedFileSet *fileset, const char *name);
-extern File SharedFileSetOpen(SharedFileSet *fileset, const char *name);
+extern File SharedFileSetCreate(SharedFileSet *fileset, const char *name,
+								bool eoxact_close);
+extern File SharedFileSetOpen(SharedFileSet *fileset, const char *name,
+							  bool eoxact_close, bool read_only);
 extern bool SharedFileSetDelete(SharedFileSet *fileset, const char *name,
 								bool error_on_failure);
 extern void SharedFileSetDeleteAll(SharedFileSet *fileset);
