mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	1. Cleanup (no more FreeFd - unuseful; others).
2. FreeFile() has to do nothing with nfile (# of files opened by VFD manager).
This commit is contained in:
		@@ -6,7 +6,7 @@
 | 
			
		||||
 * Copyright (c) 1994, Regents of the University of California
 | 
			
		||||
 *
 | 
			
		||||
 * IDENTIFICATION
 | 
			
		||||
 *    $Id: fd.c,v 1.16 1997/02/20 22:54:18 scrappy Exp $
 | 
			
		||||
 *    $Id: fd.c,v 1.17 1997/05/22 16:51:19 vadim Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * NOTES:
 | 
			
		||||
 *
 | 
			
		||||
@@ -119,11 +119,6 @@ typedef struct vfd {
 | 
			
		||||
static  Vfd     *VfdCache;
 | 
			
		||||
static  Size    SizeVfdCache = 0;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Minimum number of file descriptors known to be free.
 | 
			
		||||
 */
 | 
			
		||||
static  int     FreeFd = 0;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Number of file descriptors known to be open.
 | 
			
		||||
 */
 | 
			
		||||
@@ -215,15 +210,17 @@ _dump_lru()
 | 
			
		||||
{
 | 
			
		||||
    int mru = VfdCache[0].lruLessRecently;
 | 
			
		||||
    Vfd *vfdP = &VfdCache[mru];
 | 
			
		||||
    char buf[2048];
 | 
			
		||||
    
 | 
			
		||||
    printf("MOST %d ", mru);
 | 
			
		||||
    sprintf(buf, "LRU: MOST %d ", mru);
 | 
			
		||||
    while (mru != 0)
 | 
			
		||||
        {
 | 
			
		||||
            mru = vfdP->lruLessRecently;
 | 
			
		||||
            vfdP = &VfdCache[mru];
 | 
			
		||||
            printf("%d ", mru);
 | 
			
		||||
        }
 | 
			
		||||
    printf("LEAST\n");
 | 
			
		||||
    {
 | 
			
		||||
    	mru = vfdP->lruLessRecently;
 | 
			
		||||
    	vfdP = &VfdCache[mru];
 | 
			
		||||
    	sprintf (buf + strlen(buf), "%d ", mru);
 | 
			
		||||
    }
 | 
			
		||||
    sprintf(buf + strlen(buf), "LEAST");
 | 
			
		||||
    elog (DEBUG, buf);
 | 
			
		||||
}
 | 
			
		||||
#endif /* FDDEBUG */
 | 
			
		||||
 | 
			
		||||
@@ -232,7 +229,7 @@ Delete(File file)
 | 
			
		||||
{
 | 
			
		||||
    Vfd *fileP;
 | 
			
		||||
    
 | 
			
		||||
    DO_DB(printf("DEBUG:        Delete %d (%s)\n",
 | 
			
		||||
    DO_DB(elog (DEBUG, "Delete %d (%s)",
 | 
			
		||||
                 file, VfdCache[file].fileName));
 | 
			
		||||
    DO_DB(_dump_lru());
 | 
			
		||||
    
 | 
			
		||||
@@ -254,7 +251,7 @@ LruDelete(File file)
 | 
			
		||||
    Vfd     *fileP;
 | 
			
		||||
    int returnValue;
 | 
			
		||||
    
 | 
			
		||||
    DO_DB(printf("DEBUG:        LruDelete %d (%s)\n",
 | 
			
		||||
    DO_DB(elog (DEBUG, "LruDelete %d (%s)",
 | 
			
		||||
                 file, VfdCache[file].fileName));
 | 
			
		||||
    
 | 
			
		||||
    Assert(file != 0);
 | 
			
		||||
@@ -281,9 +278,7 @@ LruDelete(File file)
 | 
			
		||||
    
 | 
			
		||||
    --nfile;
 | 
			
		||||
    fileP->fd = VFD_CLOSED;
 | 
			
		||||
    
 | 
			
		||||
    /* note that there is now one more free real file descriptor */
 | 
			
		||||
    FreeFd++;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -291,7 +286,7 @@ Insert(File file)
 | 
			
		||||
{
 | 
			
		||||
    Vfd *vfdP;
 | 
			
		||||
    
 | 
			
		||||
    DO_DB(printf("DEBUG:        Insert %d (%s)\n",
 | 
			
		||||
    DO_DB(elog(DEBUG, "Insert %d (%s)",
 | 
			
		||||
                 file, VfdCache[file].fileName));
 | 
			
		||||
    DO_DB(_dump_lru());
 | 
			
		||||
    
 | 
			
		||||
@@ -311,13 +306,16 @@ LruInsert (File file)
 | 
			
		||||
    Vfd *vfdP;
 | 
			
		||||
    int returnValue;
 | 
			
		||||
    
 | 
			
		||||
    DO_DB(printf("DEBUG:        LruInsert %d (%s)\n",
 | 
			
		||||
    DO_DB(elog(DEBUG, "LruInsert %d (%s)",
 | 
			
		||||
                 file, VfdCache[file].fileName));
 | 
			
		||||
    
 | 
			
		||||
    vfdP = &VfdCache[file];
 | 
			
		||||
    
 | 
			
		||||
    if (FileIsNotOpen(file)) {
 | 
			
		||||
        int tmpfd;
 | 
			
		||||
 | 
			
		||||
    	if ( nfile >= pg_nofile() )
 | 
			
		||||
            AssertLruRoom();
 | 
			
		||||
        
 | 
			
		||||
        /*
 | 
			
		||||
         * Note, we check to see if there's a free file descriptor
 | 
			
		||||
@@ -329,7 +327,6 @@ LruInsert (File file)
 | 
			
		||||
    tryAgain:
 | 
			
		||||
        tmpfd = open(Nulldev, O_CREAT|O_RDWR, 0666);
 | 
			
		||||
        if (tmpfd < 0) {
 | 
			
		||||
            FreeFd = 0;
 | 
			
		||||
            errno = 0;
 | 
			
		||||
            AssertLruRoom();
 | 
			
		||||
            goto tryAgain;
 | 
			
		||||
@@ -339,11 +336,11 @@ LruInsert (File file)
 | 
			
		||||
        vfdP->fd = open(vfdP->fileName,vfdP->fileFlags,vfdP->fileMode);
 | 
			
		||||
        
 | 
			
		||||
        if (vfdP->fd < 0) {
 | 
			
		||||
            DO_DB(printf("RE_OPEN FAILED: %d\n",
 | 
			
		||||
            DO_DB(elog(DEBUG, "RE_OPEN FAILED: %d",
 | 
			
		||||
                         errno));
 | 
			
		||||
            return (vfdP->fd);
 | 
			
		||||
        } else {
 | 
			
		||||
            DO_DB(printf("RE_OPEN SUCCESS\n"));
 | 
			
		||||
            DO_DB(elog (DEBUG, "RE_OPEN SUCCESS"));
 | 
			
		||||
            ++nfile;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
@@ -357,9 +354,6 @@ LruInsert (File file)
 | 
			
		||||
        /* init state on open */
 | 
			
		||||
        vfdP->fdstate = 0x0;
 | 
			
		||||
        
 | 
			
		||||
        /* note that a file descriptor has been used up */
 | 
			
		||||
        if (FreeFd > 0)
 | 
			
		||||
            FreeFd--;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /*
 | 
			
		||||
@@ -374,16 +368,16 @@ LruInsert (File file)
 | 
			
		||||
static void
 | 
			
		||||
AssertLruRoom()
 | 
			
		||||
{
 | 
			
		||||
    DO_DB(printf("DEBUG:        AssertLruRoom (FreeFd = %d)\n",
 | 
			
		||||
                 FreeFd));
 | 
			
		||||
    DO_DB(elog(DEBUG, "AssertLruRoom. Opened %d", nfile));
 | 
			
		||||
    
 | 
			
		||||
    if (FreeFd <= 0 || nfile >= pg_nofile()) {
 | 
			
		||||
        /* We supposedly are using more vfds than we want to be.  First
 | 
			
		||||
           assert that there is at least one used vfd in the ring. 
 | 
			
		||||
           */
 | 
			
		||||
        Assert(VfdCache[0].lruMoreRecently != 0);
 | 
			
		||||
        LruDelete(VfdCache[0].lruMoreRecently);
 | 
			
		||||
    }
 | 
			
		||||
    if ( nfile <= 0 )
 | 
			
		||||
    	elog (FATAL, "AssertLruRoom: No opened files - no one can be closed");
 | 
			
		||||
    /* 
 | 
			
		||||
     * There are opened files and so there should be at least one used vfd 
 | 
			
		||||
     * in the ring. 
 | 
			
		||||
     */
 | 
			
		||||
    Assert(VfdCache[0].lruMoreRecently != 0);
 | 
			
		||||
    LruDelete(VfdCache[0].lruMoreRecently);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static File
 | 
			
		||||
@@ -392,13 +386,12 @@ AllocateVfd()
 | 
			
		||||
    Index       i;
 | 
			
		||||
    File        file;
 | 
			
		||||
    
 | 
			
		||||
    DO_DB(printf("DEBUG:        AllocateVfd\n"));
 | 
			
		||||
    DO_DB(elog(DEBUG, "AllocateVfd. Size %d", SizeVfdCache));
 | 
			
		||||
    
 | 
			
		||||
    if (SizeVfdCache == 0) {
 | 
			
		||||
        
 | 
			
		||||
        /* initialize */
 | 
			
		||||
        VfdCache = (Vfd *)malloc(sizeof(Vfd));
 | 
			
		||||
        
 | 
			
		||||
        VfdCache->nextFree = 0;
 | 
			
		||||
        VfdCache->lruMoreRecently = 0;
 | 
			
		||||
        VfdCache->lruLessRecently = 0;
 | 
			
		||||
@@ -408,8 +401,8 @@ AllocateVfd()
 | 
			
		||||
        SizeVfdCache = 1;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if (VfdCache[0].nextFree == 0) {
 | 
			
		||||
        
 | 
			
		||||
    if (VfdCache[0].nextFree == 0)
 | 
			
		||||
    {
 | 
			
		||||
        /*
 | 
			
		||||
         * The free list is empty so it is time to increase the
 | 
			
		||||
         * size of the array
 | 
			
		||||
@@ -417,7 +410,7 @@ AllocateVfd()
 | 
			
		||||
        
 | 
			
		||||
        VfdCache =(Vfd *)realloc(VfdCache, sizeof(Vfd)*SizeVfdCache*2);
 | 
			
		||||
        Assert(VfdCache != NULL);
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * Set up the free list for the new entries
 | 
			
		||||
         */
 | 
			
		||||
@@ -452,7 +445,7 @@ AllocateVfd()
 | 
			
		||||
static void
 | 
			
		||||
FreeVfd(File file)
 | 
			
		||||
{
 | 
			
		||||
    DO_DB(printf("DB: FreeVfd: %d (%s)\n",
 | 
			
		||||
    DO_DB(elog(DEBUG, "FreeVfd: %d (%s)",
 | 
			
		||||
                 file, VfdCache[file].fileName));
 | 
			
		||||
    
 | 
			
		||||
    VfdCache[file].nextFree = VfdCache[0].nextFree;
 | 
			
		||||
@@ -488,7 +481,7 @@ FileAccess(File file)
 | 
			
		||||
{
 | 
			
		||||
    int returnValue;
 | 
			
		||||
    
 | 
			
		||||
    DO_DB(printf("DB: FileAccess %d (%s)\n",
 | 
			
		||||
    DO_DB(elog(DEBUG, "FileAccess %d (%s)",
 | 
			
		||||
                 file, VfdCache[file].fileName));
 | 
			
		||||
    
 | 
			
		||||
    /*
 | 
			
		||||
@@ -498,8 +491,6 @@ FileAccess(File file)
 | 
			
		||||
    
 | 
			
		||||
    if (FileIsNotOpen(file)) {
 | 
			
		||||
        
 | 
			
		||||
        AssertLruRoom();
 | 
			
		||||
        
 | 
			
		||||
        returnValue = LruInsert(file);
 | 
			
		||||
        if (returnValue != 0)
 | 
			
		||||
            return returnValue;
 | 
			
		||||
@@ -537,29 +528,25 @@ fileNameOpenFile(FileName fileName,
 | 
			
		||||
                 int fileFlags,
 | 
			
		||||
                 int fileMode)
 | 
			
		||||
{
 | 
			
		||||
    static int osRanOut = 0;
 | 
			
		||||
    File        file;
 | 
			
		||||
    Vfd *vfdP;
 | 
			
		||||
    int     tmpfd;
 | 
			
		||||
    
 | 
			
		||||
    DO_DB(printf("DEBUG: FileNameOpenFile: %s %x %o\n",
 | 
			
		||||
    DO_DB(elog(DEBUG, "fileNameOpenFile: %s %x %o",
 | 
			
		||||
                 fileName, fileFlags, fileMode));
 | 
			
		||||
    
 | 
			
		||||
    file = AllocateVfd();
 | 
			
		||||
    vfdP = &VfdCache[file];
 | 
			
		||||
    
 | 
			
		||||
    if (nfile >= pg_nofile() || (FreeFd == 0 && osRanOut)) {
 | 
			
		||||
    if ( nfile >= pg_nofile() )
 | 
			
		||||
        AssertLruRoom();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 tryAgain:
 | 
			
		||||
    tmpfd = open(Nulldev, O_CREAT|O_RDWR, 0666);
 | 
			
		||||
    if (tmpfd < 0) {
 | 
			
		||||
        DO_DB(printf("DB: not enough descs, retry, er= %d\n",
 | 
			
		||||
        DO_DB(elog(DEBUG, "fileNameOpenFile: not enough descs, retry, er= %d",
 | 
			
		||||
                     errno));
 | 
			
		||||
        errno = 0;
 | 
			
		||||
        FreeFd = 0;
 | 
			
		||||
        osRanOut = 1;
 | 
			
		||||
        AssertLruRoom();
 | 
			
		||||
        goto tryAgain;
 | 
			
		||||
    } else {
 | 
			
		||||
@@ -574,17 +561,17 @@ fileNameOpenFile(FileName fileName,
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
    ++nfile;
 | 
			
		||||
    DO_DB(printf("DB: FNOF success %d\n",
 | 
			
		||||
    DO_DB(elog(DEBUG, "fileNameOpenFile: success %d",
 | 
			
		||||
                 vfdP->fd));
 | 
			
		||||
    
 | 
			
		||||
    (void)LruInsert(file);
 | 
			
		||||
    Insert(file);
 | 
			
		||||
    
 | 
			
		||||
    if (fileName==NULL) {
 | 
			
		||||
        elog(WARN, "fileNameOpenFile: NULL fname");
 | 
			
		||||
    }
 | 
			
		||||
    vfdP->fileName = malloc(strlen(fileName)+1);
 | 
			
		||||
    strcpy(vfdP->fileName,fileName);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    vfdP->fileFlags = fileFlags & ~(O_TRUNC|O_EXCL);
 | 
			
		||||
    vfdP->fileMode = fileMode;
 | 
			
		||||
    vfdP->seekPos = 0;
 | 
			
		||||
@@ -621,7 +608,7 @@ FileClose(File file)
 | 
			
		||||
{
 | 
			
		||||
    int returnValue;
 | 
			
		||||
    
 | 
			
		||||
    DO_DB(printf("DEBUG: FileClose: %d (%s)\n",
 | 
			
		||||
    DO_DB(elog(DEBUG, "FileClose: %d (%s)",
 | 
			
		||||
                 file, VfdCache[file].fileName));
 | 
			
		||||
    
 | 
			
		||||
    if (!FileIsNotOpen(file)) {
 | 
			
		||||
@@ -629,9 +616,6 @@ FileClose(File file)
 | 
			
		||||
        /* remove the file from the lru ring */
 | 
			
		||||
        Delete(file);
 | 
			
		||||
        
 | 
			
		||||
        /* record the new free operating system file descriptor */
 | 
			
		||||
        FreeFd++;
 | 
			
		||||
        
 | 
			
		||||
        /* if we did any writes, sync the file before closing */
 | 
			
		||||
        if (VfdCache[file].fdstate & FD_DIRTY) {
 | 
			
		||||
            returnValue = fsync(VfdCache[file].fd);
 | 
			
		||||
@@ -661,7 +645,7 @@ FileUnlink(File file)
 | 
			
		||||
{
 | 
			
		||||
    int returnValue;
 | 
			
		||||
    
 | 
			
		||||
    DO_DB(printf("DB: FileClose: %d (%s)\n",
 | 
			
		||||
    DO_DB(elog(DEBUG, "FileUnlink: %d (%s)",
 | 
			
		||||
                 file, VfdCache[file].fileName));
 | 
			
		||||
    
 | 
			
		||||
    if (!FileIsNotOpen(file)) {
 | 
			
		||||
@@ -669,9 +653,6 @@ FileUnlink(File file)
 | 
			
		||||
        /* remove the file from the lru ring */
 | 
			
		||||
        Delete(file);
 | 
			
		||||
        
 | 
			
		||||
        /* record the new free operating system file descriptor */
 | 
			
		||||
        FreeFd++;
 | 
			
		||||
        
 | 
			
		||||
        /* if we did any writes, sync the file before closing */
 | 
			
		||||
        if (VfdCache[file].fdstate & FD_DIRTY) {
 | 
			
		||||
            returnValue = fsync(VfdCache[file].fd);
 | 
			
		||||
@@ -699,7 +680,7 @@ FileRead(File file, char *buffer, int amount)
 | 
			
		||||
{
 | 
			
		||||
    int returnCode;
 | 
			
		||||
 | 
			
		||||
    DO_DB(printf("DEBUG: FileRead: %d (%s) %d 0x%x\n",
 | 
			
		||||
    DO_DB(elog(DEBUG, "FileRead: %d (%s) %d %p",
 | 
			
		||||
                 file, VfdCache[file].fileName, amount, buffer));
 | 
			
		||||
    
 | 
			
		||||
    FileAccess(file);
 | 
			
		||||
@@ -716,7 +697,7 @@ FileWrite(File file, char *buffer, int amount)
 | 
			
		||||
{
 | 
			
		||||
    int returnCode;
 | 
			
		||||
 | 
			
		||||
    DO_DB(printf("DB: FileWrite: %d (%s) %d 0x%lx\n",
 | 
			
		||||
    DO_DB(elog(DEBUG, "FileWrite: %d (%s) %d %p",
 | 
			
		||||
                 file, VfdCache[file].fileName, amount, buffer));
 | 
			
		||||
    
 | 
			
		||||
    FileAccess(file);
 | 
			
		||||
@@ -736,7 +717,7 @@ FileSeek(File file, long offset, int whence)
 | 
			
		||||
{
 | 
			
		||||
    int returnCode;
 | 
			
		||||
    
 | 
			
		||||
    DO_DB(printf("DEBUG: FileSeek: %d (%s) %d %d\n",
 | 
			
		||||
    DO_DB(elog (DEBUG, "FileSeek: %d (%s) %ld %d",
 | 
			
		||||
                 file, VfdCache[file].fileName, offset, whence));
 | 
			
		||||
    
 | 
			
		||||
    if (FileIsNotOpen(file)) {
 | 
			
		||||
@@ -771,7 +752,7 @@ FileSeek(File file, long offset, int whence)
 | 
			
		||||
long
 | 
			
		||||
FileTell(File file)
 | 
			
		||||
{
 | 
			
		||||
    DO_DB(printf("DEBUG: FileTell %d (%s)\n",
 | 
			
		||||
    DO_DB(elog(DEBUG, "FileTell %d (%s)",
 | 
			
		||||
                 file, VfdCache[file].fileName));
 | 
			
		||||
    return VfdCache[file].seekPos;
 | 
			
		||||
}
 | 
			
		||||
@@ -781,7 +762,7 @@ FileTruncate(File file, int offset)
 | 
			
		||||
{
 | 
			
		||||
    int returnCode;
 | 
			
		||||
 | 
			
		||||
    DO_DB(printf("DEBUG: FileTruncate %d (%s)\n",
 | 
			
		||||
    DO_DB(elog(DEBUG, "FileTruncate %d (%s)",
 | 
			
		||||
                 file, VfdCache[file].fileName));
 | 
			
		||||
    
 | 
			
		||||
    (void) FileSync(file);
 | 
			
		||||
@@ -840,26 +821,25 @@ AllocateFile()
 | 
			
		||||
{
 | 
			
		||||
    int fd;
 | 
			
		||||
    int fdleft;
 | 
			
		||||
    
 | 
			
		||||
    DO_DB(elog(DEBUG, "AllocateFile: Allocated %d.", allocatedFiles));
 | 
			
		||||
 | 
			
		||||
    while ((fd = open(Nulldev,O_WRONLY,0)) < 0) {
 | 
			
		||||
        if (errno == EMFILE) {
 | 
			
		||||
            errno = 0;
 | 
			
		||||
            FreeFd = 0;
 | 
			
		||||
            AssertLruRoom();
 | 
			
		||||
        } else {
 | 
			
		||||
            elog(WARN,"Open: %s in %s line %d, %s\n", Nulldev,
 | 
			
		||||
            elog(WARN,"Open: %s in %s line %d, %s", Nulldev,
 | 
			
		||||
                 __FILE__, __LINE__, strerror(errno));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    close(fd);
 | 
			
		||||
    ++allocatedFiles;
 | 
			
		||||
    fdleft = pg_nofile() - allocatedFiles;
 | 
			
		||||
    fdleft = pg_nofile() - allocatedFiles - nfile;
 | 
			
		||||
    if (fdleft < 6) {
 | 
			
		||||
        elog(DEBUG,"warning: few usable file descriptors left (%d)", fdleft);
 | 
			
		||||
        elog(NOTICE,"warning: few usable file descriptors left (%d)", fdleft);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    DO_DB(printf("DEBUG: AllocatedFile.  FreeFd = %d\n",
 | 
			
		||||
                 FreeFd));
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@@ -869,10 +849,8 @@ AllocateFile()
 | 
			
		||||
void
 | 
			
		||||
FreeFile()
 | 
			
		||||
{
 | 
			
		||||
    DO_DB(printf("DEBUG: FreeFile.  FreeFd now %d\n",
 | 
			
		||||
                 FreeFd));
 | 
			
		||||
    FreeFd++;
 | 
			
		||||
    nfile++;                    /* dangerous */
 | 
			
		||||
    DO_DB(elog(DEBUG, "FreeFile: Allocated %d.", allocatedFiles));
 | 
			
		||||
 | 
			
		||||
    Assert(allocatedFiles > 0);
 | 
			
		||||
    --allocatedFiles;
 | 
			
		||||
}
 | 
			
		||||
@@ -894,11 +872,8 @@ closeOneVfd()
 | 
			
		||||
    int tmpfd;
 | 
			
		||||
    
 | 
			
		||||
    tmpfd = open(Nulldev, O_CREAT | O_RDWR, 0666);
 | 
			
		||||
    if (tmpfd < 0) {
 | 
			
		||||
        FreeFd = 0;
 | 
			
		||||
    if (tmpfd < 0)
 | 
			
		||||
        AssertLruRoom();
 | 
			
		||||
        FreeFd = 0;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
        close(tmpfd);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user