Skip to content

Commit 16994c0

Browse files
author
Thomas Munro
committed
Fixed after PG review
1 parent 0367277 commit 16994c0

File tree

3 files changed

+68
-11
lines changed

3 files changed

+68
-11
lines changed

src/backend/storage/file/buffile.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,7 @@ BufFileOpenTagged(const BufFileTag *tag)
316316
}
317317
/* Try to load a segment. */
318318
make_tagged_path(tempdirpath, tempfilepath, tag, nfiles);
319-
files[nfiles] = PathNameOpenFile(tempfilepath,
320-
O_RDWR | PG_BINARY, 0600);
319+
files[nfiles] = PathNameOpenTemporaryFile(tempfilepath);
321320
if (files[nfiles] < 0)
322321
{
323322
if (errno == ENOENT)

src/backend/storage/file/fd.c

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@
3939
* for a long time, like relation files. It is the caller's responsibility
4040
* to close them, there is no automatic mechanism in fd.c for that.
4141
*
42+
* PathNameCreateTemporaryFile and PathNameOpenTemporaryFile are used for
43+
* temporary files that may be shared between backends. A File created or
44+
* opened with these functions is not automatically deleted when the file is
45+
* closed, but it is automatically closed and end of transaction and counts
46+
* agains the temporary file limit of the backend that created it. Any File
47+
* created this way must be explicitly deleted with PathNameDelete. Automatic
48+
* file deletion is not provided because this interface is designed for use by
49+
* buffile.c and indirectly by sharedbuffile.c to implement temporary files
50+
* with shared ownership and cleanup.
51+
*
4252
* AllocateFile, AllocateDir, OpenPipeStream and OpenTransientFile are
4353
* wrappers around fopen(3), opendir(3), popen(3) and open(2), respectively.
4454
* They behave like the corresponding native functions, except that the handle
@@ -171,7 +181,7 @@ int max_safe_fds = 32; /* default if not changed */
171181

172182
/* these are the assigned bits in fdstate below: */
173183
#define FD_DELETE_AT_CLOSE (1 << 0) /* T = delete when closed */
174-
#define FD_DELETE_AT_EOXACT (1 << 1) /* T = delete at eoXact */
184+
#define FD_CLOSE_AT_EOXACT (1 << 1) /* T = close at eoXact */
175185
#define FD_TEMP_FILE_LIMIT (1 << 2) /* T = respect temp_file_limit */
176186

177187
typedef struct vfd
@@ -1383,7 +1393,7 @@ OpenTemporaryFile(bool interXact)
13831393
/* Register it with the current resource owner */
13841394
if (!interXact)
13851395
{
1386-
VfdCache[file].fdstate |= FD_DELETE_AT_EOXACT;
1396+
VfdCache[file].fdstate |= FD_CLOSE_AT_EOXACT;
13871397

13881398
ResourceOwnerEnlargeFiles(CurrentResourceOwner);
13891399
ResourceOwnerRememberFile(CurrentResourceOwner, file);
@@ -1437,9 +1447,9 @@ OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError)
14371447

14381448
/*
14391449
* Create a new file, and also the directory that contains it if necessary.
1440-
* Files created this way are subject to temp_file_limit, but are not
1441-
* automatically deleted on close or at end of transaction because they are
1442-
* intended to be shared between cooperating backends..
1450+
* Files created this way are subject to temp_file_limit and are automatically
1451+
* closed at end of transaction, but are not automatically deleted on close
1452+
* because they are intended to be shared between cooperating backends.
14431453
*/
14441454
File
14451455
PathNameCreateTemporaryFile(char *tempdirpath, char *tempfilepath,
@@ -1474,10 +1484,56 @@ PathNameCreateTemporaryFile(char *tempdirpath, char *tempfilepath,
14741484
tempfilepath);
14751485
}
14761486

1477-
if (file >= 0)
1487+
if (file > 0)
14781488
{
1479-
/* Mark it for temp_file_limit accounting */
1489+
/* Mark it for temp_file_limit accounting. */
14801490
VfdCache[file].fdstate |= FD_TEMP_FILE_LIMIT;
1491+
1492+
/*
1493+
* We don't set FD_DELETE_AT_CLOSE for files opened this way, but we
1494+
* still want to make sure they get closed at end of xact.
1495+
*/
1496+
ResourceOwnerEnlargeFiles(CurrentResourceOwner);
1497+
ResourceOwnerRememberFile(CurrentResourceOwner, file);
1498+
VfdCache[file].resowner = CurrentResourceOwner;
1499+
1500+
/* Backup mechanism for closing at end of xact. */
1501+
VfdCache[file].fdstate |= FD_CLOSE_AT_EOXACT;
1502+
have_xact_temporary_files = true;
1503+
}
1504+
1505+
return file;
1506+
}
1507+
1508+
/*
1509+
* Open a file that was created with PathNameCreateTemporaryFile in another
1510+
* backend. Files opened this way don't count agains the temp_file_limit of
1511+
* the caller, are read-only and are automatically closed at the end of the
1512+
* transaction but are not deleted on close.
1513+
*/
1514+
File
1515+
PathNameOpenTemporaryFile(char *tempfilepath)
1516+
{
1517+
File file;
1518+
1519+
/*
1520+
* Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1521+
* temp file that can be reused.
1522+
*/
1523+
file = PathNameOpenFile(tempfilepath, O_RDONLY | PG_BINARY, 0);
1524+
if (file > 0)
1525+
{
1526+
/*
1527+
* We don't set FD_DELETE_AT_CLOSE for files opened this way, but we
1528+
* still want to make sure they get closed at end of xact.
1529+
*/
1530+
ResourceOwnerEnlargeFiles(CurrentResourceOwner);
1531+
ResourceOwnerRememberFile(CurrentResourceOwner, file);
1532+
VfdCache[file].resowner = CurrentResourceOwner;
1533+
1534+
/* Backup mechanism for closing at end of xact. */
1535+
VfdCache[file].fdstate |= FD_CLOSE_AT_EOXACT;
1536+
have_xact_temporary_files = true;
14811537
}
14821538

14831539
return file;
@@ -2659,7 +2715,8 @@ CleanupTempFiles(bool isProcExit)
26592715
{
26602716
unsigned short fdstate = VfdCache[i].fdstate;
26612717

2662-
if ((fdstate & FD_DELETE_AT_CLOSE) && VfdCache[i].fileName != NULL)
2718+
if (((fdstate & FD_DELETE_AT_CLOSE) || (fdstate & FD_CLOSE_AT_EOXACT)) &&
2719+
VfdCache[i].fileName != NULL)
26632720
{
26642721
/*
26652722
* If we're in the process of exiting a backend process, close
@@ -2670,7 +2727,7 @@ CleanupTempFiles(bool isProcExit)
26702727
*/
26712728
if (isProcExit)
26722729
FileClose(i);
2673-
else if (fdstate & FD_DELETE_AT_EOXACT)
2730+
else if (fdstate & FD_CLOSE_AT_EOXACT)
26742731
{
26752732
elog(WARNING,
26762733
"temporary file %s not closed at end-of-transaction",

src/include/storage/fd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ extern int FileGetRawMode(File file);
8383
/* Operations used by buffile.c to support tagged files */
8484
extern File PathNameCreateTemporaryFile(FileName directory, FileName filename,
8585
bool error_on_failure);
86+
extern File PathNameOpenTemporaryFile(FileName filename);
8687
extern bool PathNameDelete(FileName fileName, bool error_on_failure);
8788

8889
/* Operations that allow use of regular stdio --- USE WITH CAUTION */

0 commit comments

Comments
 (0)