Commit 5ba9d8c2 authored by Tom Lane's avatar Tom Lane

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().
parent a041c9c2
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.62 2000/07/05 21:10:05 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.63 2000/08/27 21:48:00 tgl Exp $
* *
* NOTES: * NOTES:
* *
...@@ -182,7 +182,7 @@ static void Delete(File file); ...@@ -182,7 +182,7 @@ static void Delete(File file);
static void LruDelete(File file); static void LruDelete(File file);
static void Insert(File file); static void Insert(File file);
static int LruInsert(File file); static int LruInsert(File file);
static void ReleaseLruFile(void); static bool ReleaseLruFile(void);
static File AllocateVfd(void); static File AllocateVfd(void);
static void FreeVfd(File file); static void FreeVfd(File file);
...@@ -230,13 +230,16 @@ tryAgain: ...@@ -230,13 +230,16 @@ tryAgain:
if (fd >= 0) if (fd >= 0)
return fd; /* success! */ return fd; /* success! */
if ((errno == EMFILE || errno == ENFILE) && nfile > 0) if (errno == EMFILE || errno == ENFILE)
{ {
int save_errno = errno;
DO_DB(elog(DEBUG, "BasicOpenFile: not enough descs, retry, er= %d", DO_DB(elog(DEBUG, "BasicOpenFile: not enough descs, retry, er= %d",
errno)); errno));
errno = 0; errno = 0;
ReleaseLruFile(); if (ReleaseLruFile())
goto tryAgain; goto tryAgain;
errno = save_errno;
} }
return -1; /* failure */ return -1; /* failure */
...@@ -278,7 +281,7 @@ pg_nofile(void) ...@@ -278,7 +281,7 @@ pg_nofile(void)
#if defined(FDDEBUG) #if defined(FDDEBUG)
static void static void
_dump_lru() _dump_lru(void)
{ {
int mru = VfdCache[0].lruLessRecently; int mru = VfdCache[0].lruLessRecently;
Vfd *vfdP = &VfdCache[mru]; Vfd *vfdP = &VfdCache[mru];
...@@ -389,7 +392,10 @@ LruInsert(File file) ...@@ -389,7 +392,10 @@ LruInsert(File file)
if (FileIsNotOpen(file)) if (FileIsNotOpen(file))
{ {
while (nfile + numAllocatedFiles >= pg_nofile()) while (nfile + numAllocatedFiles >= pg_nofile())
ReleaseLruFile(); {
if (! ReleaseLruFile())
break;
}
/* /*
* The open could still fail for lack of file descriptors, eg due * The open could still fail for lack of file descriptors, eg due
...@@ -400,8 +406,7 @@ LruInsert(File file) ...@@ -400,8 +406,7 @@ LruInsert(File file)
vfdP->fileMode); vfdP->fileMode);
if (vfdP->fd < 0) if (vfdP->fd < 0)
{ {
DO_DB(elog(DEBUG, "RE_OPEN FAILED: %d", DO_DB(elog(DEBUG, "RE_OPEN FAILED: %d", errno));
errno));
return vfdP->fd; return vfdP->fd;
} }
else else
...@@ -427,24 +432,26 @@ LruInsert(File file) ...@@ -427,24 +432,26 @@ LruInsert(File file)
return 0; return 0;
} }
static void static bool
ReleaseLruFile() ReleaseLruFile(void)
{ {
DO_DB(elog(DEBUG, "ReleaseLruFile. Opened %d", nfile)); DO_DB(elog(DEBUG, "ReleaseLruFile. Opened %d", nfile));
if (nfile <= 0) if (nfile > 0)
elog(ERROR, "ReleaseLruFile: No open files available to be closed"); {
/*
/* * There are opened files and so there should be at least one used
* There are opened files and so there should be at least one used vfd * vfd in the ring.
* in the ring. */
*/ Assert(VfdCache[0].lruMoreRecently != 0);
Assert(VfdCache[0].lruMoreRecently != 0); LruDelete(VfdCache[0].lruMoreRecently);
LruDelete(VfdCache[0].lruMoreRecently); return true; /* freed a file */
}
return false; /* no files available to free */
} }
static File static File
AllocateVfd() AllocateVfd(void)
{ {
Index i; Index i;
File file; File file;
...@@ -631,7 +638,10 @@ fileNameOpenFile(FileName fileName, ...@@ -631,7 +638,10 @@ fileNameOpenFile(FileName fileName,
vfdP = &VfdCache[file]; vfdP = &VfdCache[file];
while (nfile + numAllocatedFiles >= pg_nofile()) while (nfile + numAllocatedFiles >= pg_nofile())
ReleaseLruFile(); {
if (! ReleaseLruFile())
break;
}
vfdP->fd = BasicOpenFile(fileName, fileFlags, fileMode); vfdP->fd = BasicOpenFile(fileName, fileFlags, fileMode);
...@@ -1027,26 +1037,31 @@ AllocateFile(char *name, char *mode) ...@@ -1027,26 +1037,31 @@ AllocateFile(char *name, char *mode)
{ {
FILE *file; FILE *file;
DO_DB(elog(DEBUG, "AllocateFile: Allocated %d.", numAllocatedFiles)); DO_DB(elog(DEBUG, "AllocateFile: Allocated %d", numAllocatedFiles));
if (numAllocatedFiles >= MAX_ALLOCATED_FILES) if (numAllocatedFiles >= MAX_ALLOCATED_FILES)
elog(ERROR, "AllocateFile: too many private FDs demanded"); elog(ERROR, "AllocateFile: too many private FDs demanded");
TryAgain: TryAgain:
if ((file = fopen(name, mode)) == NULL) if ((file = fopen(name, mode)) != NULL)
{ {
if ((errno == EMFILE || errno == ENFILE) && nfile > 0) allocatedFiles[numAllocatedFiles++] = file;
{ return file;
DO_DB(elog(DEBUG, "AllocateFile: not enough descs, retry, er= %d", }
errno));
errno = 0; if (errno == EMFILE || errno == ENFILE)
ReleaseLruFile(); {
int save_errno = errno;
DO_DB(elog(DEBUG, "AllocateFile: not enough descs, retry, er= %d",
errno));
errno = 0;
if (ReleaseLruFile())
goto TryAgain; goto TryAgain;
} errno = save_errno;
} }
else
allocatedFiles[numAllocatedFiles++] = file; return NULL;
return file;
} }
void void
...@@ -1054,7 +1069,7 @@ FreeFile(FILE *file) ...@@ -1054,7 +1069,7 @@ FreeFile(FILE *file)
{ {
int i; int i;
DO_DB(elog(DEBUG, "FreeFile: Allocated %d.", numAllocatedFiles)); DO_DB(elog(DEBUG, "FreeFile: Allocated %d", numAllocatedFiles));
/* Remove file from list of allocated files, if it's present */ /* Remove file from list of allocated files, if it's present */
for (i = numAllocatedFiles; --i >= 0;) for (i = numAllocatedFiles; --i >= 0;)
...@@ -1079,7 +1094,7 @@ FreeFile(FILE *file) ...@@ -1079,7 +1094,7 @@ FreeFile(FILE *file)
* change in the logical state of the VFDs. * change in the logical state of the VFDs.
*/ */
void void
closeAllVfds() closeAllVfds(void)
{ {
Index i; Index i;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment