PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
fd.h File Reference
#include <dirent.h>
Include dependency graph for fd.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#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, uint32 wait_event_info)
 
int FileRead (File file, char *buffer, int amount, uint32 wait_event_info)
 
int FileWrite (File file, char *buffer, int amount, uint32 wait_event_info)
 
int FileSync (File file, uint32 wait_event_info)
 
off_t FileSeek (File file, off_t offset, int whence)
 
int FileTruncate (File file, off_t offset, uint32 wait_event_info)
 
void FileWriteback (File file, off_t offset, off_t nbytes, uint32 wait_event_info)
 
char * FilePathName (File file)
 
int FileGetRawDesc (File file)
 
int FileGetRawFlags (File file)
 
int FileGetRawMode (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)
 
DIRAllocateDir (const char *dirname)
 
struct direntReadDir (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)
 
void pg_flush_data (int fd, off_t offset, off_t amount)
 
void fsync_fname (const char *fname, bool isdir)
 
int durable_rename (const char *oldfile, const char *newfile, int loglevel)
 
int durable_unlink (const char *fname, int loglevel)
 
int durable_link_or_rename (const char *oldfile, const char *newfile, int loglevel)
 
void SyncDataDirectory (void)
 

Variables

int max_files_per_process
 
int max_safe_fds
 

Macro Definition Documentation

#define PG_TEMP_FILE_PREFIX   "pgsql_tmp"
#define PG_TEMP_FILES_DIR   "pgsql_tmp"

Definition at line 127 of file fd.h.

Referenced by OpenTemporaryFileInTablespace(), process_source_file(), and RemovePgTempFiles().

Typedef Documentation

Definition at line 51 of file fd.h.

Definition at line 49 of file fd.h.

Function Documentation

DIR* AllocateDir ( const char *  dirname)

Definition at line 2335 of file fd.c.

References AllocateDescDir, AllocateDesc::create_subid, AllocateDesc::desc, AllocateDesc::dir, DO_DB, elog, ereport, errcode(), errmsg(), ERROR, GetCurrentSubTransactionId(), AllocateDesc::kind, LOG, maxAllocatedDescs, NULL, numAllocatedDescs, opendir(), ReleaseLruFile(), ReleaseLruFiles(), and reserveAllocatedDesc().

Referenced by calculate_database_size(), calculate_tablespace_size(), CheckPointLogicalRewriteHeap(), CheckPointSnapBuild(), CleanupBackupHistory(), copydir(), db_dir_size(), DeleteAllExportedSnapshotFiles(), destroy_tablespace_directories(), directory_is_empty(), dsm_cleanup_for_mmap(), get_ext_ver_list(), getInstallationPaths(), movedb(), ParseTzFile(), perform_base_backup(), pg_available_extension_versions(), pg_available_extensions(), pg_logdir_ls(), pg_ls_dir(), pg_ls_dir_files(), pg_start_backup(), pg_tablespace_databases(), pg_tzenumerate_next(), pg_tzenumerate_start(), pgarch_readyXlog(), pgstat_reset_remove_files(), RelationCacheInitFileRemove(), RelationCacheInitFileRemoveInDir(), RemoveNonParentXlogFiles(), RemoveOldXlogFiles(), RemovePgTempFiles(), RemovePgTempFilesInDir(), RemovePgTempRelationFiles(), RemovePgTempRelationFilesInDbspace(), ResetUnloggedRelations(), ResetUnloggedRelationsInDbspaceDir(), ResetUnloggedRelationsInTablespaceDir(), restoreTwoPhaseData(), scan_directory_ci(), SendBaseBackup(), sendDir(), SlruScanDirectory(), StartupReorderBuffer(), StartupReplicationSlots(), UpdateLogicalMappings(), and walkdir().

2336 {
2337  DIR *dir;
2338 
2339  DO_DB(elog(LOG, "AllocateDir: Allocated %d (%s)",
2340  numAllocatedDescs, dirname));
2341 
2342  /* Can we allocate another non-virtual FD? */
2343  if (!reserveAllocatedDesc())
2344  ereport(ERROR,
2345  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2346  errmsg("exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"",
2347  maxAllocatedDescs, dirname)));
2348 
2349  /* Close excess kernel FDs. */
2350  ReleaseLruFiles();
2351 
2352 TryAgain:
2353  if ((dir = opendir(dirname)) != NULL)
2354  {
2356 
2357  desc->kind = AllocateDescDir;
2358  desc->desc.dir = dir;
2361  return desc->desc.dir;
2362  }
2363 
2364  if (errno == EMFILE || errno == ENFILE)
2365  {
2366  int save_errno = errno;
2367 
2368  ereport(LOG,
2369  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2370  errmsg("out of file descriptors: %m; release and retry")));
2371  errno = 0;
2372  if (ReleaseLruFile())
2373  goto TryAgain;
2374  errno = save_errno;
2375  }
2376 
2377  return NULL;
2378 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
DIR * dir
Definition: fd.c:238
union AllocateDesc::@28 desc
#define DO_DB(A)
Definition: fd.c:152
int errcode(int sqlerrcode)
Definition: elog.c:575
static bool reserveAllocatedDesc(void)
Definition: fd.c:2021
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static bool ReleaseLruFile(void)
Definition: fd.c:1140
Definition: dirent.c:25
#define ERROR
Definition: elog.h:43
DIR * opendir(const char *)
Definition: dirent.c:33
#define ereport(elevel, rest)
Definition: elog.h:122
static void ReleaseLruFiles(void)
Definition: fd.c:1162
#define NULL
Definition: c.h:229
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:649
SubTransactionId create_subid
Definition: fd.c:234
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
static int maxAllocatedDescs
Definition: fd.c:244
static int numAllocatedDescs
Definition: fd.c:243
FILE* AllocateFile ( const char *  name,
const char *  mode 
)

Definition at line 2094 of file fd.c.

References AllocateDescFile, AllocateDesc::create_subid, AllocateDesc::desc, DO_DB, elog, ereport, errcode(), errmsg(), ERROR, AllocateDesc::file, GetCurrentSubTransactionId(), AllocateDesc::kind, LOG, maxAllocatedDescs, NULL, numAllocatedDescs, ReleaseLruFile(), ReleaseLruFiles(), and reserveAllocatedDesc().

Referenced by AlterSystemSetConfigFile(), BeginCopyFrom(), BeginCopyTo(), checkDataDir(), do_pg_start_backup(), do_pg_stop_backup(), entry_reset(), existsTimeLineHistory(), ExportSnapshot(), fill_hba_view(), gc_qtexts(), ImportSnapshot(), load_hba(), load_ident(), load_relcache_init_file(), parse_extension_control_file(), ParseTzFile(), perform_base_backup(), pg_backup_start_time(), pg_current_logfile(), pg_file_write(), 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(), read_tablespace_map(), read_whole_file(), readRecoveryCommandFile(), readTimeLineHistory(), sendFile(), tokenize_inc_file(), tsearch_readline_begin(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

2095 {
2096  FILE *file;
2097 
2098  DO_DB(elog(LOG, "AllocateFile: Allocated %d (%s)",
2100 
2101  /* Can we allocate another non-virtual FD? */
2102  if (!reserveAllocatedDesc())
2103  ereport(ERROR,
2104  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2105  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2106  maxAllocatedDescs, name)));
2107 
2108  /* Close excess kernel FDs. */
2109  ReleaseLruFiles();
2110 
2111 TryAgain:
2112  if ((file = fopen(name, mode)) != NULL)
2113  {
2115 
2116  desc->kind = AllocateDescFile;
2117  desc->desc.file = file;
2120  return desc->desc.file;
2121  }
2122 
2123  if (errno == EMFILE || errno == ENFILE)
2124  {
2125  int save_errno = errno;
2126 
2127  ereport(LOG,
2128  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2129  errmsg("out of file descriptors: %m; release and retry")));
2130  errno = 0;
2131  if (ReleaseLruFile())
2132  goto TryAgain;
2133  errno = save_errno;
2134  }
2135 
2136  return NULL;
2137 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
union AllocateDesc::@28 desc
#define DO_DB(A)
Definition: fd.c:152
int errcode(int sqlerrcode)
Definition: elog.c:575
static bool reserveAllocatedDesc(void)
Definition: fd.c:2021
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static bool ReleaseLruFile(void)
Definition: fd.c:1140
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static void ReleaseLruFiles(void)
Definition: fd.c:1162
FILE * file
Definition: fd.c:237
#define NULL
Definition: c.h:229
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:649
SubTransactionId create_subid
Definition: fd.c:234
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
static int maxAllocatedDescs
Definition: fd.c:244
static int numAllocatedDescs
Definition: fd.c:243
void AtEOSubXact_Files ( bool  isCommit,
SubTransactionId  mySubid,
SubTransactionId  parentSubid 
)

Definition at line 2586 of file fd.c.

References AllocateDesc::create_subid, FreeDesc(), i, and numAllocatedDescs.

Referenced by AbortSubTransaction(), and CommitSubTransaction().

2588 {
2589  Index i;
2590 
2591  for (i = 0; i < numAllocatedDescs; i++)
2592  {
2593  if (allocatedDescs[i].create_subid == mySubid)
2594  {
2595  if (isCommit)
2596  allocatedDescs[i].create_subid = parentSubid;
2597  else
2598  {
2599  /* have to recheck the item after FreeDesc (ugly) */
2600  FreeDesc(&allocatedDescs[i--]);
2601  }
2602  }
2603  }
2604 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2238
unsigned int Index
Definition: c.h:365
SubTransactionId create_subid
Definition: fd.c:234
int i
static int numAllocatedDescs
Definition: fd.c:243
void AtEOXact_Files ( void  )

Definition at line 2617 of file fd.c.

References CleanupTempFiles(), NULL, numTempTableSpaces, and tempTableSpaces.

Referenced by AbortTransaction(), BackgroundWriterMain(), CheckpointerMain(), CommitTransaction(), PrepareTransaction(), and WalWriterMain().

2618 {
2619  CleanupTempFiles(false);
2621  numTempTableSpaces = -1;
2622 }
static int numTempTableSpaces
Definition: fd.c:258
static void CleanupTempFiles(bool isProcExit)
Definition: fd.c:2646
#define NULL
Definition: c.h:229
static Oid * tempTableSpaces
Definition: fd.c:257
int BasicOpenFile ( FileName  fileName,
int  fileFlags,
int  fileMode 
)

Definition at line 936 of file fd.c.

References ereport, errcode(), errmsg(), fd(), LOG, and ReleaseLruFile().

Referenced by AlterSystemSetConfigFile(), GetNewRelFileNode(), LruInsert(), OpenTransientFile(), PathNameOpenFile(), ReadControlFile(), UpdateControlFile(), WriteControlFile(), XLogFileInit(), XLogFileOpen(), XLogFileRead(), and XLogRead().

937 {
938  int fd;
939 
940 tryAgain:
941  fd = open(fileName, fileFlags, fileMode);
942 
943  if (fd >= 0)
944  return fd; /* success! */
945 
946  if (errno == EMFILE || errno == ENFILE)
947  {
948  int save_errno = errno;
949 
950  ereport(LOG,
951  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
952  errmsg("out of file descriptors: %m; release and retry")));
953  errno = 0;
954  if (ReleaseLruFile())
955  goto tryAgain;
956  errno = save_errno;
957  }
958 
959  return -1; /* failure */
960 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static bool ReleaseLruFile(void)
Definition: fd.c:1140
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
void closeAllVfds ( void  )

Definition at line 2499 of file fd.c.

References Assert, FileIsNotOpen, i, LruDelete(), and SizeVfdCache.

Referenced by standard_ProcessUtility().

2500 {
2501  Index i;
2502 
2503  if (SizeVfdCache > 0)
2504  {
2505  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2506  for (i = 1; i < SizeVfdCache; i++)
2507  {
2508  if (!FileIsNotOpen(i))
2509  LruDelete(i);
2510  }
2511  }
2512 }
static Size SizeVfdCache
Definition: fd.c:198
static void LruDelete(File file)
Definition: fd.c:1003
#define FileIsNotOpen(file)
Definition: fd.c:161
unsigned int Index
Definition: c.h:365
#define Assert(condition)
Definition: c.h:675
int i
int ClosePipeStream ( FILE *  file)

Definition at line 2470 of file fd.c.

References AllocateDescPipe, AllocateDesc::desc, DO_DB, elog, AllocateDesc::file, FreeDesc(), i, AllocateDesc::kind, LOG, numAllocatedDescs, and WARNING.

Referenced by ClosePipeToProgram(), and pg_import_system_collations().

2471 {
2472  int i;
2473 
2474  DO_DB(elog(LOG, "ClosePipeStream: Allocated %d", numAllocatedDescs));
2475 
2476  /* Remove file from list of allocated files, if it's present */
2477  for (i = numAllocatedDescs; --i >= 0;)
2478  {
2479  AllocateDesc *desc = &allocatedDescs[i];
2480 
2481  if (desc->kind == AllocateDescPipe && desc->desc.file == file)
2482  return FreeDesc(desc);
2483  }
2484 
2485  /* Only get here if someone passes us a file not in allocatedDescs */
2486  elog(WARNING, "file passed to ClosePipeStream was not obtained from OpenPipeStream");
2487 
2488  return pclose(file);
2489 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
union AllocateDesc::@28 desc
#define DO_DB(A)
Definition: fd.c:152
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2238
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:237
int i
#define elog
Definition: elog.h:219
static int numAllocatedDescs
Definition: fd.c:243
int CloseTransientFile ( int  fd)

Definition at line 2305 of file fd.c.

References AllocateDescRawFD, close, AllocateDesc::desc, DO_DB, elog, AllocateDesc::fd, FreeDesc(), i, AllocateDesc::kind, LOG, numAllocatedDescs, and WARNING.

Referenced by be_lo_export(), CheckPointLogicalRewriteHeap(), CheckPointReplicationOrigin(), copy_file(), dsm_impl_mmap(), durable_rename(), fsync_fname_ext(), heap_xlog_logical_rewrite(), lo_import_internal(), load_relmap_file(), mdunlinkfork(), qtext_load_file(), qtext_store(), ReadTwoPhaseFile(), RecreateTwoPhaseFile(), ReorderBufferIterTXNFinish(), ReorderBufferRestoreChanges(), ReorderBufferSerializeChange(), ReorderBufferSerializeTXN(), RestoreSlotFromDisk(), SaveSlotToPath(), SendTimeLineHistory(), SimpleLruDoesPhysicalPageExist(), SimpleLruFlush(), SlruInternalWritePage(), SlruPhysicalReadPage(), SlruPhysicalWritePage(), SnapBuildRestore(), SnapBuildSerialize(), StartupReplicationOrigin(), write_relmap_file(), writeTimeLineHistory(), writeTimeLineHistoryFile(), and XLogFileCopy().

2306 {
2307  int i;
2308 
2309  DO_DB(elog(LOG, "CloseTransientFile: Allocated %d", numAllocatedDescs));
2310 
2311  /* Remove fd from list of allocated files, if it's present */
2312  for (i = numAllocatedDescs; --i >= 0;)
2313  {
2314  AllocateDesc *desc = &allocatedDescs[i];
2315 
2316  if (desc->kind == AllocateDescRawFD && desc->desc.fd == fd)
2317  return FreeDesc(desc);
2318  }
2319 
2320  /* Only get here if someone passes us a file not in allocatedDescs */
2321  elog(WARNING, "fd passed to CloseTransientFile was not obtained from OpenTransientFile");
2322 
2323  return close(fd);
2324 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
union AllocateDesc::@28 desc
#define DO_DB(A)
Definition: fd.c:152
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2238
#define WARNING
Definition: elog.h:40
int fd
Definition: fd.c:239
int i
#define elog
Definition: elog.h:219
#define close(a)
Definition: win32.h:12
static int numAllocatedDescs
Definition: fd.c:243
int durable_link_or_rename ( const char *  oldfile,
const char *  newfile,
int  loglevel 
)

Definition at line 712 of file fd.c.

References ereport, errcode_for_file_access(), errmsg(), fsync_fname_ext(), fsync_parent_path(), link(), and unlink().

Referenced by InstallXLogFileSegment(), writeTimeLineHistory(), and writeTimeLineHistoryFile().

713 {
714  /*
715  * Ensure that, if we crash directly after the rename/link, a file with
716  * valid contents is moved into place.
717  */
718  if (fsync_fname_ext(oldfile, false, false, elevel) != 0)
719  return -1;
720 
721 #if HAVE_WORKING_LINK
722  if (link(oldfile, newfile) < 0)
723  {
724  ereport(elevel,
726  errmsg("could not link file \"%s\" to \"%s\": %m",
727  oldfile, newfile)));
728  return -1;
729  }
730  unlink(oldfile);
731 #else
732  /* XXX: Add racy file existence check? */
733  if (rename(oldfile, newfile) < 0)
734  {
735  ereport(elevel,
737  errmsg("could not rename file \"%s\" to \"%s\": %m",
738  oldfile, newfile)));
739  return -1;
740  }
741 #endif
742 
743  /*
744  * Make change persistent in case of an OS crash, both the new entry and
745  * its parent directory need to be flushed.
746  */
747  if (fsync_fname_ext(newfile, false, false, elevel) != 0)
748  return -1;
749 
750  /* Same for parent directory */
751  if (fsync_parent_path(newfile, elevel) != 0)
752  return -1;
753 
754  return 0;
755 }
int errcode_for_file_access(void)
Definition: elog.c:598
int unlink(const char *filename)
#define ereport(elevel, rest)
Definition: elog.h:122
int link(const char *fromname, const char *toname)
static int elevel
Definition: vacuumlazy.c:137
int errmsg(const char *fmt,...)
Definition: elog.c:797
static int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3126
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3196
int durable_rename ( const char *  oldfile,
const char *  newfile,
int  loglevel 
)

Definition at line 593 of file fd.c.

References CloseTransientFile(), ereport, errcode_for_file_access(), errmsg(), fd(), fsync_fname_ext(), fsync_parent_path(), OpenTransientFile(), PG_BINARY, and pg_fsync().

Referenced by AlterSystemSetConfigFile(), CancelBackup(), CheckPointReplicationOrigin(), dir_close(), exitArchiveRecovery(), KeepFileRestoredFromArchive(), pgarch_archiveDone(), pgss_shmem_shutdown(), StartupXLOG(), and XLogArchiveForceDone().

594 {
595  int fd;
596 
597  /*
598  * First fsync the old and target path (if it exists), to ensure that they
599  * are properly persistent on disk. Syncing the target file is not
600  * strictly necessary, but it makes it easier to reason about crashes;
601  * because it's then guaranteed that either source or target file exists
602  * after a crash.
603  */
604  if (fsync_fname_ext(oldfile, false, false, elevel) != 0)
605  return -1;
606 
607  fd = OpenTransientFile((char *) newfile, PG_BINARY | O_RDWR, 0);
608  if (fd < 0)
609  {
610  if (errno != ENOENT)
611  {
612  ereport(elevel,
614  errmsg("could not open file \"%s\": %m", newfile)));
615  return -1;
616  }
617  }
618  else
619  {
620  if (pg_fsync(fd) != 0)
621  {
622  int save_errno;
623 
624  /* close file upon error, might not be in transaction context */
625  save_errno = errno;
626  CloseTransientFile(fd);
627  errno = save_errno;
628 
629  ereport(elevel,
631  errmsg("could not fsync file \"%s\": %m", newfile)));
632  return -1;
633  }
634  CloseTransientFile(fd);
635  }
636 
637  /* Time to do the real deal... */
638  if (rename(oldfile, newfile) < 0)
639  {
640  ereport(elevel,
642  errmsg("could not rename file \"%s\" to \"%s\": %m",
643  oldfile, newfile)));
644  return -1;
645  }
646 
647  /*
648  * To guarantee renaming the file is persistent, fsync the file with its
649  * new name, and its containing directory.
650  */
651  if (fsync_fname_ext(newfile, false, false, elevel) != 0)
652  return -1;
653 
654  if (fsync_parent_path(newfile, elevel) != 0)
655  return -1;
656 
657  return 0;
658 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1038
int OpenTransientFile(FileName fileName, int fileFlags, int fileMode)
Definition: fd.c:2144
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
int CloseTransientFile(int fd)
Definition: fd.c:2305
static int elevel
Definition: vacuumlazy.c:137
int errmsg(const char *fmt,...)
Definition: elog.c:797
static int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3126
int pg_fsync(int fd)
Definition: fd.c:333
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3196
int durable_unlink ( const char *  fname,
int  loglevel 
)

Definition at line 676 of file fd.c.

References ereport, errcode_for_file_access(), errmsg(), fsync_parent_path(), and unlink().

Referenced by do_pg_stop_backup(), InstallXLogFileSegment(), and RemoveXlogFile().

677 {
678  if (unlink(fname) < 0)
679  {
680  ereport(elevel,
682  errmsg("could not remove file \"%s\": %m",
683  fname)));
684  return -1;
685  }
686 
687  /*
688  * To guarantee that the removal of the file is persistent, fsync
689  * its parent directory.
690  */
691  if (fsync_parent_path(fname, elevel) != 0)
692  return -1;
693 
694  return 0;
695 }
int errcode_for_file_access(void)
Definition: elog.c:598
int unlink(const char *filename)
#define ereport(elevel, rest)
Definition: elog.h:122
static int elevel
Definition: vacuumlazy.c:137
int errmsg(const char *fmt,...)
Definition: elog.c:797
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3196
void FileClose ( File  file)

Definition at line 1493 of file fd.c.

References Assert, close, Delete(), DO_DB, elog, ereport, errmsg(), 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, unlink(), and VFD_CLOSED.

Referenced by BufFileClose(), CleanupTempFiles(), logical_end_heap_rewrite(), mdclose(), mdtruncate(), and ResourceOwnerReleaseInternal().

1494 {
1495  Vfd *vfdP;
1496 
1497  Assert(FileIsValid(file));
1498 
1499  DO_DB(elog(LOG, "FileClose: %d (%s)",
1500  file, VfdCache[file].fileName));
1501 
1502  vfdP = &VfdCache[file];
1503 
1504  if (!FileIsNotOpen(file))
1505  {
1506  /* close the file */
1507  if (close(vfdP->fd))
1508  elog(LOG, "could not close file \"%s\": %m", vfdP->fileName);
1509 
1510  --nfile;
1511  vfdP->fd = VFD_CLOSED;
1512 
1513  /* remove the file from the lru ring */
1514  Delete(file);
1515  }
1516 
1517  /*
1518  * Delete the file if it was temporary, and make a log entry if wanted
1519  */
1520  if (vfdP->fdstate & FD_TEMPORARY)
1521  {
1522  struct stat filestats;
1523  int stat_errno;
1524 
1525  /*
1526  * If we get an error, as could happen within the ereport/elog calls,
1527  * we'll come right back here during transaction abort. Reset the
1528  * flag to ensure that we can't get into an infinite loop. This code
1529  * is arranged to ensure that the worst-case consequence is failing to
1530  * emit log message(s), not failing to attempt the unlink.
1531  */
1532  vfdP->fdstate &= ~FD_TEMPORARY;
1533 
1534  /* Subtract its size from current usage (do first in case of error) */
1535  temporary_files_size -= vfdP->fileSize;
1536  vfdP->fileSize = 0;
1537 
1538  /* first try the stat() */
1539  if (stat(vfdP->fileName, &filestats))
1540  stat_errno = errno;
1541  else
1542  stat_errno = 0;
1543 
1544  /* in any case do the unlink */
1545  if (unlink(vfdP->fileName))
1546  elog(LOG, "could not unlink file \"%s\": %m", vfdP->fileName);
1547 
1548  /* and last report the stat results */
1549  if (stat_errno == 0)
1550  {
1551  pgstat_report_tempfile(filestats.st_size);
1552 
1553  if (log_temp_files >= 0)
1554  {
1555  if ((filestats.st_size / 1024) >= log_temp_files)
1556  ereport(LOG,
1557  (errmsg("temporary file: path \"%s\", size %lu",
1558  vfdP->fileName,
1559  (unsigned long) filestats.st_size)));
1560  }
1561  }
1562  else
1563  {
1564  errno = stat_errno;
1565  elog(LOG, "could not stat file \"%s\": %m", vfdP->fileName);
1566  }
1567  }
1568 
1569  /* Unregister it from the resource owner */
1570  if (vfdP->resowner)
1571  ResourceOwnerForgetFile(vfdP->resowner, file);
1572 
1573  /*
1574  * Return the Vfd slot to the free list
1575  */
1576  FreeVfd(file);
1577 }
#define DO_DB(A)
Definition: fd.c:152
int log_temp_files
Definition: guc.c:458
static Vfd * VfdCache
Definition: fd.c:197
static void Delete(File file)
Definition: fd.c:984
void pgstat_report_tempfile(size_t filesize)
Definition: pgstat.c:1490
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:186
static int nfile
Definition: fd.c:203
unsigned short fdstate
Definition: fd.c:179
Definition: fd.c:176
off_t fileSize
Definition: fd.c:185
int fd
Definition: fd.c:178
int unlink(const char *filename)
#define ereport(elevel, rest)
Definition: elog.h:122
ResourceOwner resowner
Definition: fd.c:180
#define FileIsNotOpen(file)
Definition: fd.c:161
#define FD_TEMPORARY
Definition: fd.c:173
#define FileIsValid(file)
Definition: fd.c:158
#define VFD_CLOSED
Definition: fd.c:156
static uint64 temporary_files_size
Definition: fd.c:217
#define Assert(condition)
Definition: c.h:675
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void FreeVfd(File file)
Definition: fd.c:1230
#define elog
Definition: elog.h:219
#define close(a)
Definition: win32.h:12
void ResourceOwnerForgetFile(ResourceOwner owner, File file)
Definition: resowner.c:1209
int FileGetRawDesc ( File  file)

Definition at line 1990 of file fd.c.

References Assert, vfd::fd, and FileIsValid.

1991 {
1992  Assert(FileIsValid(file));
1993  return VfdCache[file].fd;
1994 }
static Vfd * VfdCache
Definition: fd.c:197
int fd
Definition: fd.c:178
#define FileIsValid(file)
Definition: fd.c:158
#define Assert(condition)
Definition: c.h:675
int FileGetRawFlags ( File  file)

Definition at line 2000 of file fd.c.

References Assert, vfd::fileFlags, and FileIsValid.

2001 {
2002  Assert(FileIsValid(file));
2003  return VfdCache[file].fileFlags;
2004 }
static Vfd * VfdCache
Definition: fd.c:197
#define FileIsValid(file)
Definition: fd.c:158
#define Assert(condition)
Definition: c.h:675
int fileFlags
Definition: fd.c:188
int FileGetRawMode ( File  file)

Definition at line 2010 of file fd.c.

References Assert, FileIsValid, and vfd::fileMode.

2011 {
2012  Assert(FileIsValid(file));
2013  return VfdCache[file].fileMode;
2014 }
static Vfd * VfdCache
Definition: fd.c:197
int fileMode
Definition: fd.c:189
#define FileIsValid(file)
Definition: fd.c:158
#define Assert(condition)
Definition: c.h:675
char* FilePathName ( File  file)

Definition at line 1974 of file fd.c.

References Assert, FileIsValid, and vfd::fileName.

Referenced by _mdnblocks(), mdextend(), mdimmedsync(), mdread(), mdsync(), mdtruncate(), mdwrite(), and register_dirty_segment().

1975 {
1976  Assert(FileIsValid(file));
1977 
1978  return VfdCache[file].fileName;
1979 }
static Vfd * VfdCache
Definition: fd.c:197
char * fileName
Definition: fd.c:186
#define FileIsValid(file)
Definition: fd.c:158
#define Assert(condition)
Definition: c.h:675
int FilePrefetch ( File  file,
off_t  offset,
int  amount,
uint32  wait_event_info 
)

Definition at line 1590 of file fd.c.

References Assert, DO_DB, elog, fd(), FileAccess(), FileIsValid, INT64_FORMAT, LOG, pgstat_report_wait_end(), and pgstat_report_wait_start().

Referenced by mdprefetch().

1591 {
1592 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
1593  int returnCode;
1594 
1595  Assert(FileIsValid(file));
1596 
1597  DO_DB(elog(LOG, "FilePrefetch: %d (%s) " INT64_FORMAT " %d",
1598  file, VfdCache[file].fileName,
1599  (int64) offset, amount));
1600 
1601  returnCode = FileAccess(file);
1602  if (returnCode < 0)
1603  return returnCode;
1604 
1605  pgstat_report_wait_start(wait_event_info);
1606  returnCode = posix_fadvise(VfdCache[file].fd, offset, amount,
1607  POSIX_FADV_WILLNEED);
1609 
1610  return returnCode;
1611 #else
1612  Assert(FileIsValid(file));
1613  return 0;
1614 #endif
1615 }
#define DO_DB(A)
Definition: fd.c:152
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1232
#define FileIsValid(file)
Definition: fd.c:158
static int FileAccess(File file)
Definition: fd.c:1250
#define Assert(condition)
Definition: c.h:675
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1208
#define INT64_FORMAT
Definition: c.h:315
#define elog
Definition: elog.h:219
int FileRead ( File  file,
char *  buffer,
int  amount,
uint32  wait_event_info 
)

Definition at line 1645 of file fd.c.

References _dosmaperr(), Assert, DO_DB, EINTR, elog, error(), vfd::fd, FileAccess(), FileIsValid, FilePosIsUnknown, FileUnknownPos, INT64_FORMAT, LOG, pg_usleep(), pgstat_report_wait_end(), pgstat_report_wait_start(), read, and vfd::seekPos.

Referenced by BufFileLoadBuffer(), and mdread().

1646 {
1647  int returnCode;
1648  Vfd *vfdP;
1649 
1650  Assert(FileIsValid(file));
1651 
1652  DO_DB(elog(LOG, "FileRead: %d (%s) " INT64_FORMAT " %d %p",
1653  file, VfdCache[file].fileName,
1654  (int64) VfdCache[file].seekPos,
1655  amount, buffer));
1656 
1657  returnCode = FileAccess(file);
1658  if (returnCode < 0)
1659  return returnCode;
1660 
1661  vfdP = &VfdCache[file];
1662 
1663 retry:
1664  pgstat_report_wait_start(wait_event_info);
1665  returnCode = read(vfdP->fd, buffer, amount);
1667 
1668  if (returnCode >= 0)
1669  {
1670  /* if seekPos is unknown, leave it that way */
1671  if (!FilePosIsUnknown(vfdP->seekPos))
1672  vfdP->seekPos += returnCode;
1673  }
1674  else
1675  {
1676  /*
1677  * Windows may run out of kernel buffers and return "Insufficient
1678  * system resources" error. Wait a bit and retry to solve it.
1679  *
1680  * It is rumored that EINTR is also possible on some Unix filesystems,
1681  * in which case immediate retry is indicated.
1682  */
1683 #ifdef WIN32
1684  DWORD error = GetLastError();
1685 
1686  switch (error)
1687  {
1688  case ERROR_NO_SYSTEM_RESOURCES:
1689  pg_usleep(1000L);
1690  errno = EINTR;
1691  break;
1692  default:
1693  _dosmaperr(error);
1694  break;
1695  }
1696 #endif
1697  /* OK to retry if interrupted */
1698  if (errno == EINTR)
1699  goto retry;
1700 
1701  /* Trouble, so assume we don't know the file position anymore */
1702  vfdP->seekPos = FileUnknownPos;
1703  }
1704 
1705  return returnCode;
1706 }
static void error(void)
Definition: sql-dyntest.c:147
#define DO_DB(A)
Definition: fd.c:152
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
#define FilePosIsUnknown(pos)
Definition: fd.c:170
void pg_usleep(long microsec)
Definition: signal.c:53
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1232
off_t seekPos
Definition: fd.c:184
Definition: fd.c:176
int fd
Definition: fd.c:178
#define EINTR
Definition: win32.h:285
#define FileIsValid(file)
Definition: fd.c:158
static int FileAccess(File file)
Definition: fd.c:1250
#define Assert(condition)
Definition: c.h:675
void _dosmaperr(unsigned long)
Definition: win32error.c:171
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:207
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1208
#define INT64_FORMAT
Definition: c.h:315
#define elog
Definition: elog.h:219
#define FileUnknownPos
Definition: fd.c:169
#define read(a, b, c)
Definition: win32.h:13
off_t FileSeek ( File  file,
off_t  offset,
int  whence 
)

Definition at line 1851 of file fd.c.

References Assert, DO_DB, elog, ERROR, vfd::fd, FileAccess(), FileIsNotOpen, FileIsValid, FilePosIsUnknown, INT64_FORMAT, LOG, and vfd::seekPos.

Referenced by _mdnblocks(), BufFileDumpBuffer(), BufFileLoadBuffer(), mdextend(), mdread(), and mdwrite().

1852 {
1853  Vfd *vfdP;
1854 
1855  Assert(FileIsValid(file));
1856 
1857  DO_DB(elog(LOG, "FileSeek: %d (%s) " INT64_FORMAT " " INT64_FORMAT " %d",
1858  file, VfdCache[file].fileName,
1859  (int64) VfdCache[file].seekPos,
1860  (int64) offset, whence));
1861 
1862  vfdP = &VfdCache[file];
1863 
1864  if (FileIsNotOpen(file))
1865  {
1866  switch (whence)
1867  {
1868  case SEEK_SET:
1869  if (offset < 0)
1870  {
1871  errno = EINVAL;
1872  return (off_t) -1;
1873  }
1874  vfdP->seekPos = offset;
1875  break;
1876  case SEEK_CUR:
1877  if (FilePosIsUnknown(vfdP->seekPos) ||
1878  vfdP->seekPos + offset < 0)
1879  {
1880  errno = EINVAL;
1881  return (off_t) -1;
1882  }
1883  vfdP->seekPos += offset;
1884  break;
1885  case SEEK_END:
1886  if (FileAccess(file) < 0)
1887  return (off_t) -1;
1888  vfdP->seekPos = lseek(vfdP->fd, offset, whence);
1889  break;
1890  default:
1891  elog(ERROR, "invalid whence: %d", whence);
1892  break;
1893  }
1894  }
1895  else
1896  {
1897  switch (whence)
1898  {
1899  case SEEK_SET:
1900  if (offset < 0)
1901  {
1902  errno = EINVAL;
1903  return (off_t) -1;
1904  }
1905  if (vfdP->seekPos != offset)
1906  vfdP->seekPos = lseek(vfdP->fd, offset, whence);
1907  break;
1908  case SEEK_CUR:
1909  if (offset != 0 || FilePosIsUnknown(vfdP->seekPos))
1910  vfdP->seekPos = lseek(vfdP->fd, offset, whence);
1911  break;
1912  case SEEK_END:
1913  vfdP->seekPos = lseek(vfdP->fd, offset, whence);
1914  break;
1915  default:
1916  elog(ERROR, "invalid whence: %d", whence);
1917  break;
1918  }
1919  }
1920 
1921  return vfdP->seekPos;
1922 }
#define DO_DB(A)
Definition: fd.c:152
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
#define FilePosIsUnknown(pos)
Definition: fd.c:170
#define ERROR
Definition: elog.h:43
off_t seekPos
Definition: fd.c:184
Definition: fd.c:176
int fd
Definition: fd.c:178
#define FileIsNotOpen(file)
Definition: fd.c:161
#define FileIsValid(file)
Definition: fd.c:158
static int FileAccess(File file)
Definition: fd.c:1250
#define Assert(condition)
Definition: c.h:675
#define INT64_FORMAT
Definition: c.h:315
#define elog
Definition: elog.h:219
int FileSync ( File  file,
uint32  wait_event_info 
)

Definition at line 1830 of file fd.c.

References Assert, DO_DB, elog, fd(), FileAccess(), FileIsValid, LOG, pg_fsync(), pgstat_report_wait_end(), and pgstat_report_wait_start().

Referenced by logical_end_heap_rewrite(), mdimmedsync(), mdsync(), and register_dirty_segment().

1831 {
1832  int returnCode;
1833 
1834  Assert(FileIsValid(file));
1835 
1836  DO_DB(elog(LOG, "FileSync: %d (%s)",
1837  file, VfdCache[file].fileName));
1838 
1839  returnCode = FileAccess(file);
1840  if (returnCode < 0)
1841  return returnCode;
1842 
1843  pgstat_report_wait_start(wait_event_info);
1844  returnCode = pg_fsync(VfdCache[file].fd);
1846 
1847  return returnCode;
1848 }
#define DO_DB(A)
Definition: fd.c:152
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1232
#define FileIsValid(file)
Definition: fd.c:158
static int FileAccess(File file)
Definition: fd.c:1250
#define Assert(condition)
Definition: c.h:675
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1208
int pg_fsync(int fd)
Definition: fd.c:333
#define elog
Definition: elog.h:219
int FileTruncate ( File  file,
off_t  offset,
uint32  wait_event_info 
)

Definition at line 1939 of file fd.c.

References Assert, DO_DB, elog, fd(), FD_TEMPORARY, FileAccess(), FileIsValid, vfd::fileSize, ftruncate, LOG, pgstat_report_wait_end(), pgstat_report_wait_start(), and temporary_files_size.

Referenced by mdtruncate().

1940 {
1941  int returnCode;
1942 
1943  Assert(FileIsValid(file));
1944 
1945  DO_DB(elog(LOG, "FileTruncate %d (%s)",
1946  file, VfdCache[file].fileName));
1947 
1948  returnCode = FileAccess(file);
1949  if (returnCode < 0)
1950  return returnCode;
1951 
1952  pgstat_report_wait_start(wait_event_info);
1953  returnCode = ftruncate(VfdCache[file].fd, offset);
1955 
1956  if (returnCode == 0 && VfdCache[file].fileSize > offset)
1957  {
1958  /* adjust our state for truncation of a temp file */
1959  Assert(VfdCache[file].fdstate & FD_TEMPORARY);
1960  temporary_files_size -= VfdCache[file].fileSize - offset;
1961  VfdCache[file].fileSize = offset;
1962  }
1963 
1964  return returnCode;
1965 }
#define DO_DB(A)
Definition: fd.c:152
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1232
off_t fileSize
Definition: fd.c:185
#define FD_TEMPORARY
Definition: fd.c:173
#define FileIsValid(file)
Definition: fd.c:158
static uint64 temporary_files_size
Definition: fd.c:217
#define ftruncate(a, b)
Definition: win32.h:59
static int FileAccess(File file)
Definition: fd.c:1250
#define Assert(condition)
Definition: c.h:675
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1208
#define elog
Definition: elog.h:219
int FileWrite ( File  file,
char *  buffer,
int  amount,
uint32  wait_event_info 
)

Definition at line 1709 of file fd.c.

References _dosmaperr(), Assert, DO_DB, EINTR, elog, ereport, errcode(), errmsg(), ERROR, error(), vfd::fd, FD_TEMPORARY, vfd::fdstate, FileAccess(), FileIsValid, vfd::fileName, FilePosIsUnknown, vfd::fileSize, FileUnknownPos, INT64_FORMAT, LOG, pg_usleep(), pgstat_report_wait_end(), pgstat_report_wait_start(), vfd::seekPos, temp_file_limit, temporary_files_size, and write.

Referenced by BufFileDumpBuffer(), logical_heap_rewrite_flush_mappings(), mdextend(), and mdwrite().

1710 {
1711  int returnCode;
1712  Vfd *vfdP;
1713 
1714  Assert(FileIsValid(file));
1715 
1716  DO_DB(elog(LOG, "FileWrite: %d (%s) " INT64_FORMAT " %d %p",
1717  file, VfdCache[file].fileName,
1718  (int64) VfdCache[file].seekPos,
1719  amount, buffer));
1720 
1721  returnCode = FileAccess(file);
1722  if (returnCode < 0)
1723  return returnCode;
1724 
1725  vfdP = &VfdCache[file];
1726 
1727  /*
1728  * If enforcing temp_file_limit and it's a temp file, check to see if the
1729  * write would overrun temp_file_limit, and throw error if so. Note: it's
1730  * really a modularity violation to throw error here; we should set errno
1731  * and return -1. However, there's no way to report a suitable error
1732  * message if we do that. All current callers would just throw error
1733  * immediately anyway, so this is safe at present.
1734  */
1735  if (temp_file_limit >= 0 && (vfdP->fdstate & FD_TEMPORARY))
1736  {
1737  off_t newPos;
1738 
1739  /*
1740  * Normally we should know the seek position, but if for some reason
1741  * we have lost track of it, try again to get it. Here, it's fine to
1742  * throw an error if we still can't get it.
1743  */
1744  if (FilePosIsUnknown(vfdP->seekPos))
1745  {
1746  vfdP->seekPos = lseek(vfdP->fd, (off_t) 0, SEEK_CUR);
1747  if (FilePosIsUnknown(vfdP->seekPos))
1748  elog(ERROR, "could not seek file \"%s\": %m", vfdP->fileName);
1749  }
1750 
1751  newPos = vfdP->seekPos + amount;
1752  if (newPos > vfdP->fileSize)
1753  {
1754  uint64 newTotal = temporary_files_size;
1755 
1756  newTotal += newPos - vfdP->fileSize;
1757  if (newTotal > (uint64) temp_file_limit * (uint64) 1024)
1758  ereport(ERROR,
1759  (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
1760  errmsg("temporary file size exceeds temp_file_limit (%dkB)",
1761  temp_file_limit)));
1762  }
1763  }
1764 
1765 retry:
1766  errno = 0;
1767  pgstat_report_wait_start(wait_event_info);
1768  returnCode = write(vfdP->fd, buffer, amount);
1770 
1771  /* if write didn't set errno, assume problem is no disk space */
1772  if (returnCode != amount && errno == 0)
1773  errno = ENOSPC;
1774 
1775  if (returnCode >= 0)
1776  {
1777  /* if seekPos is unknown, leave it that way */
1778  if (!FilePosIsUnknown(vfdP->seekPos))
1779  vfdP->seekPos += returnCode;
1780 
1781  /*
1782  * Maintain fileSize and temporary_files_size if it's a temp file.
1783  *
1784  * If seekPos is -1 (unknown), this will do nothing; but we could only
1785  * get here in that state if we're not enforcing temporary_files_size,
1786  * so we don't care.
1787  */
1788  if (vfdP->fdstate & FD_TEMPORARY)
1789  {
1790  off_t newPos = vfdP->seekPos;
1791 
1792  if (newPos > vfdP->fileSize)
1793  {
1794  temporary_files_size += newPos - vfdP->fileSize;
1795  vfdP->fileSize = newPos;
1796  }
1797  }
1798  }
1799  else
1800  {
1801  /*
1802  * See comments in FileRead()
1803  */
1804 #ifdef WIN32
1805  DWORD error = GetLastError();
1806 
1807  switch (error)
1808  {
1809  case ERROR_NO_SYSTEM_RESOURCES:
1810  pg_usleep(1000L);
1811  errno = EINTR;
1812  break;
1813  default:
1814  _dosmaperr(error);
1815  break;
1816  }
1817 #endif
1818  /* OK to retry if interrupted */
1819  if (errno == EINTR)
1820  goto retry;
1821 
1822  /* Trouble, so assume we don't know the file position anymore */
1823  vfdP->seekPos = FileUnknownPos;
1824  }
1825 
1826  return returnCode;
1827 }
static void error(void)
Definition: sql-dyntest.c:147
#define write(a, b, c)
Definition: win32.h:14
#define DO_DB(A)
Definition: fd.c:152
static Vfd * VfdCache
Definition: fd.c:197
int errcode(int sqlerrcode)
Definition: elog.c:575
#define LOG
Definition: elog.h:26
#define FilePosIsUnknown(pos)
Definition: fd.c:170
void pg_usleep(long microsec)
Definition: signal.c:53
#define ERROR
Definition: elog.h:43
char * fileName
Definition: fd.c:186
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1232
off_t seekPos
Definition: fd.c:184
unsigned short fdstate
Definition: fd.c:179
Definition: fd.c:176
off_t fileSize
Definition: fd.c:185
int fd
Definition: fd.c:178
#define ereport(elevel, rest)
Definition: elog.h:122
#define FD_TEMPORARY
Definition: fd.c:173
#define EINTR
Definition: win32.h:285
#define FileIsValid(file)
Definition: fd.c:158
static uint64 temporary_files_size
Definition: fd.c:217
static int FileAccess(File file)
Definition: fd.c:1250
#define Assert(condition)
Definition: c.h:675
void _dosmaperr(unsigned long)
Definition: win32error.c:171
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:207
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1208
#define INT64_FORMAT
Definition: c.h:315
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
#define FileUnknownPos
Definition: fd.c:169
int temp_file_limit
Definition: guc.c:461
void FileWriteback ( File  file,
off_t  offset,
off_t  nbytes,
uint32  wait_event_info 
)

Definition at line 1618 of file fd.c.

References Assert, DO_DB, elog, fd(), FileAccess(), FileIsValid, INT64_FORMAT, LOG, pg_flush_data(), pgstat_report_wait_end(), and pgstat_report_wait_start().

Referenced by mdwriteback().

1619 {
1620  int returnCode;
1621 
1622  Assert(FileIsValid(file));
1623 
1624  DO_DB(elog(LOG, "FileWriteback: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
1625  file, VfdCache[file].fileName,
1626  (int64) offset, (int64) nbytes));
1627 
1628  /*
1629  * Caution: do not call pg_flush_data with nbytes = 0, it could trash the
1630  * file's seek position. We prefer to define that as a no-op here.
1631  */
1632  if (nbytes <= 0)
1633  return;
1634 
1635  returnCode = FileAccess(file);
1636  if (returnCode < 0)
1637  return;
1638 
1639  pgstat_report_wait_start(wait_event_info);
1640  pg_flush_data(VfdCache[file].fd, offset, nbytes);
1642 }
#define DO_DB(A)
Definition: fd.c:152
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1232
void pg_flush_data(int fd, off_t offset, off_t nbytes)
Definition: fd.c:407
#define FileIsValid(file)
Definition: fd.c:158
static int FileAccess(File file)
Definition: fd.c:1250
#define Assert(condition)
Definition: c.h:675
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1208
#define INT64_FORMAT
Definition: c.h:315
#define elog
Definition: elog.h:219
int FreeDir ( DIR dir)

Definition at line 2444 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(), CheckPointLogicalRewriteHeap(), CheckPointSnapBuild(), CleanupBackupHistory(), copydir(), db_dir_size(), DeleteAllExportedSnapshotFiles(), destroy_tablespace_directories(), directory_is_empty(), dsm_cleanup_for_mmap(), get_ext_ver_list(), getInstallationPaths(), movedb(), ParseTzFile(), perform_base_backup(), pg_available_extension_versions(), pg_available_extensions(), pg_logdir_ls(), pg_ls_dir(), pg_ls_dir_files(), pg_start_backup(), pg_tablespace_databases(), pg_tzenumerate_end(), pg_tzenumerate_next(), pgarch_readyXlog(), pgstat_reset_remove_files(), RelationCacheInitFileRemove(), RelationCacheInitFileRemoveInDir(), RemoveNonParentXlogFiles(), RemoveOldXlogFiles(), RemovePgTempFiles(), RemovePgTempFilesInDir(), RemovePgTempRelationFiles(), RemovePgTempRelationFilesInDbspace(), ResetUnloggedRelations(), ResetUnloggedRelationsInDbspaceDir(), ResetUnloggedRelationsInTablespaceDir(), restoreTwoPhaseData(), scan_directory_ci(), SendBaseBackup(), sendDir(), SlruScanDirectory(), StartupReorderBuffer(), StartupReplicationSlots(), UpdateLogicalMappings(), and walkdir().

2445 {
2446  int i;
2447 
2448  DO_DB(elog(LOG, "FreeDir: Allocated %d", numAllocatedDescs));
2449 
2450  /* Remove dir from list of allocated dirs, if it's present */
2451  for (i = numAllocatedDescs; --i >= 0;)
2452  {
2453  AllocateDesc *desc = &allocatedDescs[i];
2454 
2455  if (desc->kind == AllocateDescDir && desc->desc.dir == dir)
2456  return FreeDesc(desc);
2457  }
2458 
2459  /* Only get here if someone passes us a dir not in allocatedDescs */
2460  elog(WARNING, "dir passed to FreeDir was not obtained from AllocateDir");
2461 
2462  return closedir(dir);
2463 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
DIR * dir
Definition: fd.c:238
union AllocateDesc::@28 desc
#define DO_DB(A)
Definition: fd.c:152
int closedir(DIR *)
Definition: dirent.c:113
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2238
#define WARNING
Definition: elog.h:40
int i
#define elog
Definition: elog.h:219
static int numAllocatedDescs
Definition: fd.c:243
int FreeFile ( FILE *  file)

Definition at line 2277 of file fd.c.

References AllocateDescFile, AllocateDesc::desc, DO_DB, elog, AllocateDesc::file, FreeDesc(), i, AllocateDesc::kind, LOG, numAllocatedDescs, and WARNING.

Referenced by AlterSystemSetConfigFile(), checkDataDir(), do_pg_start_backup(), do_pg_stop_backup(), EndCopy(), entry_reset(), existsTimeLineHistory(), ExportSnapshot(), fill_hba_view(), gc_qtexts(), ImportSnapshot(), load_hba(), load_ident(), load_relcache_init_file(), parse_extension_control_file(), ParseTzFile(), perform_base_backup(), pg_backup_start_time(), pg_current_logfile(), pg_file_write(), 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(), read_tablespace_map(), read_whole_file(), readRecoveryCommandFile(), readTimeLineHistory(), sendFile(), tokenize_inc_file(), tsearch_readline_end(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

2278 {
2279  int i;
2280 
2281  DO_DB(elog(LOG, "FreeFile: Allocated %d", numAllocatedDescs));
2282 
2283  /* Remove file from list of allocated files, if it's present */
2284  for (i = numAllocatedDescs; --i >= 0;)
2285  {
2286  AllocateDesc *desc = &allocatedDescs[i];
2287 
2288  if (desc->kind == AllocateDescFile && desc->desc.file == file)
2289  return FreeDesc(desc);
2290  }
2291 
2292  /* Only get here if someone passes us a file not in allocatedDescs */
2293  elog(WARNING, "file passed to FreeFile was not obtained from AllocateFile");
2294 
2295  return fclose(file);
2296 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
union AllocateDesc::@28 desc
#define DO_DB(A)
Definition: fd.c:152
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2238
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:237
int i
#define elog
Definition: elog.h:219
static int numAllocatedDescs
Definition: fd.c:243
void fsync_fname ( const char *  fname,
bool  isdir 
)
Oid GetNextTempTableSpace ( void  )

Definition at line 2565 of file fd.c.

References InvalidOid, nextTempTableSpace, numTempTableSpaces, and tempTableSpaces.

Referenced by GetDefaultTablespace(), and OpenTemporaryFile().

2566 {
2567  if (numTempTableSpaces > 0)
2568  {
2569  /* Advance nextTempTableSpace counter with wraparound */
2571  nextTempTableSpace = 0;
2573  }
2574  return InvalidOid;
2575 }
static int numTempTableSpaces
Definition: fd.c:258
static int nextTempTableSpace
Definition: fd.c:259
#define InvalidOid
Definition: postgres_ext.h:36
static Oid * tempTableSpaces
Definition: fd.c:257
void InitFileAccess ( void  )

Definition at line 764 of file fd.c.

References Assert, AtProcExit_Files(), ereport, errcode(), errmsg(), FATAL, vfd::fd, malloc, MemSet, NULL, on_proc_exit(), SizeVfdCache, and VFD_CLOSED.

Referenced by BaseInit().

765 {
766  Assert(SizeVfdCache == 0); /* call me only once */
767 
768  /* initialize cache header entry */
769  VfdCache = (Vfd *) malloc(sizeof(Vfd));
770  if (VfdCache == NULL)
771  ereport(FATAL,
772  (errcode(ERRCODE_OUT_OF_MEMORY),
773  errmsg("out of memory")));
774 
775  MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));
777 
778  SizeVfdCache = 1;
779 
780  /* register proc-exit hook to ensure temp files are dropped at exit */
782 }
static void AtProcExit_Files(int code, Datum arg)
Definition: fd.c:2631
static Size SizeVfdCache
Definition: fd.c:198
void on_proc_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:292
static Vfd * VfdCache
Definition: fd.c:197
int errcode(int sqlerrcode)
Definition: elog.c:575
#define MemSet(start, val, len)
Definition: c.h:857
#define malloc(a)
Definition: header.h:50
#define FATAL
Definition: elog.h:52
Definition: fd.c:176
int fd
Definition: fd.c:178
#define ereport(elevel, rest)
Definition: elog.h:122
#define VFD_CLOSED
Definition: fd.c:156
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
int errmsg(const char *fmt,...)
Definition: elog.c:797
FILE* OpenPipeStream ( const char *  command,
const char *  mode 
)

Definition at line 2184 of file fd.c.

References AllocateDescPipe, AllocateDesc::create_subid, AllocateDesc::desc, DO_DB, elog, ereport, errcode(), errmsg(), ERROR, AllocateDesc::file, GetCurrentSubTransactionId(), AllocateDesc::kind, LOG, maxAllocatedDescs, NULL, numAllocatedDescs, ReleaseLruFile(), ReleaseLruFiles(), and reserveAllocatedDesc().

Referenced by BeginCopyFrom(), BeginCopyTo(), and pg_import_system_collations().

2185 {
2186  FILE *file;
2187 
2188  DO_DB(elog(LOG, "OpenPipeStream: Allocated %d (%s)",
2189  numAllocatedDescs, command));
2190 
2191  /* Can we allocate another non-virtual FD? */
2192  if (!reserveAllocatedDesc())
2193  ereport(ERROR,
2194  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2195  errmsg("exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"",
2196  maxAllocatedDescs, command)));
2197 
2198  /* Close excess kernel FDs. */
2199  ReleaseLruFiles();
2200 
2201 TryAgain:
2202  fflush(stdout);
2203  fflush(stderr);
2204  errno = 0;
2205  if ((file = popen(command, mode)) != NULL)
2206  {
2208 
2209  desc->kind = AllocateDescPipe;
2210  desc->desc.file = file;
2213  return desc->desc.file;
2214  }
2215 
2216  if (errno == EMFILE || errno == ENFILE)
2217  {
2218  int save_errno = errno;
2219 
2220  ereport(LOG,
2221  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2222  errmsg("out of file descriptors: %m; release and retry")));
2223  errno = 0;
2224  if (ReleaseLruFile())
2225  goto TryAgain;
2226  errno = save_errno;
2227  }
2228 
2229  return NULL;
2230 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
union AllocateDesc::@28 desc
#define DO_DB(A)
Definition: fd.c:152
int errcode(int sqlerrcode)
Definition: elog.c:575
static bool reserveAllocatedDesc(void)
Definition: fd.c:2021
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static bool ReleaseLruFile(void)
Definition: fd.c:1140
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static void ReleaseLruFiles(void)
Definition: fd.c:1162
FILE * file
Definition: fd.c:237
#define NULL
Definition: c.h:229
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:649
SubTransactionId create_subid
Definition: fd.c:234
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
static int maxAllocatedDescs
Definition: fd.c:244
static int numAllocatedDescs
Definition: fd.c:243
File OpenTemporaryFile ( bool  interXact)

Definition at line 1371 of file fd.c.

References CurrentResourceOwner, DEFAULTTABLESPACE_OID, FD_TEMPORARY, FD_XACT_TEMPORARY, vfd::fdstate, GetNextTempTableSpace(), have_xact_temporary_files, MyDatabaseTableSpace, numTempTableSpaces, OidIsValid, OpenTemporaryFileInTablespace(), ResourceOwnerEnlargeFiles(), ResourceOwnerRememberFile(), and vfd::resowner.

Referenced by BufFileCreateTemp(), and extendBufFile().

1372 {
1373  File file = 0;
1374 
1375  /*
1376  * If some temp tablespace(s) have been given to us, try to use the next
1377  * one. If a given tablespace can't be found, we silently fall back to
1378  * the database's default tablespace.
1379  *
1380  * BUT: if the temp file is slated to outlive the current transaction,
1381  * force it into the database's default tablespace, so that it will not
1382  * pose a threat to possible tablespace drop attempts.
1383  */
1384  if (numTempTableSpaces > 0 && !interXact)
1385  {
1386  Oid tblspcOid = GetNextTempTableSpace();
1387 
1388  if (OidIsValid(tblspcOid))
1389  file = OpenTemporaryFileInTablespace(tblspcOid, false);
1390  }
1391 
1392  /*
1393  * If not, or if tablespace is bad, create in database's default
1394  * tablespace. MyDatabaseTableSpace should normally be set before we get
1395  * here, but just in case it isn't, fall back to pg_default tablespace.
1396  */
1397  if (file <= 0)
1401  true);
1402 
1403  /* Mark it for deletion at close */
1404  VfdCache[file].fdstate |= FD_TEMPORARY;
1405 
1406  /* Register it with the current resource owner */
1407  if (!interXact)
1408  {
1410 
1414 
1415  /* ensure cleanup happens at eoxact */
1417  }
1418 
1419  return file;
1420 }
static File OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError)
Definition: fd.c:1427
ResourceOwner CurrentResourceOwner
Definition: resowner.c:138
static Vfd * VfdCache
Definition: fd.c:197
static int numTempTableSpaces
Definition: fd.c:258
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
Oid MyDatabaseTableSpace
Definition: globals.c:78
static bool have_xact_temporary_files
Definition: fd.c:209
Oid GetNextTempTableSpace(void)
Definition: fd.c:2565
void ResourceOwnerRememberFile(ResourceOwner owner, File file)
Definition: resowner.c:1200
#define DEFAULTTABLESPACE_OID
Definition: pg_tablespace.h:63
unsigned short fdstate
Definition: fd.c:179
ResourceOwner resowner
Definition: fd.c:180
#define FD_TEMPORARY
Definition: fd.c:173
#define FD_XACT_TEMPORARY
Definition: fd.c:174
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1189
int File
Definition: fd.h:51
int OpenTransientFile ( FileName  fileName,
int  fileFlags,
int  fileMode 
)

Definition at line 2144 of file fd.c.

References AllocateDescRawFD, BasicOpenFile(), AllocateDesc::create_subid, AllocateDesc::desc, DO_DB, elog, ereport, errcode(), errmsg(), ERROR, fd(), AllocateDesc::fd, GetCurrentSubTransactionId(), AllocateDesc::kind, LOG, maxAllocatedDescs, numAllocatedDescs, ReleaseLruFiles(), and reserveAllocatedDesc().

Referenced by ApplyLogicalMappingFile(), be_lo_export(), CheckPointLogicalRewriteHeap(), CheckPointReplicationOrigin(), copy_file(), dsm_impl_mmap(), durable_rename(), fsync_fname_ext(), heap_xlog_logical_rewrite(), lo_import_internal(), load_relmap_file(), mdunlinkfork(), qtext_load_file(), qtext_store(), ReadTwoPhaseFile(), RecreateTwoPhaseFile(), ReorderBufferRestoreChanges(), ReorderBufferSerializeTXN(), RestoreSlotFromDisk(), SaveSlotToPath(), SendTimeLineHistory(), SimpleLruDoesPhysicalPageExist(), SlruPhysicalReadPage(), SlruPhysicalWritePage(), SnapBuildRestore(), SnapBuildSerialize(), StartupReplicationOrigin(), write_relmap_file(), writeTimeLineHistory(), writeTimeLineHistoryFile(), and XLogFileCopy().

2145 {
2146  int fd;
2147 
2148  DO_DB(elog(LOG, "OpenTransientFile: Allocated %d (%s)",
2149  numAllocatedDescs, fileName));
2150 
2151  /* Can we allocate another non-virtual FD? */
2152  if (!reserveAllocatedDesc())
2153  ereport(ERROR,
2154  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2155  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2156  maxAllocatedDescs, fileName)));
2157 
2158  /* Close excess kernel FDs. */
2159  ReleaseLruFiles();
2160 
2161  fd = BasicOpenFile(fileName, fileFlags, fileMode);
2162 
2163  if (fd >= 0)
2164  {
2166 
2167  desc->kind = AllocateDescRawFD;
2168  desc->desc.fd = fd;
2171 
2172  return fd;
2173  }
2174 
2175  return -1; /* failure */
2176 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
union AllocateDesc::@28 desc
#define DO_DB(A)
Definition: fd.c:152
int errcode(int sqlerrcode)
Definition: elog.c:575
static bool reserveAllocatedDesc(void)
Definition: fd.c:2021
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static void ReleaseLruFiles(void)
Definition: fd.c:1162
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:649
SubTransactionId create_subid
Definition: fd.c:234
int fd
Definition: fd.c:239
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
static int maxAllocatedDescs
Definition: fd.c:244
static int numAllocatedDescs
Definition: fd.c:243
int BasicOpenFile(FileName fileName, int fileFlags, int fileMode)
Definition: fd.c:936
File PathNameOpenFile ( FileName  fileName,
int  fileFlags,
int  fileMode 
)

Definition at line 1303 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, nfile, NULL, ReleaseLruFiles(), vfd::resowner, and vfd::seekPos.

Referenced by _mdfd_openseg(), logical_rewrite_log_mapping(), mdcreate(), mdopen(), and OpenTemporaryFileInTablespace().

1304 {
1305  char *fnamecopy;
1306  File file;
1307  Vfd *vfdP;
1308 
1309  DO_DB(elog(LOG, "PathNameOpenFile: %s %x %o",
1310  fileName, fileFlags, fileMode));
1311 
1312  /*
1313  * We need a malloc'd copy of the file name; fail cleanly if no room.
1314  */
1315  fnamecopy = strdup(fileName);
1316  if (fnamecopy == NULL)
1317  ereport(ERROR,
1318  (errcode(ERRCODE_OUT_OF_MEMORY),
1319  errmsg("out of memory")));
1320 
1321  file = AllocateVfd();
1322  vfdP = &VfdCache[file];
1323 
1324  /* Close excess kernel FDs. */
1325  ReleaseLruFiles();
1326 
1327  vfdP->fd = BasicOpenFile(fileName, fileFlags, fileMode);
1328 
1329  if (vfdP->fd < 0)
1330  {
1331  int save_errno = errno;
1332 
1333  FreeVfd(file);
1334  free(fnamecopy);
1335  errno = save_errno;
1336  return -1;
1337  }
1338  ++nfile;
1339  DO_DB(elog(LOG, "PathNameOpenFile: success %d",
1340  vfdP->fd));
1341 
1342  Insert(file);
1343 
1344  vfdP->fileName = fnamecopy;
1345  /* Saved flags are adjusted to be OK for re-opening file */
1346  vfdP->fileFlags = fileFlags & ~(O_CREAT | O_TRUNC | O_EXCL);
1347  vfdP->fileMode = fileMode;
1348  vfdP->seekPos = 0;
1349  vfdP->fileSize = 0;
1350  vfdP->fdstate = 0x0;
1351  vfdP->resowner = NULL;
1352 
1353  return file;
1354 }
#define DO_DB(A)
Definition: fd.c:152
static Vfd * VfdCache
Definition: fd.c:197
int errcode(int sqlerrcode)
Definition: elog.c:575
#define LOG
Definition: elog.h:26
int fileMode
Definition: fd.c:189
#define ERROR
Definition: elog.h:43
char * fileName
Definition: fd.c:186
static int nfile
Definition: fd.c:203
static File AllocateVfd(void)
Definition: fd.c:1172
off_t seekPos
Definition: fd.c:184
unsigned short fdstate
Definition: fd.c:179
Definition: fd.c:176
off_t fileSize
Definition: fd.c:185
int fd
Definition: fd.c:178
#define ereport(elevel, rest)
Definition: elog.h:122
static void Insert(File file)
Definition: fd.c:1044
ResourceOwner resowner
Definition: fd.c:180
static void ReleaseLruFiles(void)
Definition: fd.c:1162
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void FreeVfd(File file)
Definition: fd.c:1230
#define elog
Definition: elog.h:219
int fileFlags
Definition: fd.c:188
int File
Definition: fd.h:51
int BasicOpenFile(FileName fileName, int fileFlags, int fileMode)
Definition: fd.c:936
int pg_fdatasync ( int  fd)

Definition at line 385 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync().

386 {
387  if (enableFsync)
388  {
389 #ifdef HAVE_FDATASYNC
390  return fdatasync(fd);
391 #else
392  return fsync(fd);
393 #endif
394  }
395  else
396  return 0;
397 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define fsync(fd)
Definition: win32.h:62
bool enableFsync
Definition: globals.c:110
void pg_flush_data ( int  fd,
off_t  offset,
off_t  amount 
)

Definition at line 407 of file fd.c.

References enableFsync, ereport, errcode_for_file_access(), errmsg(), FATAL, MAP_FAILED, NULL, and WARNING.

Referenced by copy_file(), and FileWriteback().

408 {
409  /*
410  * Right now file flushing is primarily used to avoid making later
411  * fsync()/fdatasync() calls have less impact. Thus don't trigger flushes
412  * if fsyncs are disabled - that's a decision we might want to make
413  * configurable at some point.
414  */
415  if (!enableFsync)
416  return;
417 
418  /*
419  * We compile all alternatives that are supported on the current platform,
420  * to find portability problems more easily.
421  */
422 #if defined(HAVE_SYNC_FILE_RANGE)
423  {
424  int rc;
425 
426  /*
427  * sync_file_range(SYNC_FILE_RANGE_WRITE), currently linux specific,
428  * tells the OS that writeback for the specified blocks should be
429  * started, but that we don't want to wait for completion. Note that
430  * this call might block if too much dirty data exists in the range.
431  * This is the preferable method on OSs supporting it, as it works
432  * reliably when available (contrast to msync()) and doesn't flush out
433  * clean data (like FADV_DONTNEED).
434  */
435  rc = sync_file_range(fd, offset, nbytes,
436  SYNC_FILE_RANGE_WRITE);
437 
438  /* don't error out, this is just a performance optimization */
439  if (rc != 0)
440  {
443  errmsg("could not flush dirty data: %m")));
444  }
445 
446  return;
447  }
448 #endif
449 #if !defined(WIN32) && defined(MS_ASYNC)
450  {
451  void *p;
452  static int pagesize = 0;
453 
454  /*
455  * On several OSs msync(MS_ASYNC) on a mmap'ed file triggers
456  * writeback. On linux it only does so if MS_SYNC is specified, but
457  * then it does the writeback synchronously. Luckily all common linux
458  * systems have sync_file_range(). This is preferable over
459  * FADV_DONTNEED because it doesn't flush out clean data.
460  *
461  * We map the file (mmap()), tell the kernel to sync back the contents
462  * (msync()), and then remove the mapping again (munmap()).
463  */
464 
465  /* mmap() needs actual length if we want to map whole file */
466  if (offset == 0 && nbytes == 0)
467  {
468  nbytes = lseek(fd, 0, SEEK_END);
469  if (nbytes < 0)
470  {
473  errmsg("could not determine dirty data size: %m")));
474  return;
475  }
476  }
477 
478  /*
479  * Some platforms reject partial-page mmap() attempts. To deal with
480  * that, just truncate the request to a page boundary. If any extra
481  * bytes don't get flushed, well, it's only a hint anyway.
482  */
483 
484  /* fetch pagesize only once */
485  if (pagesize == 0)
486  pagesize = sysconf(_SC_PAGESIZE);
487 
488  /* align length to pagesize, dropping any fractional page */
489  if (pagesize > 0)
490  nbytes = (nbytes / pagesize) * pagesize;
491 
492  /* fractional-page request is a no-op */
493  if (nbytes <= 0)
494  return;
495 
496  /*
497  * mmap could well fail, particularly on 32-bit platforms where there
498  * may simply not be enough address space. If so, silently fall
499  * through to the next implementation.
500  */
501  if (nbytes <= (off_t) SSIZE_MAX)
502  p = mmap(NULL, nbytes, PROT_READ, MAP_SHARED, fd, offset);
503  else
504  p = MAP_FAILED;
505 
506  if (p != MAP_FAILED)
507  {
508  int rc;
509 
510  rc = msync(p, (size_t) nbytes, MS_ASYNC);
511  if (rc != 0)
512  {
515  errmsg("could not flush dirty data: %m")));
516  /* NB: need to fall through to munmap()! */
517  }
518 
519  rc = munmap(p, (size_t) nbytes);
520  if (rc != 0)
521  {
522  /* FATAL error because mapping would remain */
523  ereport(FATAL,
525  errmsg("could not munmap() while flushing data: %m")));
526  }
527 
528  return;
529  }
530  }
531 #endif
532 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
533  {
534  int rc;
535 
536  /*
537  * Signal the kernel that the passed in range should not be cached
538  * anymore. This has the, desired, side effect of writing out dirty
539  * data, and the, undesired, side effect of likely discarding useful
540  * clean cached blocks. For the latter reason this is the least
541  * preferable method.
542  */
543 
544  rc = posix_fadvise(fd, offset, nbytes, POSIX_FADV_DONTNEED);
545 
546  if (rc != 0)
547  {
548  /* don't error out, this is just a performance optimization */
551  errmsg("could not flush dirty data: %m")));
552  }
553 
554  return;
555  }
556 #endif
557 }
#define MAP_FAILED
Definition: mem.h:45
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define FATAL
Definition: elog.h:52
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
#define WARNING
Definition: elog.h:40
#define NULL
Definition: c.h:229
bool enableFsync
Definition: globals.c:110
int errmsg(const char *fmt,...)
Definition: elog.c:797
int pg_fsync ( int  fd)

Definition at line 333 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(), CheckPointLogicalRewriteHeap(), CreateLockFile(), do_pg_start_backup(), durable_rename(), FileSync(), fsync_fname_ext(), heap_xlog_logical_rewrite(), RecreateTwoPhaseFile(), RestoreSlotFromDisk(), SaveSlotToPath(), SimpleLruFlush(), SlruPhysicalWritePage(), SnapBuildSerialize(), UpdateControlFile(), write_auto_conf_file(), write_relmap_file(), WriteControlFile(), writeTimeLineHistory(), writeTimeLineHistoryFile(), XLogFileCopy(), and XLogFileInit().

334 {
335  /* #if is to skip the sync_method test if there's no need for it */
336 #if defined(HAVE_FSYNC_WRITETHROUGH) && !defined(FSYNC_WRITETHROUGH_IS_FSYNC)
338  return pg_fsync_writethrough(fd);
339  else
340 #endif
342 }
#define SYNC_METHOD_FSYNC_WRITETHROUGH
Definition: xlog.h:28
int pg_fsync_writethrough(int fd)
Definition: fd.c:362
int pg_fsync_no_writethrough(int fd)
Definition: fd.c:350
static int fd(const char *x, int i)
Definition: preproc-init.c:105
int sync_method
Definition: xlog.c:103
int pg_fsync_no_writethrough ( int  fd)

Definition at line 350 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync(), and pg_fsync().

351 {
352  if (enableFsync)
353  return fsync(fd);
354  else
355  return 0;
356 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define fsync(fd)
Definition: win32.h:62
bool enableFsync
Definition: globals.c:110
int pg_fsync_writethrough ( int  fd)

Definition at line 362 of file fd.c.

References enableFsync.

Referenced by issue_xlog_fsync(), pg_fsync(), and test_sync().

363 {
364  if (enableFsync)
365  {
366 #ifdef WIN32
367  return _commit(fd);
368 #elif defined(F_FULLFSYNC)
369  return (fcntl(fd, F_FULLFSYNC, 0) == -1) ? -1 : 0;
370 #else
371  errno = ENOSYS;
372  return -1;
373 #endif
374  }
375  else
376  return 0;
377 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
bool enableFsync
Definition: globals.c:110
void RemovePgTempFiles ( void  )

Definition at line 2706 of file fd.c.

References AllocateDir(), dirent::d_name, FreeDir(), MAXPGPATH, NULL, PG_TEMP_FILES_DIR, ReadDir(), RemovePgTempFilesInDir(), RemovePgTempRelationFiles(), snprintf(), and TABLESPACE_VERSION_DIRECTORY.

Referenced by PostmasterMain().

2707 {
2708  char temp_path[MAXPGPATH + 10 + sizeof(TABLESPACE_VERSION_DIRECTORY) + sizeof(PG_TEMP_FILES_DIR)];
2709  DIR *spc_dir;
2710  struct dirent *spc_de;
2711 
2712  /*
2713  * First process temp files in pg_default ($PGDATA/base)
2714  */
2715  snprintf(temp_path, sizeof(temp_path), "base/%s", PG_TEMP_FILES_DIR);
2716  RemovePgTempFilesInDir(temp_path);
2717  RemovePgTempRelationFiles("base");
2718 
2719  /*
2720  * Cycle through temp directories for all non-default tablespaces.
2721  */
2722  spc_dir = AllocateDir("pg_tblspc");
2723 
2724  while ((spc_de = ReadDir(spc_dir, "pg_tblspc")) != NULL)
2725  {
2726  if (strcmp(spc_de->d_name, ".") == 0 ||
2727  strcmp(spc_de->d_name, "..") == 0)
2728  continue;
2729 
2730  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s/%s",
2732  RemovePgTempFilesInDir(temp_path);
2733 
2734  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s",
2736  RemovePgTempRelationFiles(temp_path);
2737  }
2738 
2739  FreeDir(spc_dir);
2740 
2741  /*
2742  * In EXEC_BACKEND case there is a pgsql_tmp directory at the top level of
2743  * DataDir as well.
2744  */
2745 #ifdef EXEC_BACKEND
2747 #endif
2748 }
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
static void RemovePgTempFilesInDir(const char *tmpdirname)
Definition: fd.c:2752
Definition: dirent.h:9
static void RemovePgTempRelationFiles(const char *tsdirname)
Definition: fd.c:2793
Definition: dirent.c:25
#define MAXPGPATH
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2335
#define PG_TEMP_FILES_DIR
Definition: fd.h:127
#define NULL
Definition: c.h:229
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2401
#define TABLESPACE_VERSION_DIRECTORY
Definition: catalog.h:26
char d_name[MAX_PATH]
Definition: dirent.h:14
int FreeDir(DIR *dir)
Definition: fd.c:2444
void set_max_safe_fds ( void  )

Definition at line 881 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().

882 {
883  int usable_fds;
884  int already_open;
885 
886  /*----------
887  * We want to set max_safe_fds to
888  * MIN(usable_fds, max_files_per_process - already_open)
889  * less the slop factor for files that are opened without consulting
890  * fd.c. This ensures that we won't exceed either max_files_per_process
891  * or the experimentally-determined EMFILE limit.
892  *----------
893  */
895  &usable_fds, &already_open);
896 
897  max_safe_fds = Min(usable_fds, max_files_per_process - already_open);
898 
899  /*
900  * Take off the FDs reserved for system() etc.
901  */
903 
904  /*
905  * Make sure we still have enough to get by.
906  */
907  if (max_safe_fds < FD_MINFREE)
908  ereport(FATAL,
909  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
910  errmsg("insufficient file descriptors available to start server process"),
911  errdetail("System allows %d, we need at least %d.",
914 
915  elog(DEBUG2, "max_safe_fds = %d, usable_fds = %d, already_open = %d",
916  max_safe_fds, usable_fds, already_open);
917 }
static void count_usable_fds(int max_to_probe, int *usable_fds, int *already_open)
Definition: fd.c:797
#define NUM_RESERVED_FDS
Definition: fd.c:111
int max_safe_fds
Definition: fd.c:139
#define Min(x, y)
Definition: c.h:806
int errcode(int sqlerrcode)
Definition: elog.c:575
#define FATAL
Definition: elog.h:52
#define DEBUG2
Definition: elog.h:24
int errdetail(const char *fmt,...)
Definition: elog.c:873
int max_files_per_process
Definition: fd.c:126
#define ereport(elevel, rest)
Definition: elog.h:122
#define FD_MINFREE
Definition: fd.c:117
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
void SetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 2525 of file fd.c.

References Assert, nextTempTableSpace, numTempTableSpaces, random(), and tempTableSpaces.

Referenced by assign_temp_tablespaces(), and PrepareTempTablespaces().

2526 {
2527  Assert(numSpaces >= 0);
2528  tempTableSpaces = tableSpaces;
2529  numTempTableSpaces = numSpaces;
2530 
2531  /*
2532  * Select a random starting point in the list. This is to minimize
2533  * conflicts between backends that are most likely sharing the same list
2534  * of temp tablespaces. Note that if we create multiple temp files in the
2535  * same transaction, we'll advance circularly through the list --- this
2536  * ensures that large temporary sort files are nicely spread across all
2537  * available tablespaces.
2538  */
2539  if (numSpaces > 1)
2540  nextTempTableSpace = random() % numSpaces;
2541  else
2542  nextTempTableSpace = 0;
2543 }
long random(void)
Definition: random.c:22
static int numTempTableSpaces
Definition: fd.c:258
static int nextTempTableSpace
Definition: fd.c:259
#define Assert(condition)
Definition: c.h:675
static Oid * tempTableSpaces
Definition: fd.c:257
void SyncDataDirectory ( void  )

Definition at line 2933 of file fd.c.

References datadir_fsync_fname(), DEBUG1, enableFsync, ereport, errcode_for_file_access(), errmsg(), LOG, lstat, and walkdir().

Referenced by StartupXLOG().

2934 {
2935  bool xlog_is_symlink;
2936 
2937  /* We can skip this whole thing if fsync is disabled. */
2938  if (!enableFsync)
2939  return;
2940 
2941  /*
2942  * If pg_wal is a symlink, we'll need to recurse into it separately,
2943  * because the first walkdir below will ignore it.
2944  */
2945  xlog_is_symlink = false;
2946 
2947 #ifndef WIN32
2948  {
2949  struct stat st;
2950 
2951  if (lstat("pg_wal", &st) < 0)
2952  ereport(LOG,
2954  errmsg("could not stat file \"%s\": %m",
2955  "pg_wal")));
2956  else if (S_ISLNK(st.st_mode))
2957  xlog_is_symlink = true;
2958  }
2959 #else
2960  if (pgwin32_is_junction("pg_wal"))
2961  xlog_is_symlink = true;
2962 #endif
2963 
2964  /*
2965  * If possible, hint to the kernel that we're soon going to fsync the data
2966  * directory and its contents. Errors in this step are even less
2967  * interesting than normal, so log them only at DEBUG1.
2968  */
2969 #ifdef PG_FLUSH_DATA_WORKS
2970  walkdir(".", pre_sync_fname, false, DEBUG1);
2971  if (xlog_is_symlink)
2972  walkdir("pg_wal", pre_sync_fname, false, DEBUG1);
2973  walkdir("pg_tblspc", pre_sync_fname, true, DEBUG1);
2974 #endif
2975 
2976  /*
2977  * Now we do the fsync()s in the same order.
2978  *
2979  * The main call ignores symlinks, so in addition to specially processing
2980  * pg_wal if it's a symlink, pg_tblspc has to be visited separately with
2981  * process_symlinks = true. Note that if there are any plain directories
2982  * in pg_tblspc, they'll get fsync'd twice. That's not an expected case
2983  * so we don't worry about optimizing it.
2984  */
2985  walkdir(".", datadir_fsync_fname, false, LOG);
2986  if (xlog_is_symlink)
2987  walkdir("pg_wal", datadir_fsync_fname, false, LOG);
2988  walkdir("pg_tblspc", datadir_fsync_fname, true, LOG);
2989 }
#define DEBUG1
Definition: elog.h:25
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
Definition: fd.c:3006
#define LOG
Definition: elog.h:26
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
static void datadir_fsync_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3108
bool enableFsync
Definition: globals.c:110
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define lstat(path, sb)
Definition: win32.h:262
bool TempTablespacesAreSet ( void  )

Definition at line 2553 of file fd.c.

References numTempTableSpaces.

Referenced by PrepareTempTablespaces().

2554 {
2555  return (numTempTableSpaces >= 0);
2556 }
static int numTempTableSpaces
Definition: fd.c:258

Variable Documentation

int max_files_per_process

Definition at line 126 of file fd.c.

Referenced by set_max_safe_fds().

int max_safe_fds

Definition at line 139 of file fd.c.

Referenced by ReleaseLruFiles(), reserveAllocatedDesc(), and set_max_safe_fds().