8000 Back-patch fix that allows AllocateFile() to return errno=ENFILE/EMFILE · lhcezar/postgres@de3e018 · GitHub
[go: up one dir, main page]

Skip to content

Commit de3e018

Browse files
committed
Back-patch fix that allows AllocateFile() to return errno=ENFILE/EMFILE
after we are no longer able to close any more VFDs. This is needed to avoid postmaster crash under out-of-file-descriptors conditions.
1 parent c954088 commit de3e018

File tree

1 file changed

+37
-20
lines changed
  • src/backend/storage/file

1 file changed

+37
-20
lines changed

src/backend/storage/file/fd.c

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.56 2000/04/12 17:15:35 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.56.2.1 2000/09/23 23:31:24 tgl Exp $
1111
*
1212
* NOTES:
1313
*
@@ -181,7 +181,7 @@ static void Delete(File file);
181181
static void LruDelete(File file);
182182
static void Insert(File file);
183183
static int LruInsert(File file);
184-
static void ReleaseLruFile(void);
184+
static bool ReleaseLruFile(void);
185185
static File AllocateVfd(void);
186186
static void FreeVfd(File file);
187187

@@ -347,7 +347,10 @@ LruInsert(File file)
347347
{
348348

349349
while (nfile + numAllocatedFiles >= pg_nofile())
350-
ReleaseLruFile();
350+
{
351+
if (! ReleaseLruFile())
352+
break;
353+
}
351354

352355
/*
353356
* The open could still fail for lack of file descriptors, eg due
@@ -358,9 +361,12 @@ LruInsert(File file)
358361
vfdP->fd = open(vfdP->fileName, vfdP->fileFlags, vfdP->fileMode);
359362
if (vfdP->fd < 0 && (errno == EMFILE || errno == ENFILE))
360363
{
364+
int save_errno = errno;
365+
361366
errno = 0;
362-
ReleaseLruFile();
363-
goto tryAgain;
367+
if (ReleaseLruFile())
368+
goto tryAgain;
369+
errno = save_errno;
364370
}
365371

366372
if (vfdP->fd < 0)
@@ -392,20 +398,22 @@ LruInsert(File file)
392398
return 0;
393399
}
394400

395-
static void
401+
static bool
396402
ReleaseLruFile()
397403
{
398404
DO_DB(elog(DEBUG, "ReleaseLruFile. Opened %d", nfile));
399405

400-
if (nfile <= 0)
401-
elog(ERROR, "ReleaseLruFile: No open files available to be closed");
402-
403-
/*
404-
* There are opened files and so there should be at least one used vfd
405-
* in the ring.
406-
*/
407-
Assert(VfdCache[0].lruMoreRecently != 0);
408-
LruDelete(VfdCache[0].lruMoreRecently);
406+
if (nfile > 0)
407+
{
408+
/*
409+
* There are opened files and so there should be at least one used
410+
* vfd in the ring.
411+
*/
412+
Assert(VfdCache[0].lruMoreRecently != 0);
413+
LruDelete(VfdCache[0].lruMoreRecently);
414+
return true; /* freed a file */
415+
}
416+
return false; /* no files available to free */
409417
}
410418

411419
/*
@@ -612,17 +620,23 @@ fileNameOpenFile(FileName fileName,
612620
vfdP = &VfdCache[file];
613621

614622
while (nfile + numAllocatedFiles >= pg_nofile())
615-
ReleaseLruFile();
623+
{
624+
if (! ReleaseLruFile())
625+
break;
626+
}
616627

617628
tryAgain:
618629
vfdP->fd = open(fileName, fileFlags, fileMode);
619630
if (vfdP->fd < 0 && (errno == EMFILE || errno == ENFILE))
620631
{
632+
int save_errno = errno;
633+
621634
DO_DB(elog(DEBUG, "fileNameOpenFile: not enough descs, retry, er= %d",
622635
errno));
623636
errno = 0;
624-
ReleaseLruFile();
625-
goto tryAgain;
637+
if (ReleaseLruFile())
638+
goto tryAgain;
639+
errno = save_errno;
626640
}
627641

628642
if (vfdP->fd < 0)
@@ -1004,11 +1018,14 @@ AllocateFile(char *name, char *mode)
10041018
{
10051019
if (errno == EMFILE || errno == ENFILE)
10061020
{
1021+
int save_errno = errno;
1022+
10071023
DO_DB(elog(DEBUG, "AllocateFile: not enough descs, retry, er= %d",
10081024
errno));
10091025
errno = 0;
1010-
ReleaseLruFile();
1011-
goto TryAgain;
1026+
if (ReleaseLruFile())
1027+
goto TryAgain;
1028+
errno = save_errno;
10121029
}
10131030
}
10141031
else

0 commit comments

Comments
 (0)
0