#include <dirent.h>
Go to the source code of this file.
Defines | |
#define | PG_TEMP_FILES_DIR "pgsql_tmp" |
#define | PG_TEMP_FILE_PREFIX "pgsql_tmp" |
Typedefs | |
typedef char * | FileName |
typedef int | File |
Functions | |
File | PathNameOpenFile (FileName fileName, int fileFlags, int fileMode) |
File | OpenTemporaryFile (bool interXact) |
void | FileClose (File file) |
int | FilePrefetch (File file, off_t offset, int amount) |
int | FileRead (File file, char *buffer, int amount) |
int | FileWrite (File file, char *buffer, int amount) |
int | FileSync (File file) |
off_t | FileSeek (File file, off_t offset, int whence) |
int | FileTruncate (File file, off_t offset) |
char * | FilePathName (File file) |
FILE * | AllocateFile (const char *name, const char *mode) |
int | FreeFile (FILE *file) |
FILE * | OpenPipeStream (const char *command, const char *mode) |
int | ClosePipeStream (FILE *file) |
DIR * | AllocateDir (const char *dirname) |
struct dirent * | ReadDir (DIR *dir, const char *dirname) |
int | FreeDir (DIR *dir) |
int | OpenTransientFile (FileName fileName, int fileFlags, int fileMode) |
int | CloseTransientFile (int fd) |
int | BasicOpenFile (FileName fileName, int fileFlags, int fileMode) |
void | InitFileAccess (void) |
void | set_max_safe_fds (void) |
void | closeAllVfds (void) |
void | SetTempTablespaces (Oid *tableSpaces, int numSpaces) |
bool | TempTablespacesAreSet (void) |
Oid | GetNextTempTableSpace (void) |
void | AtEOXact_Files (void) |
void | AtEOSubXact_Files (bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid) |
void | RemovePgTempFiles (void) |
int | pg_fsync (int fd) |
int | pg_fsync_no_writethrough (int fd) |
int | pg_fsync_writethrough (int fd) |
int | pg_fdatasync (int fd) |
int | pg_flush_data (int fd, off_t offset, off_t amount) |
Variables | |
int | max_files_per_process |
int | max_safe_fds |
#define PG_TEMP_FILE_PREFIX "pgsql_tmp" |
Definition at line 119 of file fd.h.
Referenced by OpenTemporaryFileInTablespace(), RemovePgTempFilesInDir(), and sendDir().
#define PG_TEMP_FILES_DIR "pgsql_tmp" |
Definition at line 118 of file fd.h.
Referenced by OpenTemporaryFileInTablespace(), and RemovePgTempFiles().
DIR* AllocateDir | ( | const char * | dirname | ) |
Definition at line 1747 of file fd.c.
References AllocateDesc::create_subid, AllocateDesc::desc, AllocateDesc::dir, DO_DB, elog, ereport, errcode(), errmsg(), ERROR, GetCurrentSubTransactionId(), AllocateDesc::kind, LOG, MAX_ALLOCATED_DESCS, max_safe_fds, NULL, numAllocatedDescs, opendir(), and ReleaseLruFile().
Referenced by calculate_database_size(), calculate_tablespace_size(), CleanupBackupHistory(), copydir(), db_dir_size(), DeleteAllExportedSnapshotFiles(), destroy_tablespace_directories(), directory_is_empty(), get_available_versions_for_extension(), get_ext_ver_list(), getInstallationPaths(), movedb(), ParseTzFile(), perform_base_backup(), pg_available_extension_versions(), pg_available_extensions(), pg_logdir_ls(), pg_ls_dir(), pg_tablespace_databases(), pg_tzenumerate_next(), pg_tzenumerate_start(), pgarch_readyXlog(), pgstat_reset_remove_files(), PrescanPreparedTransactions(), RecoverPreparedTransactions(), RelationCacheInitFileRemove(), RelationCacheInitFileRemoveInDir(), RemoveOldXlogFiles(), RemovePgTempFiles(), RemovePgTempFilesInDir(), RemovePgTempRelationFiles(), RemovePgTempRelationFilesInDbspace(), ResetUnloggedRelations(), ResetUnloggedRelationsInDbspaceDir(), ResetUnloggedRelationsInTablespaceDir(), scan_directory_ci(), SendBaseBackup(), sendDir(), SlruScanDirectory(), and StandbyRecoverPreparedTransactions().
{ DIR *dir; DO_DB(elog(LOG, "AllocateDir: Allocated %d (%s)", numAllocatedDescs, dirname)); /* * The test against MAX_ALLOCATED_DESCS prevents us from overflowing * allocatedDescs[]; the test against max_safe_fds prevents AllocateDir * from hogging every one of the available FDs, which'd lead to infinite * looping. */ if (numAllocatedDescs >= MAX_ALLOCATED_DESCS || numAllocatedDescs >= max_safe_fds - 1) elog(ERROR, "exceeded MAX_ALLOCATED_DESCS while trying to open directory \"%s\"", dirname); TryAgain: if ((dir = opendir(dirname)) != NULL) { AllocateDesc *desc = &allocatedDescs[numAllocatedDescs]; desc->kind = AllocateDescDir; desc->desc.dir = dir; desc->create_subid = GetCurrentSubTransactionId(); numAllocatedDescs++; return desc->desc.dir; } if (errno == EMFILE || errno == ENFILE) { int save_errno = errno; ereport(LOG, (errcode(ERRCODE_INSUFFICIENT_RESOURCES), errmsg("out of file descriptors: %m; release and retry"))); errno = 0; if (ReleaseLruFile()) goto TryAgain; errno = save_errno; } return NULL; }
FILE* AllocateFile | ( | const char * | name, | |
const char * | mode | |||
) |
Definition at line 1502 of file fd.c.
References AllocateDesc::create_subid, AllocateDesc::desc, DO_DB, elog, ereport, errcode(), errmsg(), ERROR, AllocateDesc::file, GetCurrentSubTransactionId(), AllocateDesc::kind, LOG, MAX_ALLOCATED_DESCS, max_safe_fds, NULL, numAllocatedDescs, and ReleaseLruFile().
Referenced by BeginCopyFrom(), BeginCopyTo(), checkDataDir(), do_pg_start_backup(), do_pg_stop_backup(), existsTimeLineHistory(), ExportSnapshot(), ImportSnapshot(), load_hba(), load_ident(), load_relcache_init_file(), parse_extension_control_file(), ParseTzFile(), perform_base_backup(), pg_backup_start_time(), pgss_shmem_shutdown(), pgss_shmem_startup(), pgstat_read_db_statsfile(), pgstat_read_db_statsfile_timestamp(), pgstat_read_statsfiles(), pgstat_write_db_statsfile(), pgstat_write_statsfiles(), read_backup_label(), read_binary_file(), readRecoveryCommandFile(), readTimeLineHistory(), sendFile(), tokenize_inc_file(), tsearch_readline_begin(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().
{ FILE *file; DO_DB(elog(LOG, "AllocateFile: Allocated %d (%s)", numAllocatedDescs, name)); /* * The test against MAX_ALLOCATED_DESCS prevents us from overflowing * allocatedFiles[]; the test against max_safe_fds prevents AllocateFile * from hogging every one of the available FDs, which'd lead to infinite * looping. */ if (numAllocatedDescs >= MAX_ALLOCATED_DESCS || numAllocatedDescs >= max_safe_fds - 1) elog(ERROR, "exceeded MAX_ALLOCATED_DESCS while trying to open file \"%s\"", name); TryAgain: if ((file = fopen(name, mode)) != NULL) { AllocateDesc *desc = &allocatedDescs[numAllocatedDescs]; desc->kind = AllocateDescFile; desc->desc.file = file; desc->create_subid = GetCurrentSubTransactionId(); numAllocatedDescs++; return desc->desc.file; } if (errno == EMFILE || errno == ENFILE) { int save_errno = errno; ereport(LOG, (errcode(ERRCODE_INSUFFICIENT_RESOURCES), errmsg("out of file descriptors: %m; release and retry"))); errno = 0; if (ReleaseLruFile()) goto TryAgain; errno = save_errno; } return NULL; }
void AtEOSubXact_Files | ( | bool | isCommit, | |
SubTransactionId | mySubid, | |||
SubTransactionId | parentSubid | |||
) |
Definition at line 1996 of file fd.c.
References AllocateDesc::create_subid, FreeDesc(), i, and numAllocatedDescs.
Referenced by AbortSubTransaction(), and CommitSubTransaction().
{ Index i; for (i = 0; i < numAllocatedDescs; i++) { if (allocatedDescs[i].create_subid == mySubid) { if (isCommit) allocatedDescs[i].create_subid = parentSubid; else { /* have to recheck the item after FreeDesc (ugly) */ FreeDesc(&allocatedDescs[i--]); } } } }
void AtEOXact_Files | ( | void | ) |
Definition at line 2027 of file fd.c.
References CleanupTempFiles(), numTempTableSpaces, and tempTableSpaces.
Referenced by AbortTransaction(), BackgroundWriterMain(), CheckpointerMain(), CommitTransaction(), PrepareTransaction(), and WalWriterMain().
{ CleanupTempFiles(false); tempTableSpaces = NULL; numTempTableSpaces = -1; }
int BasicOpenFile | ( | FileName | fileName, | |
int | fileFlags, | |||
int | fileMode | |||
) |
Definition at line 561 of file fd.c.
References ereport, errcode(), errmsg(), LOG, and ReleaseLruFile().
Referenced by GetNewRelFileNode(), LruInsert(), OpenTransientFile(), PathNameOpenFile(), ReadControlFile(), UpdateControlFile(), WriteControlFile(), XLogFileInit(), XLogFileOpen(), XLogFileRead(), and XLogRead().
{ int fd; tryAgain: fd = open(fileName, fileFlags, fileMode); if (fd >= 0) return fd; /* success! */ if (errno == EMFILE || errno == ENFILE) { int save_errno = errno; ereport(LOG, (errcode(ERRCODE_INSUFFICIENT_RESOURCES), errmsg("out of file descriptors: %m; release and retry"))); errno = 0; if (ReleaseLruFile()) goto tryAgain; errno = save_errno; } return -1; /* failure */ }
void closeAllVfds | ( | void | ) |
Definition at line 1909 of file fd.c.
References Assert, FileIsNotOpen, i, LruDelete(), and SizeVfdCache.
Referenced by standard_ProcessUtility().
{ Index i; if (SizeVfdCache > 0) { Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */ for (i = 1; i < SizeVfdCache; i++) { if (!FileIsNotOpen(i)) LruDelete(i); } } }
int ClosePipeStream | ( | FILE * | file | ) |
Definition at line 1880 of file fd.c.
References AllocateDescPipe, AllocateDesc::desc, DO_DB, elog, AllocateDesc::file, FreeDesc(), i, AllocateDesc::kind, LOG, numAllocatedDescs, and WARNING.
Referenced by ClosePipeToProgram().
{ int i; DO_DB(elog(LOG, "ClosePipeStream: Allocated %d", numAllocatedDescs)); /* Remove file from list of allocated files, if it's present */ for (i = numAllocatedDescs; --i >= 0;) { AllocateDesc *desc = &allocatedDescs[i]; if (desc->kind == AllocateDescPipe && desc->desc.file == file) return FreeDesc(desc); } /* Only get here if someone passes us a file not in allocatedDescs */ elog(WARNING, "file passed to ClosePipeStream was not obtained from OpenPipeStream"); return pclose(file); }
int CloseTransientFile | ( | int | fd | ) |
Definition at line 1717 of file fd.c.
References AllocateDescRawFD, close, AllocateDesc::desc, DO_DB, elog, AllocateDesc::fd, FreeDesc(), i, AllocateDesc::kind, LOG, numAllocatedDescs, and WARNING.
Referenced by CheckPointTwoPhase(), copy_file(), EndPrepare(), fsync_fname(), lo_export(), lo_import_internal(), load_relmap_file(), mdunlinkfork(), ReadTwoPhaseFile(), RecreateTwoPhaseFile(), SendTimeLineHistory(), SimpleLruFlush(), SlruInternalWritePage(), SlruPhysicalReadPage(), SlruPhysicalWritePage(), write_relmap_file(), writeTimeLineHistory(), writeTimeLineHistoryFile(), and XLogFileCopy().
{ int i; DO_DB(elog(LOG, "CloseTransientFile: Allocated %d", numAllocatedDescs)); /* Remove fd from list of allocated files, if it's present */ for (i = numAllocatedDescs; --i >= 0;) { AllocateDesc *desc = &allocatedDescs[i]; if (desc->kind == AllocateDescRawFD && desc->desc.fd == fd) return FreeDesc(desc); } /* Only get here if someone passes us a file not in allocatedDescs */ elog(WARNING, "fd passed to CloseTransientFile was not obtained from OpenTransientFile"); return close(fd); }
void FileClose | ( | File | file | ) |
Definition at line 1073 of file fd.c.
References Assert, close, Delete(), DO_DB, elog, ereport, errmsg(), ERROR, vfd::fd, FD_TEMPORARY, vfd::fdstate, FileIsNotOpen, FileIsValid, vfd::fileName, vfd::fileSize, FreeVfd(), LOG, log_temp_files, nfile, pgstat_report_tempfile(), ResourceOwnerForgetFile(), vfd::resowner, temporary_files_size, and unlink().
Referenced by BufFileClose(), CleanupTempFiles(), mdclose(), and ResourceOwnerReleaseInternal().
{ Vfd *vfdP; Assert(FileIsValid(file)); DO_DB(elog(LOG, "FileClose: %d (%s)", file, VfdCache[file].fileName)); vfdP = &VfdCache[file]; if (!FileIsNotOpen(file)) { /* remove the file from the lru ring */ Delete(file); /* close the file */ if (close(vfdP->fd)) elog(ERROR, "could not close file \"%s\": %m", vfdP->fileName); --nfile; vfdP->fd = VFD_CLOSED; } /* * Delete the file if it was temporary, and make a log entry if wanted */ if (vfdP->fdstate & FD_TEMPORARY) { struct stat filestats; int stat_errno; /* * If we get an error, as could happen within the ereport/elog calls, * we'll come right back here during transaction abort. Reset the * flag to ensure that we can't get into an infinite loop. This code * is arranged to ensure that the worst-case consequence is failing to * emit log message(s), not failing to attempt the unlink. */ vfdP->fdstate &= ~FD_TEMPORARY; /* Subtract its size from current usage (do first in case of error) */ temporary_files_size -= vfdP->fileSize; vfdP->fileSize = 0; /* first try the stat() */ if (stat(vfdP->fileName, &filestats)) stat_errno = errno; else stat_errno = 0; /* in any case do the unlink */ if (unlink(vfdP->fileName)) elog(LOG, "could not unlink file \"%s\": %m", vfdP->fileName); /* and last report the stat results */ if (stat_errno == 0) { pgstat_report_tempfile(filestats.st_size); if (log_temp_files >= 0) { if ((filestats.st_size / 1024) >= log_temp_files) ereport(LOG, (errmsg("temporary file: path \"%s\", size %lu", vfdP->fileName, (unsigned long) filestats.st_size))); } } else { errno = stat_errno; elog(LOG, "could not stat file \"%s\": %m", vfdP->fileName); } } /* Unregister it from the resource owner */ if (vfdP->resowner) ResourceOwnerForgetFile(vfdP->resowner, file); /* * Return the Vfd slot to the free list */ FreeVfd(file); }
char* FilePathName | ( | File | file | ) |
Definition at line 1476 of file fd.c.
References Assert, FileIsValid, and vfd::fileName.
Referenced by _mdnblocks(), mdextend(), mdimmedsync(), mdread(), mdsync(), mdtruncate(), mdwrite(), and register_dirty_segment().
{ Assert(FileIsValid(file)); return VfdCache[file].fileName; }
int FilePrefetch | ( | File | file, | |
off_t | offset, | |||
int | amount | |||
) |
Definition at line 1170 of file fd.c.
References Assert, DO_DB, elog, fd(), FileAccess(), FileIsValid, and LOG.
Referenced by mdprefetch().
{ #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED) int returnCode; Assert(FileIsValid(file)); DO_DB(elog(LOG, "FilePrefetch: %d (%s) " INT64_FORMAT " %d", file, VfdCache[file].fileName, (int64) offset, amount)); returnCode = FileAccess(file); if (returnCode < 0) return returnCode; returnCode = posix_fadvise(VfdCache[file].fd, offset, amount, POSIX_FADV_WILLNEED); return returnCode; #else Assert(FileIsValid(file)); return 0; #endif }
int FileRead | ( | File | file, | |
char * | buffer, | |||
int | amount | |||
) |
Definition at line 1196 of file fd.c.
References _dosmaperr(), Assert, DO_DB, EINTR, elog, error(), fd(), FileAccess(), FileIsValid, LOG, pg_usleep(), read, and vfd::seekPos.
Referenced by BufFileLoadBuffer(), and mdread().
{ int returnCode; Assert(FileIsValid(file)); DO_DB(elog(LOG, "FileRead: %d (%s) " INT64_FORMAT " %d %p", file, VfdCache[file].fileName, (int64) VfdCache[file].seekPos, amount, buffer)); returnCode = FileAccess(file); if (returnCode < 0) return returnCode; retry: returnCode = read(VfdCache[file].fd, buffer, amount); if (returnCode >= 0) VfdCache[file].seekPos += returnCode; else { /* * Windows may run out of kernel buffers and return "Insufficient * system resources" error. Wait a bit and retry to solve it. * * It is rumored that EINTR is also possible on some Unix filesystems, * in which case immediate retry is indicated. */ #ifdef WIN32 DWORD error = GetLastError(); switch (error) { case ERROR_NO_SYSTEM_RESOURCES: pg_usleep(1000L); errno = EINTR; break; default: _dosmaperr(error); break; } #endif /* OK to retry if interrupted */ if (errno == EINTR) goto retry; /* Trouble, so assume we don't know the file position anymore */ VfdCache[file].seekPos = FileUnknownPos; } return returnCode; }
off_t FileSeek | ( | File | file, | |
off_t | offset, | |||
int | whence | |||
) |
Definition at line 1363 of file fd.c.
References Assert, DO_DB, elog, ERROR, fd(), FileAccess(), FileIsNotOpen, FileIsValid, FileUnknownPos, LOG, and vfd::seekPos.
Referenced by _mdnblocks(), BufFileDumpBuffer(), BufFileLoadBuffer(), mdextend(), mdread(), and mdwrite().
{ int returnCode; Assert(FileIsValid(file)); DO_DB(elog(LOG, "FileSeek: %d (%s) " INT64_FORMAT " " INT64_FORMAT " %d", file, VfdCache[file].fileName, (int64) VfdCache[file].seekPos, (int64) offset, whence)); if (FileIsNotOpen(file)) { switch (whence) { case SEEK_SET: if (offset < 0) elog(ERROR, "invalid seek offset: " INT64_FORMAT, (int64) offset); VfdCache[file].seekPos = offset; break; case SEEK_CUR: VfdCache[file].seekPos += offset; break; case SEEK_END: returnCode = FileAccess(file); if (returnCode < 0) return returnCode; VfdCache[file].seekPos = lseek(VfdCache[file].fd, offset, whence); break; default: elog(ERROR, "invalid whence: %d", whence); break; } } else { switch (whence) { case SEEK_SET: if (offset < 0) elog(ERROR, "invalid seek offset: " INT64_FORMAT, (int64) offset); if (VfdCache[file].seekPos != offset) VfdCache[file].seekPos = lseek(VfdCache[file].fd, offset, whence); break; case SEEK_CUR: if (offset != 0 || VfdCache[file].seekPos == FileUnknownPos) VfdCache[file].seekPos = lseek(VfdCache[file].fd, offset, whence); break; case SEEK_END: VfdCache[file].seekPos = lseek(VfdCache[file].fd, offset, whence); break; default: elog(ERROR, "invalid whence: %d", whence); break; } } return VfdCache[file].seekPos; }
int FileSync | ( | File | file | ) |
Definition at line 1346 of file fd.c.
References Assert, DO_DB, elog, fd(), FileAccess(), FileIsValid, LOG, and pg_fsync().
Referenced by mdimmedsync(), mdsync(), and register_dirty_segment().
{ int returnCode; Assert(FileIsValid(file)); DO_DB(elog(LOG, "FileSync: %d (%s)", file, VfdCache[file].fileName)); returnCode = FileAccess(file); if (returnCode < 0) return returnCode; return pg_fsync(VfdCache[file].fd); }
int FileTruncate | ( | File | file, | |
off_t | offset | |||
) |
Definition at line 1443 of file fd.c.
References Assert, DO_DB, elog, fd(), FD_TEMPORARY, FileAccess(), FileIsValid, vfd::fileSize, ftruncate, LOG, and temporary_files_size.
Referenced by mdtruncate().
{ int returnCode; Assert(FileIsValid(file)); DO_DB(elog(LOG, "FileTruncate %d (%s)", file, VfdCache[file].fileName)); returnCode = FileAccess(file); if (returnCode < 0) return returnCode; returnCode = ftruncate(VfdCache[file].fd, offset); if (returnCode == 0 && VfdCache[file].fileSize > offset) { /* adjust our state for truncation of a temp file */ Assert(VfdCache[file].fdstate & FD_TEMPORARY); temporary_files_size -= VfdCache[file].fileSize - offset; VfdCache[file].fileSize = offset; } return returnCode; }
int FileWrite | ( | File | file, | |
char * | buffer, | |||
int | amount | |||
) |
Definition at line 1251 of file fd.c.
References _dosmaperr(), Assert, DO_DB, EINTR, elog, ereport, errcode(), errmsg(), error(), ERROR, fd(), FD_TEMPORARY, FileAccess(), FileIsValid, vfd::fileSize, LOG, pg_usleep(), vfd::seekPos, temp_file_limit, temporary_files_size, and write.
Referenced by BufFileDumpBuffer(), mdextend(), and mdwrite().
{ int returnCode; Assert(FileIsValid(file)); DO_DB(elog(LOG, "FileWrite: %d (%s) " INT64_FORMAT " %d %p", file, VfdCache[file].fileName, (int64) VfdCache[file].seekPos, amount, buffer)); returnCode = FileAccess(file); if (returnCode < 0) return returnCode; /* * If enforcing temp_file_limit and it's a temp file, check to see if the * write would overrun temp_file_limit, and throw error if so. Note: it's * really a modularity violation to throw error here; we should set errno * and return -1. However, there's no way to report a suitable error * message if we do that. All current callers would just throw error * immediately anyway, so this is safe at present. */ if (temp_file_limit >= 0 && (VfdCache[file].fdstate & FD_TEMPORARY)) { off_t newPos = VfdCache[file].seekPos + amount; if (newPos > VfdCache[file].fileSize) { uint64 newTotal = temporary_files_size; newTotal += newPos - VfdCache[file].fileSize; if (newTotal > (uint64) temp_file_limit * (uint64) 1024) ereport(ERROR, (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED), errmsg("temporary file size exceeds temp_file_limit (%dkB)", temp_file_limit))); } } retry: errno = 0; returnCode = write(VfdCache[file].fd, buffer, amount); /* if write didn't set errno, assume problem is no disk space */ if (returnCode != amount && errno == 0) errno = ENOSPC; if (returnCode >= 0) { VfdCache[file].seekPos += returnCode; /* maintain fileSize and temporary_files_size if it's a temp file */ if (VfdCache[file].fdstate & FD_TEMPORARY) { off_t newPos = VfdCache[file].seekPos; if (newPos > VfdCache[file].fileSize) { temporary_files_size += newPos - VfdCache[file].fileSize; VfdCache[file].fileSize = newPos; } } } else { /* * See comments in FileRead() */ #ifdef WIN32 DWORD error = GetLastError(); switch (error) { case ERROR_NO_SYSTEM_RESOURCES: pg_usleep(1000L); errno = EINTR; break; default: _dosmaperr(error); break; } #endif /* OK to retry if interrupted */ if (errno == EINTR) goto retry; /* Trouble, so assume we don't know the file position anymore */ VfdCache[file].seekPos = FileUnknownPos; } return returnCode; }
int FreeDir | ( | DIR * | dir | ) |
Definition at line 1854 of file fd.c.
References AllocateDescDir, closedir(), AllocateDesc::desc, AllocateDesc::dir, DO_DB, elog, FreeDesc(), i, AllocateDesc::kind, LOG, numAllocatedDescs, and WARNING.
Referenced by calculate_database_size(), calculate_tablespace_size(), CleanupBackupHistory(), copydir(), db_dir_size(), DeleteAllExportedSnapshotFiles(), destroy_tablespace_directories(), directory_is_empty(), get_available_versions_for_extension(), get_ext_ver_list(), getInstallationPaths(), movedb(), ParseTzFile(), perform_base_backup(), pg_available_extension_versions(), pg_available_extensions(), pg_logdir_ls(), pg_ls_dir(), pg_tablespace_databases(), pg_tzenumerate_end(), pg_tzenumerate_next(), pgarch_readyXlog(), pgstat_reset_remove_files(), PrescanPreparedTransactions(), RecoverPreparedTransactions(), RelationCacheInitFileRemove(), RelationCacheInitFileRemoveInDir(), RemoveOldXlogFiles(), RemovePgTempFiles(), RemovePgTempFilesInDir(), RemovePgTempRelationFiles(), RemovePgTempRelationFilesInDbspace(), ResetUnloggedRelations(), ResetUnloggedRelationsInDbspaceDir(), ResetUnloggedRelationsInTablespaceDir(), scan_directory_ci(), SendBaseBackup(), sendDir(), SlruScanDirectory(), and StandbyRecoverPreparedTransactions().
{ int i; DO_DB(elog(LOG, "FreeDir: Allocated %d", numAllocatedDescs)); /* Remove dir from list of allocated dirs, if it's present */ for (i = numAllocatedDescs; --i >= 0;) { AllocateDesc *desc = &allocatedDescs[i]; if (desc->kind == AllocateDescDir && desc->desc.dir == dir) return FreeDesc(desc); } /* Only get here if someone passes us a dir not in allocatedDescs */ elog(WARNING, "dir passed to FreeDir was not obtained from AllocateDir"); return closedir(dir); }
int FreeFile | ( | FILE * | file | ) |
Definition at line 1689 of file fd.c.
References AllocateDescFile, AllocateDesc::desc, DO_DB, elog, AllocateDesc::file, FreeDesc(), i, AllocateDesc::kind, LOG, numAllocatedDescs, and WARNING.
Referenced by checkDataDir(), do_pg_start_backup(), do_pg_stop_backup(), EndCopy(), existsTimeLineHistory(), ExportSnapshot(), ImportSnapshot(), load_hba(), load_ident(), load_relcache_init_file(), parse_extension_control_file(), ParseTzFile(), perform_base_backup(), pg_backup_start_time(), pgss_shmem_shutdown(), pgss_shmem_startup(), pgstat_read_db_statsfile(), pgstat_read_db_statsfile_timestamp(), pgstat_read_statsfiles(), pgstat_write_db_statsfile(), pgstat_write_statsfiles(), read_backup_label(), read_binary_file(), readRecoveryCommandFile(), readTimeLineHistory(), sendFile(), tokenize_inc_file(), tsearch_readline_end(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().
{ int i; DO_DB(elog(LOG, "FreeFile: Allocated %d", numAllocatedDescs)); /* Remove file from list of allocated files, if it's present */ for (i = numAllocatedDescs; --i >= 0;) { AllocateDesc *desc = &allocatedDescs[i]; if (desc->kind == AllocateDescFile && desc->desc.file == file) return FreeDesc(desc); } /* Only get here if someone passes us a file not in allocatedDescs */ elog(WARNING, "file passed to FreeFile was not obtained from AllocateFile"); return fclose(file); }
Oid GetNextTempTableSpace | ( | void | ) |
Definition at line 1975 of file fd.c.
References nextTempTableSpace, numTempTableSpaces, and tempTableSpaces.
Referenced by GetDefaultTablespace(), and OpenTemporaryFile().
{ if (numTempTableSpaces > 0) { /* Advance nextTempTableSpace counter with wraparound */ if (++nextTempTableSpace >= numTempTableSpaces) nextTempTableSpace = 0; return tempTableSpaces[nextTempTableSpace]; } return InvalidOid; }
void InitFileAccess | ( | void | ) |
Definition at line 389 of file fd.c.
References Assert, AtProcExit_Files(), ereport, errcode(), errmsg(), FATAL, vfd::fd, malloc, MemSet, NULL, on_proc_exit(), and SizeVfdCache.
Referenced by BaseInit().
{ Assert(SizeVfdCache == 0); /* call me only once */ /* initialize cache header entry */ VfdCache = (Vfd *) malloc(sizeof(Vfd)); if (VfdCache == NULL) ereport(FATAL, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"))); MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd)); VfdCache->fd = VFD_CLOSED; SizeVfdCache = 1; /* register proc-exit hook to ensure temp files are dropped at exit */ on_proc_exit(AtProcExit_Files, 0); }
FILE* OpenPipeStream | ( | const char * | command, | |
const char * | mode | |||
) |
Definition at line 1595 of file fd.c.
References AllocateDesc::create_subid, AllocateDesc::desc, DO_DB, elog, ereport, errcode(), errmsg(), ERROR, AllocateDesc::file, GetCurrentSubTransactionId(), AllocateDesc::kind, LOG, MAX_ALLOCATED_DESCS, max_safe_fds, NULL, numAllocatedDescs, and ReleaseLruFile().
Referenced by BeginCopyFrom(), and BeginCopyTo().
{ FILE *file; DO_DB(elog(LOG, "OpenPipeStream: Allocated %d (%s)", numAllocatedDescs, command)); /* * The test against MAX_ALLOCATED_DESCS prevents us from overflowing * allocatedFiles[]; the test against max_safe_fds prevents AllocateFile * from hogging every one of the available FDs, which'd lead to infinite * looping. */ if (numAllocatedDescs >= MAX_ALLOCATED_DESCS || numAllocatedDescs >= max_safe_fds - 1) elog(ERROR, "exceeded MAX_ALLOCATED_DESCS while trying to execute command \"%s\"", command); TryAgain: fflush(stdout); fflush(stderr); errno = 0; if ((file = popen(command, mode)) != NULL) { AllocateDesc *desc = &allocatedDescs[numAllocatedDescs]; desc->kind = AllocateDescPipe; desc->desc.file = file; desc->create_subid = GetCurrentSubTransactionId(); numAllocatedDescs++; return desc->desc.file; } if (errno == EMFILE || errno == ENFILE) { int save_errno = errno; ereport(LOG, (errcode(ERRCODE_INSUFFICIENT_RESOURCES), errmsg("out of file descriptors: %m; release and retry"))); errno = 0; if (ReleaseLruFile()) goto TryAgain; errno = save_errno; } return NULL; }
Definition at line 951 of file fd.c.
References CurrentResourceOwner, DEFAULTTABLESPACE_OID, vfd::fdstate, GetNextTempTableSpace(), have_xact_temporary_files, MyDatabaseTableSpace, numTempTableSpaces, OidIsValid, OpenTemporaryFileInTablespace(), ResourceOwnerEnlargeFiles(), ResourceOwnerRememberFile(), and vfd::resowner.
Referenced by BufFileCreateTemp(), and extendBufFile().
{ File file = 0; /* * If some temp tablespace(s) have been given to us, try to use the next * one. If a given tablespace can't be found, we silently fall back to * the database's default tablespace. * * BUT: if the temp file is slated to outlive the current transaction, * force it into the database's default tablespace, so that it will not * pose a threat to possible tablespace drop attempts. */ if (numTempTableSpaces > 0 && !interXact) { Oid tblspcOid = GetNextTempTableSpace(); if (OidIsValid(tblspcOid)) file = OpenTemporaryFileInTablespace(tblspcOid, false); } /* * If not, or if tablespace is bad, create in database's default * tablespace. MyDatabaseTableSpace should normally be set before we get * here, but just in case it isn't, fall back to pg_default tablespace. */ if (file <= 0) file = OpenTemporaryFileInTablespace(MyDatabaseTableSpace ? MyDatabaseTableSpace : DEFAULTTABLESPACE_OID, true); /* Mark it for deletion at close */ VfdCache[file].fdstate |= FD_TEMPORARY; /* Register it with the current resource owner */ if (!interXact) { VfdCache[file].fdstate |= FD_XACT_TEMPORARY; ResourceOwnerEnlargeFiles(CurrentResourceOwner); ResourceOwnerRememberFile(CurrentResourceOwner, file); VfdCache[file].resowner = CurrentResourceOwner; /* ensure cleanup happens at eoxact */ have_xact_temporary_files = true; } return file; }
int OpenTransientFile | ( | FileName | fileName, | |
int | fileFlags, | |||
int | fileMode | |||
) |
Definition at line 1553 of file fd.c.
References BasicOpenFile(), AllocateDesc::create_subid, AllocateDesc::desc, DO_DB, elog, ERROR, AllocateDesc::fd, GetCurrentSubTransactionId(), AllocateDesc::kind, LOG, MAX_ALLOCATED_DESCS, max_safe_fds, and numAllocatedDescs.
Referenced by CheckPointTwoPhase(), copy_file(), EndPrepare(), fsync_fname(), lo_export(), lo_import_internal(), load_relmap_file(), mdunlinkfork(), ReadTwoPhaseFile(), RecreateTwoPhaseFile(), SendTimeLineHistory(), SlruPhysicalReadPage(), SlruPhysicalWritePage(), write_relmap_file(), writeTimeLineHistory(), writeTimeLineHistoryFile(), and XLogFileCopy().
{ int fd; DO_DB(elog(LOG, "OpenTransientFile: Allocated %d (%s)", numAllocatedDescs, fileName)); /* * The test against MAX_ALLOCATED_DESCS prevents us from overflowing * allocatedFiles[]; the test against max_safe_fds prevents BasicOpenFile * from hogging every one of the available FDs, which'd lead to infinite * looping. */ if (numAllocatedDescs >= MAX_ALLOCATED_DESCS || numAllocatedDescs >= max_safe_fds - 1) elog(ERROR, "exceeded MAX_ALLOCATED_DESCS while trying to open file \"%s\"", fileName); fd = BasicOpenFile(fileName, fileFlags, fileMode); if (fd >= 0) { AllocateDesc *desc = &allocatedDescs[numAllocatedDescs]; desc->kind = AllocateDescRawFD; desc->desc.fd = fd; desc->create_subid = GetCurrentSubTransactionId(); numAllocatedDescs++; return fd; } return -1; /* failure */ }
Definition at line 883 of file fd.c.
References AllocateVfd(), BasicOpenFile(), DO_DB, elog, ereport, errcode(), errmsg(), ERROR, vfd::fd, vfd::fdstate, vfd::fileFlags, vfd::fileMode, vfd::fileName, vfd::fileSize, free, FreeVfd(), Insert(), LOG, max_safe_fds, nfile, NULL, numAllocatedDescs, ReleaseLruFile(), vfd::resowner, and vfd::seekPos.
Referenced by _mdfd_openseg(), mdcreate(), mdopen(), and OpenTemporaryFileInTablespace().
{ char *fnamecopy; File file; Vfd *vfdP; DO_DB(elog(LOG, "PathNameOpenFile: %s %x %o", fileName, fileFlags, fileMode)); /* * We need a malloc'd copy of the file name; fail cleanly if no room. */ fnamecopy = strdup(fileName); if (fnamecopy == NULL) ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"))); file = AllocateVfd(); vfdP = &VfdCache[file]; while (nfile + numAllocatedDescs >= max_safe_fds) { if (!ReleaseLruFile()) break; } vfdP->fd = BasicOpenFile(fileName, fileFlags, fileMode); if (vfdP->fd < 0) { FreeVfd(file); free(fnamecopy); return -1; } ++nfile; DO_DB(elog(LOG, "PathNameOpenFile: success %d", vfdP->fd)); Insert(file); vfdP->fileName = fnamecopy; /* Saved flags are adjusted to be OK for re-opening file */ vfdP->fileFlags = fileFlags & ~(O_CREAT | O_TRUNC | O_EXCL); vfdP->fileMode = fileMode; vfdP->seekPos = 0; vfdP->fileSize = 0; vfdP->fdstate = 0x0; vfdP->resowner = NULL; return file; }
int pg_fdatasync | ( | int | fd | ) |
Definition at line 345 of file fd.c.
References enableFsync, and fsync.
Referenced by issue_xlog_fsync().
{ if (enableFsync) { #ifdef HAVE_FDATASYNC return fdatasync(fd); #else return fsync(fd); #endif } else return 0; }
int pg_flush_data | ( | int | fd, | |
off_t | offset, | |||
off_t | amount | |||
) |
Definition at line 368 of file fd.c.
References enableFsync.
Referenced by copy_file().
{ if (enableFsync) { #if defined(HAVE_SYNC_FILE_RANGE) return sync_file_range(fd, offset, amount, SYNC_FILE_RANGE_WRITE); #elif defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED) return posix_fadvise(fd, offset, amount, POSIX_FADV_DONTNEED); #endif } return 0; }
int pg_fsync | ( | int | fd | ) |
Definition at line 293 of file fd.c.
References pg_fsync_no_writethrough(), pg_fsync_writethrough(), sync_method, and SYNC_METHOD_FSYNC_WRITETHROUGH.
Referenced by AddToDataDirLockFile(), assign_xlog_sync_method(), BootStrapXLOG(), CheckPointTwoPhase(), CreateLockFile(), do_pg_start_backup(), FileSync(), fsync_fname(), RecreateTwoPhaseFile(), SimpleLruFlush(), SlruPhysicalWritePage(), UpdateControlFile(), write_relmap_file(), WriteControlFile(), writeTimeLineHistory(), writeTimeLineHistoryFile(), XLogFileCopy(), and XLogFileInit().
{ /* #if is to skip the sync_method test if there's no need for it */ #if defined(HAVE_FSYNC_WRITETHROUGH) && !defined(FSYNC_WRITETHROUGH_IS_FSYNC) if (sync_method == SYNC_METHOD_FSYNC_WRITETHROUGH) return pg_fsync_writethrough(fd); else #endif return pg_fsync_no_writethrough(fd); }
int pg_fsync_no_writethrough | ( | int | fd | ) |
Definition at line 310 of file fd.c.
References enableFsync, and fsync.
Referenced by issue_xlog_fsync(), and pg_fsync().
{ if (enableFsync) return fsync(fd); else return 0; }
int pg_fsync_writethrough | ( | int | fd | ) |
Definition at line 322 of file fd.c.
References enableFsync.
Referenced by issue_xlog_fsync(), pg_fsync(), and test_sync().
{ if (enableFsync) { #ifdef WIN32 return _commit(fd); #elif defined(F_FULLFSYNC) return (fcntl(fd, F_FULLFSYNC, 0) == -1) ? -1 : 0; #else errno = ENOSYS; return -1; #endif } else return 0; }
Definition at line 1814 of file fd.c.
References ereport, errcode_for_file_access(), errmsg(), ERROR, NULL, and readdir().
Referenced by calculate_database_size(), calculate_tablespace_size(), CleanupBackupHistory(), copydir(), db_dir_size(), DeleteAllExportedSnapshotFiles(), destroy_tablespace_directories(), directory_is_empty(), get_available_versions_for_extension(), get_ext_ver_list(), movedb(), perform_base_backup(), pg_available_extension_versions(), pg_available_extensions(), pg_logdir_ls(), pg_ls_dir(), pg_tablespace_databases(), pg_tzenumerate_next(), pgarch_readyXlog(), pgstat_reset_remove_files(), PrescanPreparedTransactions(), RecoverPreparedTransactions(), RelationCacheInitFileRemove(), RelationCacheInitFileRemoveInDir(), RemoveOldXlogFiles(), RemovePgTempFiles(), RemovePgTempFilesInDir(), RemovePgTempRelationFiles(), RemovePgTempRelationFilesInDbspace(), ResetUnloggedRelations(), ResetUnloggedRelationsInDbspaceDir(), ResetUnloggedRelationsInTablespaceDir(), scan_directory_ci(), sendDir(), SlruScanDirectory(), and StandbyRecoverPreparedTransactions().
{ struct dirent *dent; /* Give a generic message for AllocateDir failure, if caller didn't */ if (dir == NULL) ereport(ERROR, (errcode_for_file_access(), errmsg("could not open directory \"%s\": %m", dirname))); errno = 0; if ((dent = readdir(dir)) != NULL) return dent; #ifdef WIN32 /* * This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in * released version */ if (GetLastError() == ERROR_NO_MORE_FILES) errno = 0; #endif if (errno) ereport(ERROR, (errcode_for_file_access(), errmsg("could not read directory \"%s\": %m", dirname))); return NULL; }
void RemovePgTempFiles | ( | void | ) |
Definition at line 2116 of file fd.c.
References AllocateDir(), dirent::d_name, FreeDir(), NULL, PG_TEMP_FILES_DIR, ReadDir(), RemovePgTempFilesInDir(), RemovePgTempRelationFiles(), snprintf(), and TABLESPACE_VERSION_DIRECTORY.
Referenced by PostmasterMain().
{ char temp_path[MAXPGPATH]; DIR *spc_dir; struct dirent *spc_de; /* * First process temp files in pg_default ($PGDATA/base) */ snprintf(temp_path, sizeof(temp_path), "base/%s", PG_TEMP_FILES_DIR); RemovePgTempFilesInDir(temp_path); RemovePgTempRelationFiles("base"); /* * Cycle through temp directories for all non-default tablespaces. */ spc_dir = AllocateDir("pg_tblspc"); while ((spc_de = ReadDir(spc_dir, "pg_tblspc")) != NULL) { if (strcmp(spc_de->d_name, ".") == 0 || strcmp(spc_de->d_name, "..") == 0) continue; snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s/%s", spc_de->d_name, TABLESPACE_VERSION_DIRECTORY, PG_TEMP_FILES_DIR); RemovePgTempFilesInDir(temp_path); snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s", spc_de->d_name, TABLESPACE_VERSION_DIRECTORY); RemovePgTempRelationFiles(temp_path); } FreeDir(spc_dir); /* * In EXEC_BACKEND case there is a pgsql_tmp directory at the top level of * DataDir as well. */ #ifdef EXEC_BACKEND RemovePgTempFilesInDir(PG_TEMP_FILES_DIR); #endif }
void set_max_safe_fds | ( | void | ) |
Definition at line 506 of file fd.c.
References count_usable_fds(), DEBUG2, elog, ereport, errcode(), errdetail(), errmsg(), FATAL, FD_MINFREE, max_files_per_process, max_safe_fds, Min, and NUM_RESERVED_FDS.
Referenced by PostmasterMain().
{ int usable_fds; int already_open; /*---------- * We want to set max_safe_fds to * MIN(usable_fds, max_files_per_process - already_open) * less the slop factor for files that are opened without consulting * fd.c. This ensures that we won't exceed either max_files_per_process * or the experimentally-determined EMFILE limit. *---------- */ count_usable_fds(max_files_per_process, &usable_fds, &already_open); max_safe_fds = Min(usable_fds, max_files_per_process - already_open); /* * Take off the FDs reserved for system() etc. */ max_safe_fds -= NUM_RESERVED_FDS; /* * Make sure we still have enough to get by. */ if (max_safe_fds < FD_MINFREE) ereport(FATAL, (errcode(ERRCODE_INSUFFICIENT_RESOURCES), errmsg("insufficient file descriptors available to start server process"), errdetail("System allows %d, we need at least %d.", max_safe_fds + NUM_RESERVED_FDS, FD_MINFREE + NUM_RESERVED_FDS))); elog(DEBUG2, "max_safe_fds = %d, usable_fds = %d, already_open = %d", max_safe_fds, usable_fds, already_open); }
void SetTempTablespaces | ( | Oid * | tableSpaces, | |
int | numSpaces | |||
) |
Definition at line 1935 of file fd.c.
References Assert, nextTempTableSpace, numTempTableSpaces, random(), and tempTableSpaces.
Referenced by assign_temp_tablespaces(), and PrepareTempTablespaces().
{ Assert(numSpaces >= 0); tempTableSpaces = tableSpaces; numTempTableSpaces = numSpaces; /* * Select a random starting point in the list. This is to minimize * conflicts between backends that are most likely sharing the same list * of temp tablespaces. Note that if we create multiple temp files in the * same transaction, we'll advance circularly through the list --- this * ensures that large temporary sort files are nicely spread across all * available tablespaces. */ if (numSpaces > 1) nextTempTableSpace = random() % numSpaces; else nextTempTableSpace = 0; }
bool TempTablespacesAreSet | ( | void | ) |
Definition at line 1963 of file fd.c.
References numTempTableSpaces.
Referenced by PrepareTempTablespaces().
{ return (numTempTableSpaces >= 0); }
Definition at line 112 of file fd.c.
Referenced by set_max_safe_fds().
int max_safe_fds |
Definition at line 125 of file fd.c.
Referenced by AllocateDir(), AllocateFile(), LruInsert(), OpenPipeStream(), OpenTransientFile(), PathNameOpenFile(), and set_max_safe_fds().