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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy