Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
634b38aa
Commit
634b38aa
authored
Dec 27, 1996
by
Bryan Henderson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add asserts to check for file descriptor ring corruption.
parent
4a5135c3
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
293 additions
and
285 deletions
+293
-285
src/backend/storage/file/fd.c
src/backend/storage/file/fd.c
+293
-285
No files found.
src/backend/storage/file/fd.c
View file @
634b38aa
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
* Copyright (c) 1994, Regents of the University of California
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Id: fd.c,v 1.1
0 1996/12/04 03:05:58
bryanh Exp $
* $Id: fd.c,v 1.1
1 1996/12/27 22:57:51
bryanh Exp $
*
*
* NOTES:
* NOTES:
*
*
...
@@ -48,7 +48,7 @@
...
@@ -48,7 +48,7 @@
#include <fcntl.h>
#include <fcntl.h>
#include "postgres.h"
#include "postgres.h"
#include "miscadmin.h"
/* for DataDir */
#include "miscadmin.h"
/* for DataDir */
#include "utils/palloc.h"
#include "utils/palloc.h"
#include "storage/fd.h"
#include "storage/fd.h"
...
@@ -81,7 +81,7 @@
...
@@ -81,7 +81,7 @@
* equivalent, the OS must still open several files to perform the
* equivalent, the OS must still open several files to perform the
* dynamic loading. Keep this here.)
* dynamic loading. Keep this here.)
*/
*/
#define RESERVE_FOR_LD
10
#define RESERVE_FOR_LD
10
/*
/*
* If we are using weird storage managers, we may need to keep real
* If we are using weird storage managers, we may need to keep real
...
@@ -93,10 +93,10 @@
...
@@ -93,10 +93,10 @@
* these descriptors at whim, we must make allowances for them.
* these descriptors at whim, we must make allowances for them.
*/
*/
#ifdef HP_JUKEBOX
#ifdef HP_JUKEBOX
#define RESERVE_FOR_JB
25
#define RESERVE_FOR_JB
25
#define
MAXFILES
((NOFILE - RESERVE_FOR_LD) - RESERVE_FOR_JB)
#define
MAXFILES
((NOFILE - RESERVE_FOR_LD) - RESERVE_FOR_JB)
#else
/* HP_JUKEBOX */
#else
/* HP_JUKEBOX */
#define
MAXFILES
(NOFILE - RESERVE_FOR_LD)
#define
MAXFILES
(NOFILE - RESERVE_FOR_LD)
#endif
/* HP_JUKEBOX */
#endif
/* HP_JUKEBOX */
/* Debugging.... */
/* Debugging.... */
...
@@ -115,36 +115,36 @@
...
@@ -115,36 +115,36 @@
#define FileIsNotOpen(file) (VfdCache[file].fd == VFD_CLOSED)
#define FileIsNotOpen(file) (VfdCache[file].fd == VFD_CLOSED)
typedef
struct
vfd
{
typedef
struct
vfd
{
signed
short
fd
;
signed
short
fd
;
unsigned
short
fdstate
;
unsigned
short
fdstate
;
#define FD_DIRTY
(1 << 0)
#define FD_DIRTY
(1 << 0)
File
nextFree
;
File
nextFree
;
File
lruMoreRecently
;
File
lruMoreRecently
;
File
lruLessRecently
;
File
lruLessRecently
;
long
seekPos
;
long
seekPos
;
char
*
fileName
;
char
*
fileName
;
int
fileFlags
;
int
fileFlags
;
int
fileMode
;
int
fileMode
;
}
Vfd
;
}
Vfd
;
/*
/*
* Virtual File Descriptor array pointer and size. This grows as
* Virtual File Descriptor array pointer and size. This grows as
* needed.
* needed.
*/
*/
static
Vfd
*
VfdCache
;
static
Vfd
*
VfdCache
;
static
Size
SizeVfdCache
=
0
;
static
Size
SizeVfdCache
=
0
;
/*
/*
* Minimum number of file descriptors known to be free.
* Minimum number of file descriptors known to be free.
*/
*/
static
int
FreeFd
=
0
;
static
int
FreeFd
=
0
;
/*
/*
* Number of file descriptors known to be open.
* Number of file descriptors known to be open.
*/
*/
static
int
nfile
=
0
;
static
int
nfile
=
0
;
/*
/*
* we use the name of the null device in various places, mostly so
* we use the name of the null device in various places, mostly so
...
@@ -162,14 +162,16 @@ static char Sep_char = '\\';
...
@@ -162,14 +162,16 @@ static char Sep_char = '\\';
/*
/*
* Private Routines
* Private Routines
*
*
* Delete
- delete a file from the Lru ring
* Delete
- delete a file from the Lru ring
* LruDelete
- remove a file from the Lru ring and close
* LruDelete
- remove a file from the Lru ring and close
* Insert
- put a file at the front of the Lru ring
* Insert
- put a file at the front of the Lru ring
* LruInsert
- put a file at the front of the Lru ring and open
* LruInsert
- put a file at the front of the Lru ring and open
* AssertLruRoom - make sure that there is a free fd.
* AssertLruRoom - make sure that there is a free fd.
*
*
* the Last Recently Used ring is a doubly linked list that begins and
* the Last Recently Used ring is a doubly linked list that begins and
* ends on element zero.
* ends on element zero. Element zero is special -- it doesn't represent
* a file and its "fd" field always == VFD_CLOSED. Element zero is just an
* anchor that shows us the beginning/end of the ring.
*
*
* example:
* example:
*
*
...
@@ -180,8 +182,8 @@ static char Sep_char = '\\';
...
@@ -180,8 +182,8 @@ static char Sep_char = '\\';
* \\less--> MostRecentlyUsedFile <---/ |
* \\less--> MostRecentlyUsedFile <---/ |
* \more---/ \--less--/
* \more---/ \--less--/
*
*
* AllocateVfd
- grab a free (or new) file record (from VfdArray)
* AllocateVfd
- grab a free (or new) file record (from VfdArray)
* FreeVfd
- free a file record
* FreeVfd
- free a file record
*
*
*/
*/
static
void
Delete
(
File
file
);
static
void
Delete
(
File
file
);
...
@@ -213,11 +215,11 @@ _dump_lru()
...
@@ -213,11 +215,11 @@ _dump_lru()
printf
(
"MOST %d "
,
mru
);
printf
(
"MOST %d "
,
mru
);
while
(
mru
!=
0
)
while
(
mru
!=
0
)
{
{
mru
=
vfdP
->
lruLessRecently
;
mru
=
vfdP
->
lruLessRecently
;
vfdP
=
&
VfdCache
[
mru
];
vfdP
=
&
VfdCache
[
mru
];
printf
(
"%d "
,
mru
);
printf
(
"%d "
,
mru
);
}
}
printf
(
"LEAST
\n
"
);
printf
(
"LEAST
\n
"
);
}
}
#endif
/* FDDEBUG */
#endif
/* FDDEBUG */
...
@@ -225,10 +227,10 @@ _dump_lru()
...
@@ -225,10 +227,10 @@ _dump_lru()
static
void
static
void
Delete
(
File
file
)
Delete
(
File
file
)
{
{
Vfd
*
fileP
;
Vfd
*
fileP
;
DO_DB
(
printf
(
"DEBUG:
Delete %d (%s)
\n
"
,
DO_DB
(
printf
(
"DEBUG:
Delete %d (%s)
\n
"
,
file
,
VfdCache
[
file
].
fileName
));
file
,
VfdCache
[
file
].
fileName
));
DO_DB
(
_dump_lru
());
DO_DB
(
_dump_lru
());
Assert
(
file
!=
0
);
Assert
(
file
!=
0
);
...
@@ -236,9 +238,9 @@ Delete(File file)
...
@@ -236,9 +238,9 @@ Delete(File file)
fileP
=
&
VfdCache
[
file
];
fileP
=
&
VfdCache
[
file
];
VfdCache
[
fileP
->
lruLessRecently
].
lruMoreRecently
=
VfdCache
[
fileP
->
lruLessRecently
].
lruMoreRecently
=
VfdCache
[
file
].
lruMoreRecently
;
VfdCache
[
file
].
lruMoreRecently
;
VfdCache
[
fileP
->
lruMoreRecently
].
lruLessRecently
=
VfdCache
[
fileP
->
lruMoreRecently
].
lruLessRecently
=
VfdCache
[
file
].
lruLessRecently
;
VfdCache
[
file
].
lruLessRecently
;
DO_DB
(
_dump_lru
());
DO_DB
(
_dump_lru
());
}
}
...
@@ -247,10 +249,10 @@ static void
...
@@ -247,10 +249,10 @@ static void
LruDelete
(
File
file
)
LruDelete
(
File
file
)
{
{
Vfd
*
fileP
;
Vfd
*
fileP
;
int
returnValue
;
int
returnValue
;
DO_DB
(
printf
(
"DEBUG:
LruDelete %d (%s)
\n
"
,
DO_DB
(
printf
(
"DEBUG:
LruDelete %d (%s)
\n
"
,
file
,
VfdCache
[
file
].
fileName
));
file
,
VfdCache
[
file
].
fileName
));
Assert
(
file
!=
0
);
Assert
(
file
!=
0
);
...
@@ -265,9 +267,9 @@ LruDelete(File file)
...
@@ -265,9 +267,9 @@ LruDelete(File file)
/* if we have written to the file, sync it */
/* if we have written to the file, sync it */
if
(
fileP
->
fdstate
&
FD_DIRTY
)
{
if
(
fileP
->
fdstate
&
FD_DIRTY
)
{
returnValue
=
fsync
(
fileP
->
fd
);
returnValue
=
fsync
(
fileP
->
fd
);
Assert
(
returnValue
!=
-
1
);
Assert
(
returnValue
!=
-
1
);
fileP
->
fdstate
&=
~
FD_DIRTY
;
fileP
->
fdstate
&=
~
FD_DIRTY
;
}
}
/* close the file */
/* close the file */
...
@@ -284,10 +286,10 @@ LruDelete(File file)
...
@@ -284,10 +286,10 @@ LruDelete(File file)
static
void
static
void
Insert
(
File
file
)
Insert
(
File
file
)
{
{
Vfd
*
vfdP
;
Vfd
*
vfdP
;
DO_DB
(
printf
(
"DEBUG:
Insert %d (%s)
\n
"
,
DO_DB
(
printf
(
"DEBUG:
Insert %d (%s)
\n
"
,
file
,
VfdCache
[
file
].
fileName
));
file
,
VfdCache
[
file
].
fileName
));
DO_DB
(
_dump_lru
());
DO_DB
(
_dump_lru
());
vfdP
=
&
VfdCache
[
file
];
vfdP
=
&
VfdCache
[
file
];
...
@@ -303,58 +305,58 @@ Insert(File file)
...
@@ -303,58 +305,58 @@ Insert(File file)
static
int
static
int
LruInsert
(
File
file
)
LruInsert
(
File
file
)
{
{
Vfd
*
vfdP
;
Vfd
*
vfdP
;
int
returnValue
;
int
returnValue
;
DO_DB
(
printf
(
"DEBUG:
LruInsert %d (%s)
\n
"
,
DO_DB
(
printf
(
"DEBUG:
LruInsert %d (%s)
\n
"
,
file
,
VfdCache
[
file
].
fileName
));
file
,
VfdCache
[
file
].
fileName
));
vfdP
=
&
VfdCache
[
file
];
vfdP
=
&
VfdCache
[
file
];
if
(
FileIsNotOpen
(
file
))
{
if
(
FileIsNotOpen
(
file
))
{
int
tmpfd
;
int
tmpfd
;
/*
/*
* Note, we check to see if there's a free file descriptor
* Note, we check to see if there's a free file descriptor
* before attempting to open a file. One general way to do
* before attempting to open a file. One general way to do
* this is to try to open the null device which everybody
* this is to try to open the null device which everybody
* should be able to open all the time. If this fails, we
* should be able to open all the time. If this fails, we
* assume this is because there's no free file descriptors.
* assume this is because there's no free file descriptors.
*/
*/
tryAgain:
tryAgain:
tmpfd
=
open
(
Nulldev
,
O_CREAT
|
O_RDWR
,
0666
);
tmpfd
=
open
(
Nulldev
,
O_CREAT
|
O_RDWR
,
0666
);
if
(
tmpfd
<
0
)
{
if
(
tmpfd
<
0
)
{
FreeFd
=
0
;
FreeFd
=
0
;
errno
=
0
;
errno
=
0
;
AssertLruRoom
();
AssertLruRoom
();
goto
tryAgain
;
goto
tryAgain
;
}
else
{
}
else
{
close
(
tmpfd
);
close
(
tmpfd
);
}
}
vfdP
->
fd
=
open
(
vfdP
->
fileName
,
vfdP
->
fileFlags
,
vfdP
->
fileMode
);
vfdP
->
fd
=
open
(
vfdP
->
fileName
,
vfdP
->
fileFlags
,
vfdP
->
fileMode
);
if
(
vfdP
->
fd
<
0
)
{
if
(
vfdP
->
fd
<
0
)
{
DO_DB
(
printf
(
"RE_OPEN FAILED: %d
\n
"
,
DO_DB
(
printf
(
"RE_OPEN FAILED: %d
\n
"
,
errno
));
errno
));
return
(
vfdP
->
fd
);
return
(
vfdP
->
fd
);
}
else
{
}
else
{
DO_DB
(
printf
(
"RE_OPEN SUCCESS
\n
"
));
DO_DB
(
printf
(
"RE_OPEN SUCCESS
\n
"
));
++
nfile
;
++
nfile
;
}
}
/* seek to the right position */
/* seek to the right position */
if
(
vfdP
->
seekPos
!=
0L
)
{
if
(
vfdP
->
seekPos
!=
0L
)
{
returnValue
=
returnValue
=
lseek
(
vfdP
->
fd
,
vfdP
->
seekPos
,
SEEK_SET
);
lseek
(
vfdP
->
fd
,
vfdP
->
seekPos
,
SEEK_SET
);
Assert
(
returnValue
!=
-
1
);
Assert
(
returnValue
!=
-
1
);
}
}
/* init state on open */
/* init state on open */
vfdP
->
fdstate
=
0x0
;
vfdP
->
fdstate
=
0x0
;
/* note that a file descriptor has been used up */
/* note that a file descriptor has been used up */
if
(
FreeFd
>
0
)
if
(
FreeFd
>
0
)
FreeFd
--
;
FreeFd
--
;
}
}
/*
/*
...
@@ -369,69 +371,73 @@ LruInsert (File file)
...
@@ -369,69 +371,73 @@ LruInsert (File file)
static
void
static
void
AssertLruRoom
()
AssertLruRoom
()
{
{
DO_DB
(
printf
(
"DEBUG:
AssertLruRoom (FreeFd = %d)
\n
"
,
DO_DB
(
printf
(
"DEBUG:
AssertLruRoom (FreeFd = %d)
\n
"
,
FreeFd
));
FreeFd
));
if
(
FreeFd
<=
0
||
nfile
>=
MAXFILES
)
{
if
(
FreeFd
<=
0
||
nfile
>=
MAXFILES
)
{
LruDelete
(
VfdCache
[
0
].
lruMoreRecently
);
/* 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
);
}
}
}
}
static
File
static
File
AllocateVfd
()
AllocateVfd
()
{
{
Index
i
;
Index
i
;
File
file
;
File
file
;
DO_DB
(
printf
(
"DEBUG:
AllocateVfd
\n
"
));
DO_DB
(
printf
(
"DEBUG:
AllocateVfd
\n
"
));
if
(
SizeVfdCache
==
0
)
{
if
(
SizeVfdCache
==
0
)
{
/* initialize */
/* initialize */
VfdCache
=
(
Vfd
*
)
malloc
(
sizeof
(
Vfd
));
VfdCache
=
(
Vfd
*
)
malloc
(
sizeof
(
Vfd
));
VfdCache
->
nextFree
=
0
;
VfdCache
->
nextFree
=
0
;
VfdCache
->
lruMoreRecently
=
0
;
VfdCache
->
lruMoreRecently
=
0
;
VfdCache
->
lruLessRecently
=
0
;
VfdCache
->
lruLessRecently
=
0
;
VfdCache
->
fd
=
VFD_CLOSED
;
VfdCache
->
fd
=
VFD_CLOSED
;
VfdCache
->
fdstate
=
0x0
;
VfdCache
->
fdstate
=
0x0
;
SizeVfdCache
=
1
;
SizeVfdCache
=
1
;
}
}
if
(
VfdCache
[
0
].
nextFree
==
0
)
{
if
(
VfdCache
[
0
].
nextFree
==
0
)
{
/*
/*
* The free list is empty so it is time to increase the
* The free list is empty so it is time to increase the
* size of the array
* size of the array
*/
*/
VfdCache
=
(
Vfd
*
)
realloc
(
VfdCache
,
sizeof
(
Vfd
)
*
SizeVfdCache
*
2
);
VfdCache
=
(
Vfd
*
)
realloc
(
VfdCache
,
sizeof
(
Vfd
)
*
SizeVfdCache
*
2
);
Assert
(
VfdCache
!=
NULL
);
Assert
(
VfdCache
!=
NULL
);
/*
/*
* Set up the free list for the new entries
* Set up the free list for the new entries
*/
*/
for
(
i
=
SizeVfdCache
;
i
<
2
*
SizeVfdCache
;
i
++
)
{
for
(
i
=
SizeVfdCache
;
i
<
2
*
SizeVfdCache
;
i
++
)
{
memset
((
char
*
)
&
(
VfdCache
[
i
]),
0
,
sizeof
(
VfdCache
[
0
]));
memset
((
char
*
)
&
(
VfdCache
[
i
]),
0
,
sizeof
(
VfdCache
[
0
]));
VfdCache
[
i
].
nextFree
=
i
+
1
;
VfdCache
[
i
].
nextFree
=
i
+
1
;
VfdCache
[
i
].
fd
=
VFD_CLOSED
;
VfdCache
[
i
].
fd
=
VFD_CLOSED
;
}
}
/*
/*
* Element 0 is the first and last element of the free
* Element 0 is the first and last element of the free
* list
* list
*/
*/
VfdCache
[
0
].
nextFree
=
SizeVfdCache
;
VfdCache
[
0
].
nextFree
=
SizeVfdCache
;
VfdCache
[
2
*
SizeVfdCache
-
1
].
nextFree
=
0
;
VfdCache
[
2
*
SizeVfdCache
-
1
].
nextFree
=
0
;
/*
/*
* Record the new size
* Record the new size
*/
*/
SizeVfdCache
*=
2
;
SizeVfdCache
*=
2
;
}
}
file
=
VfdCache
[
0
].
nextFree
;
file
=
VfdCache
[
0
].
nextFree
;
...
@@ -444,7 +450,7 @@ static void
...
@@ -444,7 +450,7 @@ static void
FreeVfd
(
File
file
)
FreeVfd
(
File
file
)
{
{
DO_DB
(
printf
(
"DB: FreeVfd: %d (%s)
\n
"
,
DO_DB
(
printf
(
"DB: FreeVfd: %d (%s)
\n
"
,
file
,
VfdCache
[
file
].
fileName
));
file
,
VfdCache
[
file
].
fileName
));
VfdCache
[
file
].
nextFree
=
VfdCache
[
0
].
nextFree
;
VfdCache
[
file
].
nextFree
=
VfdCache
[
0
].
nextFree
;
VfdCache
[
0
].
nextFree
=
file
;
VfdCache
[
0
].
nextFree
=
file
;
...
@@ -461,19 +467,19 @@ filepath(char *filename)
...
@@ -461,19 +467,19 @@ filepath(char *filename)
if
(
*
filename
!=
Sep_char
)
{
if
(
*
filename
!=
Sep_char
)
{
#else
#else
if
(
!
(
filename
[
1
]
==
':'
&&
filename
[
2
]
==
Sep_char
))
{
if
(
!
(
filename
[
1
]
==
':'
&&
filename
[
2
]
==
Sep_char
))
{
#endif
/* WIN32 */
#endif
/* WIN32 */
/* Either /base/ or \base\ */
/* Either /base/ or \base\ */
sprintf
(
basename
,
"%cbase%c"
,
Sep_char
,
Sep_char
);
sprintf
(
basename
,
"%cbase%c"
,
Sep_char
,
Sep_char
);
len
=
strlen
(
DataDir
)
+
strlen
(
basename
)
+
strlen
(
GetDatabaseName
())
len
=
strlen
(
DataDir
)
+
strlen
(
basename
)
+
strlen
(
GetDatabaseName
())
+
strlen
(
filename
)
+
2
;
+
strlen
(
filename
)
+
2
;
buf
=
(
char
*
)
palloc
(
len
);
buf
=
(
char
*
)
palloc
(
len
);
sprintf
(
buf
,
"%s%s%s%c%s"
,
sprintf
(
buf
,
"%s%s%s%c%s"
,
DataDir
,
basename
,
GetDatabaseName
(),
Sep_char
,
filename
);
DataDir
,
basename
,
GetDatabaseName
(),
Sep_char
,
filename
);
}
else
{
}
else
{
buf
=
(
char
*
)
palloc
(
strlen
(
filename
)
+
1
);
buf
=
(
char
*
)
palloc
(
strlen
(
filename
)
+
1
);
strcpy
(
buf
,
filename
);
strcpy
(
buf
,
filename
);
}
}
return
(
buf
);
return
(
buf
);
...
@@ -482,10 +488,10 @@ filepath(char *filename)
...
@@ -482,10 +488,10 @@ filepath(char *filename)
static
int
static
int
FileAccess
(
File
file
)
FileAccess
(
File
file
)
{
{
int
returnValue
;
int
returnValue
;
DO_DB
(
printf
(
"DB: FileAccess %d (%s)
\n
"
,
DO_DB
(
printf
(
"DB: FileAccess %d (%s)
\n
"
,
file
,
VfdCache
[
file
].
fileName
));
file
,
VfdCache
[
file
].
fileName
));
/*
/*
* Is the file open? If not, close the least recently used,
* Is the file open? If not, close the least recently used,
...
@@ -493,23 +499,23 @@ FileAccess(File file)
...
@@ -493,23 +499,23 @@ FileAccess(File file)
*/
*/
if
(
FileIsNotOpen
(
file
))
{
if
(
FileIsNotOpen
(
file
))
{
AssertLruRoom
();
AssertLruRoom
();
returnValue
=
LruInsert
(
file
);
returnValue
=
LruInsert
(
file
);
if
(
returnValue
!=
0
)
if
(
returnValue
!=
0
)
return
returnValue
;
return
returnValue
;
}
else
{
}
else
{
/*
/*
* We now know that the file is open and that it is not the
* We now know that the file is open and that it is not the
* last one accessed, so we need to more it to the head of
* last one accessed, so we need to more it to the head of
* the Lru ring.
* the Lru ring.
*/
*/
Delete
(
file
);
Delete
(
file
);
Insert
(
file
);
Insert
(
file
);
}
}
return
(
0
);
return
(
0
);
...
@@ -521,44 +527,45 @@ FileAccess(File file)
...
@@ -521,44 +527,45 @@ FileAccess(File file)
void
void
FileInvalidate
(
File
file
)
FileInvalidate
(
File
file
)
{
{
Assert
(
file
>
0
);
if
(
!
FileIsNotOpen
(
file
))
{
if
(
!
FileIsNotOpen
(
file
))
{
LruDelete
(
file
);
LruDelete
(
file
);
}
}
}
}
/* VARARGS2 */
/* VARARGS2 */
static
File
static
File
fileNameOpenFile
(
FileName
fileName
,
fileNameOpenFile
(
FileName
fileName
,
int
fileFlags
,
int
fileFlags
,
int
fileMode
)
int
fileMode
)
{
{
static
int
osRanOut
=
0
;
static
int
osRanOut
=
0
;
File
file
;
File
file
;
Vfd
*
vfdP
;
Vfd
*
vfdP
;
int
tmpfd
;
int
tmpfd
;
DO_DB
(
printf
(
"DEBUG: FileNameOpenFile: %s %x %o
\n
"
,
DO_DB
(
printf
(
"DEBUG: FileNameOpenFile: %s %x %o
\n
"
,
fileName
,
fileFlags
,
fileMode
));
fileName
,
fileFlags
,
fileMode
));
file
=
AllocateVfd
();
file
=
AllocateVfd
();
vfdP
=
&
VfdCache
[
file
];
vfdP
=
&
VfdCache
[
file
];
if
(
nfile
>=
MAXFILES
||
(
FreeFd
==
0
&&
osRanOut
))
{
if
(
nfile
>=
MAXFILES
||
(
FreeFd
==
0
&&
osRanOut
))
{
AssertLruRoom
();
AssertLruRoom
();
}
}
tryAgain:
tryAgain:
tmpfd
=
open
(
Nulldev
,
O_CREAT
|
O_RDWR
,
0666
);
tmpfd
=
open
(
Nulldev
,
O_CREAT
|
O_RDWR
,
0666
);
if
(
tmpfd
<
0
)
{
if
(
tmpfd
<
0
)
{
DO_DB
(
printf
(
"DB: not enough descs, retry, er= %d
\n
"
,
DO_DB
(
printf
(
"DB: not enough descs, retry, er= %d
\n
"
,
errno
));
errno
));
errno
=
0
;
errno
=
0
;
FreeFd
=
0
;
FreeFd
=
0
;
osRanOut
=
1
;
osRanOut
=
1
;
AssertLruRoom
();
AssertLruRoom
();
goto
tryAgain
;
goto
tryAgain
;
}
else
{
}
else
{
close
(
tmpfd
);
close
(
tmpfd
);
}
}
#ifdef WIN32
#ifdef WIN32
...
@@ -568,17 +575,17 @@ fileNameOpenFile(FileName fileName,
...
@@ -568,17 +575,17 @@ fileNameOpenFile(FileName fileName,
vfdP
->
fdstate
=
0x0
;
vfdP
->
fdstate
=
0x0
;
if
(
vfdP
->
fd
<
0
)
{
if
(
vfdP
->
fd
<
0
)
{
FreeVfd
(
file
);
FreeVfd
(
file
);
return
-
1
;
return
-
1
;
}
}
++
nfile
;
++
nfile
;
DO_DB
(
printf
(
"DB: FNOF success %d
\n
"
,
DO_DB
(
printf
(
"DB: FNOF success %d
\n
"
,
vfdP
->
fd
));
vfdP
->
fd
));
(
void
)
LruInsert
(
file
);
(
void
)
LruInsert
(
file
);
if
(
fileName
==
NULL
)
{
if
(
fileName
==
NULL
)
{
elog
(
WARN
,
"fileNameOpenFile: NULL fname"
);
elog
(
WARN
,
"fileNameOpenFile: NULL fname"
);
}
}
vfdP
->
fileName
=
malloc
(
strlen
(
fileName
)
+
1
);
vfdP
->
fileName
=
malloc
(
strlen
(
fileName
)
+
1
);
strcpy
(
vfdP
->
fileName
,
fileName
);
strcpy
(
vfdP
->
fileName
,
fileName
);
...
@@ -617,32 +624,32 @@ PathNameOpenFile(FileName fileName, int fileFlags, int fileMode)
...
@@ -617,32 +624,32 @@ PathNameOpenFile(FileName fileName, int fileFlags, int fileMode)
void
void
FileClose
(
File
file
)
FileClose
(
File
file
)
{
{
int
returnValue
;
int
returnValue
;
DO_DB
(
printf
(
"DEBUG: FileClose: %d (%s)
\n
"
,
DO_DB
(
printf
(
"DEBUG: FileClose: %d (%s)
\n
"
,
file
,
VfdCache
[
file
].
fileName
));
file
,
VfdCache
[
file
].
fileName
));
if
(
!
FileIsNotOpen
(
file
))
{
if
(
!
FileIsNotOpen
(
file
))
{
/* remove the file from the lru ring */
/* remove the file from the lru ring */
Delete
(
file
);
Delete
(
file
);
/* record the new free operating system file descriptor */
/* record the new free operating system file descriptor */
FreeFd
++
;
FreeFd
++
;
/* if we did any writes, sync the file before closing */
/* if we did any writes, sync the file before closing */
if
(
VfdCache
[
file
].
fdstate
&
FD_DIRTY
)
{
if
(
VfdCache
[
file
].
fdstate
&
FD_DIRTY
)
{
returnValue
=
fsync
(
VfdCache
[
file
].
fd
);
returnValue
=
fsync
(
VfdCache
[
file
].
fd
);
Assert
(
returnValue
!=
-
1
);
Assert
(
returnValue
!=
-
1
);
VfdCache
[
file
].
fdstate
&=
~
FD_DIRTY
;
VfdCache
[
file
].
fdstate
&=
~
FD_DIRTY
;
}
}
/* close the file */
/* close the file */
returnValue
=
close
(
VfdCache
[
file
].
fd
);
returnValue
=
close
(
VfdCache
[
file
].
fd
);
Assert
(
returnValue
!=
-
1
);
Assert
(
returnValue
!=
-
1
);
--
nfile
;
--
nfile
;
VfdCache
[
file
].
fd
=
VFD_CLOSED
;
VfdCache
[
file
].
fd
=
VFD_CLOSED
;
}
}
/*
/*
* Add the Vfd slot to the free list
* Add the Vfd slot to the free list
...
@@ -660,29 +667,29 @@ FileUnlink(File file)
...
@@ -660,29 +667,29 @@ FileUnlink(File file)
int
returnValue
;
int
returnValue
;
DO_DB
(
printf
(
"DB: FileClose: %d (%s)
\n
"
,
DO_DB
(
printf
(
"DB: FileClose: %d (%s)
\n
"
,
file
,
VfdCache
[
file
].
fileName
));
file
,
VfdCache
[
file
].
fileName
));
if
(
!
FileIsNotOpen
(
file
))
{
if
(
!
FileIsNotOpen
(
file
))
{
/* remove the file from the lru ring */
/* remove the file from the lru ring */
Delete
(
file
);
Delete
(
file
);
/* record the new free operating system file descriptor */
/* record the new free operating system file descriptor */
FreeFd
++
;
FreeFd
++
;
/* if we did any writes, sync the file before closing */
/* if we did any writes, sync the file before closing */
if
(
VfdCache
[
file
].
fdstate
&
FD_DIRTY
)
{
if
(
VfdCache
[
file
].
fdstate
&
FD_DIRTY
)
{
returnValue
=
fsync
(
VfdCache
[
file
].
fd
);
returnValue
=
fsync
(
VfdCache
[
file
].
fd
);
Assert
(
returnValue
!=
-
1
);
Assert
(
returnValue
!=
-
1
);
VfdCache
[
file
].
fdstate
&=
~
FD_DIRTY
;
VfdCache
[
file
].
fdstate
&=
~
FD_DIRTY
;
}
}
/* close the file */
/* close the file */
returnValue
=
close
(
VfdCache
[
file
].
fd
);
returnValue
=
close
(
VfdCache
[
file
].
fd
);
Assert
(
returnValue
!=
-
1
);
Assert
(
returnValue
!=
-
1
);
--
nfile
;
--
nfile
;
VfdCache
[
file
].
fd
=
VFD_CLOSED
;
VfdCache
[
file
].
fd
=
VFD_CLOSED
;
}
}
/* add the Vfd slot to the free list */
/* add the Vfd slot to the free list */
FreeVfd
(
file
);
FreeVfd
(
file
);
...
@@ -695,15 +702,15 @@ FileUnlink(File file)
...
@@ -695,15 +702,15 @@ FileUnlink(File file)
int
int
FileRead
(
File
file
,
char
*
buffer
,
int
amount
)
FileRead
(
File
file
,
char
*
buffer
,
int
amount
)
{
{
int
returnCode
;
int
returnCode
;
DO_DB
(
printf
(
"DEBUG: FileRead: %d (%s) %d 0x%x
\n
"
,
DO_DB
(
printf
(
"DEBUG: FileRead: %d (%s) %d 0x%x
\n
"
,
file
,
VfdCache
[
file
].
fileName
,
amount
,
buffer
));
file
,
VfdCache
[
file
].
fileName
,
amount
,
buffer
));
FileAccess
(
file
);
FileAccess
(
file
);
returnCode
=
read
(
VfdCache
[
file
].
fd
,
buffer
,
amount
);
returnCode
=
read
(
VfdCache
[
file
].
fd
,
buffer
,
amount
);
if
(
returnCode
>
0
)
{
if
(
returnCode
>
0
)
{
VfdCache
[
file
].
seekPos
+=
returnCode
;
VfdCache
[
file
].
seekPos
+=
returnCode
;
}
}
return
returnCode
;
return
returnCode
;
...
@@ -712,15 +719,15 @@ FileRead(File file, char *buffer, int amount)
...
@@ -712,15 +719,15 @@ FileRead(File file, char *buffer, int amount)
int
int
FileWrite
(
File
file
,
char
*
buffer
,
int
amount
)
FileWrite
(
File
file
,
char
*
buffer
,
int
amount
)
{
{
int
returnCode
;
int
returnCode
;
DO_DB
(
printf
(
"DB: FileWrite: %d (%s) %d 0x%lx
\n
"
,
DO_DB
(
printf
(
"DB: FileWrite: %d (%s) %d 0x%lx
\n
"
,
file
,
VfdCache
[
file
].
fileName
,
amount
,
buffer
));
file
,
VfdCache
[
file
].
fileName
,
amount
,
buffer
));
FileAccess
(
file
);
FileAccess
(
file
);
returnCode
=
write
(
VfdCache
[
file
].
fd
,
buffer
,
amount
);
returnCode
=
write
(
VfdCache
[
file
].
fd
,
buffer
,
amount
);
if
(
returnCode
>
0
)
{
/* changed by Boris with Mao's advice */
if
(
returnCode
>
0
)
{
/* changed by Boris with Mao's advice */
VfdCache
[
file
].
seekPos
+=
returnCode
;
VfdCache
[
file
].
seekPos
+=
returnCode
;
}
}
/* record the write */
/* record the write */
...
@@ -732,32 +739,32 @@ FileWrite(File file, char *buffer, int amount)
...
@@ -732,32 +739,32 @@ FileWrite(File file, char *buffer, int amount)
long
long
FileSeek
(
File
file
,
long
offset
,
int
whence
)
FileSeek
(
File
file
,
long
offset
,
int
whence
)
{
{
int
returnCode
;
int
returnCode
;
DO_DB
(
printf
(
"DEBUG: FileSeek: %d (%s) %d %d
\n
"
,
DO_DB
(
printf
(
"DEBUG: FileSeek: %d (%s) %d %d
\n
"
,
file
,
VfdCache
[
file
].
fileName
,
offset
,
whence
));
file
,
VfdCache
[
file
].
fileName
,
offset
,
whence
));
if
(
FileIsNotOpen
(
file
))
{
if
(
FileIsNotOpen
(
file
))
{
switch
(
whence
)
{
switch
(
whence
)
{
case
SEEK_SET
:
case
SEEK_SET
:
VfdCache
[
file
].
seekPos
=
offset
;
VfdCache
[
file
].
seekPos
=
offset
;
return
offset
;
return
offset
;
case
SEEK_CUR
:
case
SEEK_CUR
:
VfdCache
[
file
].
seekPos
=
VfdCache
[
file
].
seekPos
+
offset
;
VfdCache
[
file
].
seekPos
=
VfdCache
[
file
].
seekPos
+
offset
;
return
VfdCache
[
file
].
seekPos
;
return
VfdCache
[
file
].
seekPos
;
case
SEEK_END
:
case
SEEK_END
:
FileAccess
(
file
);
FileAccess
(
file
);
returnCode
=
VfdCache
[
file
].
seekPos
=
returnCode
=
VfdCache
[
file
].
seekPos
=
lseek
(
VfdCache
[
file
].
fd
,
offset
,
whence
);
lseek
(
VfdCache
[
file
].
fd
,
offset
,
whence
);
return
returnCode
;
return
returnCode
;
default:
default:
elog
(
WARN
,
"FileSeek: invalid whence: %d"
,
whence
);
elog
(
WARN
,
"FileSeek: invalid whence: %d"
,
whence
);
break
;
break
;
}
}
}
else
{
}
else
{
returnCode
=
VfdCache
[
file
].
seekPos
=
returnCode
=
VfdCache
[
file
].
seekPos
=
lseek
(
VfdCache
[
file
].
fd
,
offset
,
whence
);
lseek
(
VfdCache
[
file
].
fd
,
offset
,
whence
);
return
returnCode
;
return
returnCode
;
}
}
/*NOTREACHED*/
/*NOTREACHED*/
return
(
-
1L
);
return
(
-
1L
);
...
@@ -770,7 +777,7 @@ long
...
@@ -770,7 +777,7 @@ long
FileTell
(
File
file
)
FileTell
(
File
file
)
{
{
DO_DB
(
printf
(
"DEBUG: FileTell %d (%s)
\n
"
,
DO_DB
(
printf
(
"DEBUG: FileTell %d (%s)
\n
"
,
file
,
VfdCache
[
file
].
fileName
));
file
,
VfdCache
[
file
].
fileName
));
return
VfdCache
[
file
].
seekPos
;
return
VfdCache
[
file
].
seekPos
;
}
}
...
@@ -780,7 +787,7 @@ FileTruncate(File file, int offset)
...
@@ -780,7 +787,7 @@ FileTruncate(File file, int offset)
int
returnCode
;
int
returnCode
;
DO_DB
(
printf
(
"DEBUG: FileTruncate %d (%s)
\n
"
,
DO_DB
(
printf
(
"DEBUG: FileTruncate %d (%s)
\n
"
,
file
,
VfdCache
[
file
].
fileName
));
file
,
VfdCache
[
file
].
fileName
));
(
void
)
FileSync
(
file
);
(
void
)
FileSync
(
file
);
(
void
)
FileAccess
(
file
);
(
void
)
FileAccess
(
file
);
...
@@ -791,7 +798,7 @@ FileTruncate(File file, int offset)
...
@@ -791,7 +798,7 @@ FileTruncate(File file, int offset)
int
int
FileSync
(
File
file
)
FileSync
(
File
file
)
{
{
int
returnCode
;
int
returnCode
;
/*
/*
* If the file isn't open, then we don't need to sync it; we
* If the file isn't open, then we don't need to sync it; we
...
@@ -801,10 +808,10 @@ FileSync(File file)
...
@@ -801,10 +808,10 @@ FileSync(File file)
*/
*/
if
(
VfdCache
[
file
].
fd
<
0
||
!
(
VfdCache
[
file
].
fdstate
&
FD_DIRTY
))
{
if
(
VfdCache
[
file
].
fd
<
0
||
!
(
VfdCache
[
file
].
fdstate
&
FD_DIRTY
))
{
returnCode
=
0
;
returnCode
=
0
;
}
else
{
}
else
{
returnCode
=
fsync
(
VfdCache
[
file
].
fd
);
returnCode
=
fsync
(
VfdCache
[
file
].
fd
);
VfdCache
[
file
].
fdstate
&=
~
FD_DIRTY
;
VfdCache
[
file
].
fdstate
&=
~
FD_DIRTY
;
}
}
return
returnCode
;
return
returnCode
;
...
@@ -840,24 +847,24 @@ AllocateFile()
...
@@ -840,24 +847,24 @@ AllocateFile()
int
fdleft
;
int
fdleft
;
while
((
fd
=
open
(
Nulldev
,
O_WRONLY
,
0
))
<
0
)
{
while
((
fd
=
open
(
Nulldev
,
O_WRONLY
,
0
))
<
0
)
{
if
(
errno
==
EMFILE
)
{
if
(
errno
==
EMFILE
)
{
errno
=
0
;
errno
=
0
;
FreeFd
=
0
;
FreeFd
=
0
;
AssertLruRoom
();
AssertLruRoom
();
}
else
{
}
else
{
elog
(
WARN
,
"Open: %s in %s line %d
\n
"
,
Nulldev
,
elog
(
WARN
,
"Open: %s in %s line %d
\n
"
,
Nulldev
,
__FILE__
,
__LINE__
);
__FILE__
,
__LINE__
);
}
}
}
}
close
(
fd
);
close
(
fd
);
++
allocatedFiles
;
++
allocatedFiles
;
fdleft
=
MAXFILES
-
allocatedFiles
;
fdleft
=
MAXFILES
-
allocatedFiles
;
if
(
fdleft
<
6
)
{
if
(
fdleft
<
6
)
{
elog
(
DEBUG
,
"warning: few usable file descriptors left (%d)"
,
fdleft
);
elog
(
DEBUG
,
"warning: few usable file descriptors left (%d)"
,
fdleft
);
}
}
DO_DB
(
printf
(
"DEBUG: AllocatedFile. FreeFd = %d
\n
"
,
DO_DB
(
printf
(
"DEBUG: AllocatedFile. FreeFd = %d
\n
"
,
FreeFd
));
FreeFd
));
}
}
/*
/*
...
@@ -868,9 +875,9 @@ void
...
@@ -868,9 +875,9 @@ void
FreeFile
()
FreeFile
()
{
{
DO_DB
(
printf
(
"DEBUG: FreeFile. FreeFd now %d
\n
"
,
DO_DB
(
printf
(
"DEBUG: FreeFile. FreeFd now %d
\n
"
,
FreeFd
));
FreeFd
));
FreeFd
++
;
FreeFd
++
;
nfile
++
;
/* dangerous */
nfile
++
;
/* dangerous */
Assert
(
allocatedFiles
>
0
);
Assert
(
allocatedFiles
>
0
);
--
allocatedFiles
;
--
allocatedFiles
;
}
}
...
@@ -879,9 +886,10 @@ void
...
@@ -879,9 +886,10 @@ void
closeAllVfds
()
closeAllVfds
()
{
{
int
i
;
int
i
;
for
(
i
=
0
;
i
<
SizeVfdCache
;
i
++
)
{
Assert
(
FileIsNotOpen
(
0
));
/* Make sure ring not corrupted */
if
(
!
FileIsNotOpen
(
i
))
for
(
i
=
1
;
i
<
SizeVfdCache
;
i
++
)
{
LruDelete
(
i
);
if
(
!
FileIsNotOpen
(
i
))
LruDelete
(
i
);
}
}
}
}
...
@@ -892,10 +900,10 @@ closeOneVfd()
...
@@ -892,10 +900,10 @@ closeOneVfd()
tmpfd
=
open
(
Nulldev
,
O_CREAT
|
O_RDWR
,
0666
);
tmpfd
=
open
(
Nulldev
,
O_CREAT
|
O_RDWR
,
0666
);
if
(
tmpfd
<
0
)
{
if
(
tmpfd
<
0
)
{
FreeFd
=
0
;
FreeFd
=
0
;
AssertLruRoom
();
AssertLruRoom
();
FreeFd
=
0
;
FreeFd
=
0
;
}
}
else
else
close
(
tmpfd
);
close
(
tmpfd
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment