Skip to content

Commit 5ba9d8c

Browse files
committed
Change ReleaseLruFile() usage so that if we cannot release any more
virtual FDs, we just return the ENFILE/EMFILE error to the caller, rather than immediate elog(). This allows more robust behavior in the postmaster, which uses AllocateFile() but does not want elog().
1 parent a041c9c commit 5ba9d8c

File tree

1 file changed

+51
-36
lines changed
  • src/backend/storage/file

1 file changed

+51
-36
lines changed

src/backend/storage/file/fd.c

Lines changed: 51 additions & 36 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.62 2000/07/05 21:10:05 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.63 2000/08/27 21:48:00 tgl Exp $
1111
*
1212
* NOTES:
1313
*
@@ -182,7 +182,7 @@ static void Delete(File file);
182182
static void LruDelete(File file);
183183
static void Insert(File file);
184184
static int LruInsert(File file);
185-
static void ReleaseLruFile(void);
185+
static bool ReleaseLruFile(void);
186186
static File AllocateVfd(void);
187187
static void FreeVfd(File file);
188188

@@ -230,13 +230,16 @@ BasicOpenFile(FileName fileName, int fileFlags, int fileMode)
230230
if (fd >= 0)
231231
return fd; /* success! */
232232

233-
if ((errno == EMFILE || errno == ENFILE) && nfile > 0)
233+
if (errno == EMFILE || errno == ENFILE)
234234
{
235+
int save_errno = errno;
236+
235237
DO_DB(elog(DEBUG, "BasicOpenFile: not enough descs, retry, er= %d",
236238
errno));
237239
errno = 0;
238-
ReleaseLruFile();
239-
goto tryAgain;
240+
if (ReleaseLruFile())
241+
goto tryAgain;
242+
errno = save_errno;
240243
}
241244

242245
return -1; /* failure */
@@ -278,7 +281,7 @@ pg_nofile(void)
278281
#if defined(FDDEBUG)
279282

280283
static void
281-
_dump_lru()
284+
_dump_lru(void)
282285
{
283286
int mru = VfdCache[0].lruLessRecently;
284287
Vfd *vfdP = &VfdCache[mru];
@@ -389,7 +392,10 @@ LruInsert(File file)
389392
if (FileIsNotOpen(file))
390393
{
391394
while (nfile + numAllocatedFiles >= pg_nofile())
392-
ReleaseLruFile();
395+
{
396+
if (! ReleaseLruFile())
397+
break;
398+
}
393399

394400
/*
395401
* The open could still fail for lack of file descriptors, eg due
@@ -400,8 +406,7 @@ LruInsert(File file)
400406
vfdP->fileMode);
401407
if (vfdP->fd < 0)
402408
{
403-
DO_DB(elog(DEBUG, "RE_OPEN FAILED: %d",
404-
errno));
409+
DO_DB(elog(DEBUG, "RE_OPEN FAILED: %d", errno));
405410
return vfdP->fd;
406411
}
407412
else
@@ -427,24 +432,26 @@ LruInsert(File file)
427432
return 0;
428433
}
429434

430-
static void
431-
ReleaseLruFile()
435+
static bool
436+
ReleaseLruFile(void)
432437
{
433438
DO_DB(elog(DEBUG, "ReleaseLruFile. Opened %d", nfile));
434439

435-
if (nfile <= 0)
436-
elog(ERROR, "ReleaseLruFile: No open files available to be closed");
437-
438-
/*
439-
* There are opened files and so there should be at least one used vfd
440-
* in the ring.
441-
*/
442-
Assert(VfdCache[0].lruMoreRecently != 0);
443-
LruDelete(VfdCache[0].lruMoreRecently);
440+
if (nfile > 0)
441+
{
442+
/*
443+
* There are opened files and so there should be at least one used
444+
* vfd in the ring.
445+
*/
446+
Assert(VfdCache[0].lruMoreRecently != 0);
447+
LruDelete(VfdCache[0].lruMoreRecently);
448+
return true; /* freed a file */
449+
}
450+
return false; /* no files available to free */
444451
}
445452

446453
static File
447-
AllocateVfd()
454+
AllocateVfd(void)
448455
{
449456
Index i;
450457
File file;
@@ -631,7 +638,10 @@ fileNameOpenFile(FileName fileName,
631638
vfdP = &VfdCache[file];
632639

633640
while (nfile + numAllocatedFiles >= pg_nofile())
634-
ReleaseLruFile();
641+
{
642+
if (! ReleaseLruFile())
643+
break;
644+
}
635645

636646
vfdP->fd = BasicOpenFile(fileName, fileFlags, fileMode);
637647

@@ -1027,34 +1037,39 @@ AllocateFile(char *name, char *mode)
10271037
{
10281038
FILE *file;
10291039

1030-
DO_DB(elog(DEBUG, "AllocateFile: Allocated %d.", numAllocatedFiles));
1040+
DO_DB(elog(DEBUG, "AllocateFile: Allocated %d", numAllocatedFiles));
10311041

10321042
if (numAllocatedFiles >= MAX_ALLOCATED_FILES)
10331043
elog(ERROR, "AllocateFile: too many private FDs demanded");
10341044

10351045
TryAgain:
1036-
if ((file = fopen(name, mode)) == NULL)
1046+
if ((file = fopen(name, mode)) != NULL)
10371047
{
1038-
if ((errno == EMFILE || errno == ENFILE) && nfile > 0)
1039-
{
1040-
DO_DB(elog(DEBUG, "AllocateFile: not enough descs, retry, er= %d",
1041-
errno));
1042-
errno = 0;
1043-
ReleaseLruFile();
1048+
allocatedFiles[numAllocatedFiles++] = file;
1049+
return file;
1050+
}
1051+
1052+
if (errno == EMFILE || errno == ENFILE)
1053+
{
1054+
int save_errno = errno;
1055+
1056+
DO_DB(elog(DEBUG, "AllocateFile: not enough descs, retry, er= %d",
1057+
errno));
1058+
errno = 0;
1059+
if (ReleaseLruFile())
10441060
goto TryAgain;
1045-
}
1061+
errno = save_errno;
10461062
}
1047-
else
1048-
allocatedFiles[numAllocatedFiles++] = file;
1049-
return file;
1063+
1064+
return NULL;
10501065
}
10511066

10521067
void
10531068
FreeFile(FILE *file)
10541069
{
10551070
int i;
10561071

1057-
DO_DB(elog(DEBUG, "FreeFile: Allocated %d.", numAllocatedFiles));
1072+
DO_DB(elog(DEBUG, "FreeFile: Allocated %d", numAllocatedFiles));
10581073

10591074
/* Remove file from list of allocated files, if it's present */
10601075
for (i = numAllocatedFiles; --i >= 0;)
@@ -1079,7 +1094,7 @@ FreeFile(FILE *file)
10791094
* change in the logical state of the VFDs.
10801095
*/
10811096
void
1082-
closeAllVfds()
1097+
closeAllVfds(void)
10831098
{
10841099
Index i;
10851100

0 commit comments

Comments
 (0)