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)
 
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)
 
void FileWriteback (File file, off_t offset, off_t nbytes)
 
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_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 126 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 2284 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_start_backup(), pg_tablespace_databases(), pg_tzenumerate_next(), pg_tzenumerate_start(), pgarch_readyXlog(), pgstat_reset_remove_files(), PrescanPreparedTransactions(), RecoverPreparedTransactions(), RelationCacheInitFileRemove(), RelationCacheInitFileRemoveInDir(), RemoveNonParentXlogFiles(), RemoveOldXlogFiles(), RemovePgTempFiles(), RemovePgTempFilesInDir(), RemovePgTempRelationFiles(), RemovePgTempRelationFilesInDbspace(), ResetUnloggedRelations(), ResetUnloggedRelationsInDbspaceDir(), ResetUnloggedRelationsInTablespaceDir(), scan_directory_ci(), SendBaseBackup(), sendDir(), SlruScanDirectory(), StandbyRecoverPreparedTransactions(), StartupReorderBuffer(), StartupReplicationSlots(), UpdateLogicalMappings(), and walkdir().

2285 {
2286  DIR *dir;
2287 
2288  DO_DB(elog(LOG, "AllocateDir: Allocated %d (%s)",
2289  numAllocatedDescs, dirname));
2290 
2291  /* Can we allocate another non-virtual FD? */
2292  if (!reserveAllocatedDesc())
2293  ereport(ERROR,
2294  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2295  errmsg("exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"",
2296  maxAllocatedDescs, dirname)));
2297 
2298  /* Close excess kernel FDs. */
2299  ReleaseLruFiles();
2300 
2301 TryAgain:
2302  if ((dir = opendir(dirname)) != NULL)
2303  {
2305 
2306  desc->kind = AllocateDescDir;
2307  desc->desc.dir = dir;
2310  return desc->desc.dir;
2311  }
2312 
2313  if (errno == EMFILE || errno == ENFILE)
2314  {
2315  int save_errno = errno;
2316 
2317  ereport(LOG,
2318  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2319  errmsg("out of file descriptors: %m; release and retry")));
2320  errno = 0;
2321  if (ReleaseLruFile())
2322  goto TryAgain;
2323  errno = save_errno;
2324  }
2325 
2326  return NULL;
2327 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
DIR * dir
Definition: fd.c:238
#define DO_DB(A)
Definition: fd.c:152
int errcode(int sqlerrcode)
Definition: elog.c:575
static bool reserveAllocatedDesc(void)
Definition: fd.c:1970
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static bool ReleaseLruFile(void)
Definition: fd.c:1103
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:1125
#define NULL
Definition: c.h:226
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:648
SubTransactionId create_subid
Definition: fd.c:234
union AllocateDesc::@25 desc
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 2043 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(), 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().

2044 {
2045  FILE *file;
2046 
2047  DO_DB(elog(LOG, "AllocateFile: Allocated %d (%s)",
2049 
2050  /* Can we allocate another non-virtual FD? */
2051  if (!reserveAllocatedDesc())
2052  ereport(ERROR,
2053  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2054  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2055  maxAllocatedDescs, name)));
2056 
2057  /* Close excess kernel FDs. */
2058  ReleaseLruFiles();
2059 
2060 TryAgain:
2061  if ((file = fopen(name, mode)) != NULL)
2062  {
2064 
2065  desc->kind = AllocateDescFile;
2066  desc->desc.file = file;
2069  return desc->desc.file;
2070  }
2071 
2072  if (errno == EMFILE || errno == ENFILE)
2073  {
2074  int save_errno = errno;
2075 
2076  ereport(LOG,
2077  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2078  errmsg("out of file descriptors: %m; release and retry")));
2079  errno = 0;
2080  if (ReleaseLruFile())
2081  goto TryAgain;
2082  errno = save_errno;
2083  }
2084 
2085  return NULL;
2086 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
#define DO_DB(A)
Definition: fd.c:152
int errcode(int sqlerrcode)
Definition: elog.c:575
static bool reserveAllocatedDesc(void)
Definition: fd.c:1970
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static bool ReleaseLruFile(void)
Definition: fd.c:1103
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static void ReleaseLruFiles(void)
Definition: fd.c:1125
FILE * file
Definition: fd.c:237
#define NULL
Definition: c.h:226
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:648
SubTransactionId create_subid
Definition: fd.c:234
const char * name
Definition: encode.c:521
union AllocateDesc::@25 desc
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 2535 of file fd.c.

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

2537 {
2538  Index i;
2539 
2540  for (i = 0; i < numAllocatedDescs; i++)
2541  {
2542  if (allocatedDescs[i].create_subid == mySubid)
2543  {
2544  if (isCommit)
2545  allocatedDescs[i].create_subid = parentSubid;
2546  else
2547  {
2548  /* have to recheck the item after FreeDesc (ugly) */
2549  FreeDesc(&allocatedDescs[i--]);
2550  }
2551  }
2552  }
2553 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2187
unsigned int Index
Definition: c.h:362
SubTransactionId create_subid
Definition: fd.c:234
int i
static int numAllocatedDescs
Definition: fd.c:243
void AtEOXact_Files ( void  )

Definition at line 2566 of file fd.c.

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

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

2567 {
2568  CleanupTempFiles(false);
2570  numTempTableSpaces = -1;
2571 }
static int numTempTableSpaces
Definition: fd.c:258
static void CleanupTempFiles(bool isProcExit)
Definition: fd.c:2595
#define NULL
Definition: c.h:226
static Oid * tempTableSpaces
Definition: fd.c:257
int BasicOpenFile ( FileName  fileName,
int  fileFlags,
int  fileMode 
)

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

900 {
901  int fd;
902 
903 tryAgain:
904  fd = open(fileName, fileFlags, fileMode);
905 
906  if (fd >= 0)
907  return fd; /* success! */
908 
909  if (errno == EMFILE || errno == ENFILE)
910  {
911  int save_errno = errno;
912 
913  ereport(LOG,
914  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
915  errmsg("out of file descriptors: %m; release and retry")));
916  errno = 0;
917  if (ReleaseLruFile())
918  goto tryAgain;
919  errno = save_errno;
920  }
921 
922  return -1; /* failure */
923 }
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:1103
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
void closeAllVfds ( void  )

Definition at line 2448 of file fd.c.

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

Referenced by standard_ProcessUtility().

2449 {
2450  Index i;
2451 
2452  if (SizeVfdCache > 0)
2453  {
2454  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2455  for (i = 1; i < SizeVfdCache; i++)
2456  {
2457  if (!FileIsNotOpen(i))
2458  LruDelete(i);
2459  }
2460  }
2461 }
static Size SizeVfdCache
Definition: fd.c:198
static void LruDelete(File file)
Definition: fd.c:966
#define FileIsNotOpen(file)
Definition: fd.c:161
unsigned int Index
Definition: c.h:362
#define Assert(condition)
Definition: c.h:671
int i
int ClosePipeStream ( FILE *  file)

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

2420 {
2421  int i;
2422 
2423  DO_DB(elog(LOG, "ClosePipeStream: Allocated %d", numAllocatedDescs));
2424 
2425  /* Remove file from list of allocated files, if it's present */
2426  for (i = numAllocatedDescs; --i >= 0;)
2427  {
2428  AllocateDesc *desc = &allocatedDescs[i];
2429 
2430  if (desc->kind == AllocateDescPipe && desc->desc.file == file)
2431  return FreeDesc(desc);
2432  }
2433 
2434  /* Only get here if someone passes us a file not in allocatedDescs */
2435  elog(WARNING, "file passed to ClosePipeStream was not obtained from OpenPipeStream");
2436 
2437  return pclose(file);
2438 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
#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:2187
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:237
union AllocateDesc::@25 desc
int i
#define elog
Definition: elog.h:219
static int numAllocatedDescs
Definition: fd.c:243
int CloseTransientFile ( int  fd)

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

2255 {
2256  int i;
2257 
2258  DO_DB(elog(LOG, "CloseTransientFile: Allocated %d", numAllocatedDescs));
2259 
2260  /* Remove fd from list of allocated files, if it's present */
2261  for (i = numAllocatedDescs; --i >= 0;)
2262  {
2263  AllocateDesc *desc = &allocatedDescs[i];
2264 
2265  if (desc->kind == AllocateDescRawFD && desc->desc.fd == fd)
2266  return FreeDesc(desc);
2267  }
2268 
2269  /* Only get here if someone passes us a file not in allocatedDescs */
2270  elog(WARNING, "fd passed to CloseTransientFile was not obtained from OpenTransientFile");
2271 
2272  return close(fd);
2273 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
#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:2187
#define WARNING
Definition: elog.h:40
int fd
Definition: fd.c:239
union AllocateDesc::@25 desc
int i
#define elog
Definition: elog.h:219
#define close(a)
Definition: win32.h:17
static int numAllocatedDescs
Definition: fd.c:243
int durable_link_or_rename ( const char *  oldfile,
const char *  newfile,
int  loglevel 
)

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

676 {
677  /*
678  * Ensure that, if we crash directly after the rename/link, a file with
679  * valid contents is moved into place.
680  */
681  if (fsync_fname_ext(oldfile, false, false, elevel) != 0)
682  return -1;
683 
684 #if HAVE_WORKING_LINK
685  if (link(oldfile, newfile) < 0)
686  {
687  ereport(elevel,
689  errmsg("could not link file \"%s\" to \"%s\": %m",
690  oldfile, newfile)));
691  return -1;
692  }
693  unlink(oldfile);
694 #else
695  /* XXX: Add racy file existence check? */
696  if (rename(oldfile, newfile) < 0)
697  {
698  ereport(elevel,
700  errmsg("could not rename file \"%s\" to \"%s\": %m",
701  oldfile, newfile)));
702  return -1;
703  }
704 #endif
705 
706  /*
707  * Make change persistent in case of an OS crash, both the new entry and
708  * its parent directory need to be flushed.
709  */
710  if (fsync_fname_ext(newfile, false, false, elevel) != 0)
711  return -1;
712 
713  /* Same for parent directory */
714  if (fsync_parent_path(newfile, elevel) != 0)
715  return -1;
716 
717  return 0;
718 }
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:136
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:3075
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3145
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:2093
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:2254
static int elevel
Definition: vacuumlazy.c:136
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:3075
int pg_fsync(int fd)
Definition: fd.c:333
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3145
void FileClose ( File  file)

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

1457 {
1458  Vfd *vfdP;
1459 
1460  Assert(FileIsValid(file));
1461 
1462  DO_DB(elog(LOG, "FileClose: %d (%s)",
1463  file, VfdCache[file].fileName));
1464 
1465  vfdP = &VfdCache[file];
1466 
1467  if (!FileIsNotOpen(file))
1468  {
1469  /* close the file */
1470  if (close(vfdP->fd))
1471  elog(LOG, "could not close file \"%s\": %m", vfdP->fileName);
1472 
1473  --nfile;
1474  vfdP->fd = VFD_CLOSED;
1475 
1476  /* remove the file from the lru ring */
1477  Delete(file);
1478  }
1479 
1480  /*
1481  * Delete the file if it was temporary, and make a log entry if wanted
1482  */
1483  if (vfdP->fdstate & FD_TEMPORARY)
1484  {
1485  struct stat filestats;
1486  int stat_errno;
1487 
1488  /*
1489  * If we get an error, as could happen within the ereport/elog calls,
1490  * we'll come right back here during transaction abort. Reset the
1491  * flag to ensure that we can't get into an infinite loop. This code
1492  * is arranged to ensure that the worst-case consequence is failing to
1493  * emit log message(s), not failing to attempt the unlink.
1494  */
1495  vfdP->fdstate &= ~FD_TEMPORARY;
1496 
1497  /* Subtract its size from current usage (do first in case of error) */
1498  temporary_files_size -= vfdP->fileSize;
1499  vfdP->fileSize = 0;
1500 
1501  /* first try the stat() */
1502  if (stat(vfdP->fileName, &filestats))
1503  stat_errno = errno;
1504  else
1505  stat_errno = 0;
1506 
1507  /* in any case do the unlink */
1508  if (unlink(vfdP->fileName))
1509  elog(LOG, "could not unlink file \"%s\": %m", vfdP->fileName);
1510 
1511  /* and last report the stat results */
1512  if (stat_errno == 0)
1513  {
1514  pgstat_report_tempfile(filestats.st_size);
1515 
1516  if (log_temp_files >= 0)
1517  {
1518  if ((filestats.st_size / 1024) >= log_temp_files)
1519  ereport(LOG,
1520  (errmsg("temporary file: path \"%s\", size %lu",
1521  vfdP->fileName,
1522  (unsigned long) filestats.st_size)));
1523  }
1524  }
1525  else
1526  {
1527  errno = stat_errno;
1528  elog(LOG, "could not stat file \"%s\": %m", vfdP->fileName);
1529  }
1530  }
1531 
1532  /* Unregister it from the resource owner */
1533  if (vfdP->resowner)
1534  ResourceOwnerForgetFile(vfdP->resowner, file);
1535 
1536  /*
1537  * Return the Vfd slot to the free list
1538  */
1539  FreeVfd(file);
1540 }
#define DO_DB(A)
Definition: fd.c:152
int log_temp_files
Definition: guc.c:456
static Vfd * VfdCache
Definition: fd.c:197
static void Delete(File file)
Definition: fd.c:947
void pgstat_report_tempfile(size_t filesize)
Definition: pgstat.c:1449
#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:671
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void FreeVfd(File file)
Definition: fd.c:1193
#define elog
Definition: elog.h:219
#define close(a)
Definition: win32.h:17
void ResourceOwnerForgetFile(ResourceOwner owner, File file)
Definition: resowner.c:1209
int FileGetRawDesc ( File  file)

Definition at line 1939 of file fd.c.

References Assert, vfd::fd, and FileIsValid.

1940 {
1941  Assert(FileIsValid(file));
1942  return VfdCache[file].fd;
1943 }
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:671
int FileGetRawFlags ( File  file)

Definition at line 1949 of file fd.c.

References Assert, vfd::fileFlags, and FileIsValid.

1950 {
1951  Assert(FileIsValid(file));
1952  return VfdCache[file].fileFlags;
1953 }
static Vfd * VfdCache
Definition: fd.c:197
#define FileIsValid(file)
Definition: fd.c:158
#define Assert(condition)
Definition: c.h:671
int fileFlags
Definition: fd.c:188
int FileGetRawMode ( File  file)

Definition at line 1959 of file fd.c.

References Assert, FileIsValid, and vfd::fileMode.

1960 {
1961  Assert(FileIsValid(file));
1962  return VfdCache[file].fileMode;
1963 }
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:671
char* FilePathName ( File  file)

Definition at line 1923 of file fd.c.

References Assert, FileIsValid, and vfd::fileName.

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

1924 {
1925  Assert(FileIsValid(file));
1926 
1927  return VfdCache[file].fileName;
1928 }
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:671
int FilePrefetch ( File  file,
off_t  offset,
int  amount 
)

Definition at line 1553 of file fd.c.

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

Referenced by mdprefetch().

1554 {
1555 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
1556  int returnCode;
1557 
1558  Assert(FileIsValid(file));
1559 
1560  DO_DB(elog(LOG, "FilePrefetch: %d (%s) " INT64_FORMAT " %d",
1561  file, VfdCache[file].fileName,
1562  (int64) offset, amount));
1563 
1564  returnCode = FileAccess(file);
1565  if (returnCode < 0)
1566  return returnCode;
1567 
1568  returnCode = posix_fadvise(VfdCache[file].fd, offset, amount,
1569  POSIX_FADV_WILLNEED);
1570 
1571  return returnCode;
1572 #else
1573  Assert(FileIsValid(file));
1574  return 0;
1575 #endif
1576 }
#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
#define FileIsValid(file)
Definition: fd.c:158
static int FileAccess(File file)
Definition: fd.c:1213
#define Assert(condition)
Definition: c.h:671
#define INT64_FORMAT
Definition: c.h:312
#define elog
Definition: elog.h:219
int FileRead ( File  file,
char *  buffer,
int  amount 
)

Definition at line 1604 of file fd.c.

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

Referenced by BufFileLoadBuffer(), and mdread().

1605 {
1606  int returnCode;
1607  Vfd *vfdP;
1608 
1609  Assert(FileIsValid(file));
1610 
1611  DO_DB(elog(LOG, "FileRead: %d (%s) " INT64_FORMAT " %d %p",
1612  file, VfdCache[file].fileName,
1613  (int64) VfdCache[file].seekPos,
1614  amount, buffer));
1615 
1616  returnCode = FileAccess(file);
1617  if (returnCode < 0)
1618  return returnCode;
1619 
1620  vfdP = &VfdCache[file];
1621 
1622 retry:
1623  returnCode = read(vfdP->fd, buffer, amount);
1624 
1625  if (returnCode >= 0)
1626  {
1627  /* if seekPos is unknown, leave it that way */
1628  if (!FilePosIsUnknown(vfdP->seekPos))
1629  vfdP->seekPos += returnCode;
1630  }
1631  else
1632  {
1633  /*
1634  * Windows may run out of kernel buffers and return "Insufficient
1635  * system resources" error. Wait a bit and retry to solve it.
1636  *
1637  * It is rumored that EINTR is also possible on some Unix filesystems,
1638  * in which case immediate retry is indicated.
1639  */
1640 #ifdef WIN32
1641  DWORD error = GetLastError();
1642 
1643  switch (error)
1644  {
1645  case ERROR_NO_SYSTEM_RESOURCES:
1646  pg_usleep(1000L);
1647  errno = EINTR;
1648  break;
1649  default:
1650  _dosmaperr(error);
1651  break;
1652  }
1653 #endif
1654  /* OK to retry if interrupted */
1655  if (errno == EINTR)
1656  goto retry;
1657 
1658  /* Trouble, so assume we don't know the file position anymore */
1659  vfdP->seekPos = FileUnknownPos;
1660  }
1661 
1662  return returnCode;
1663 }
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
off_t seekPos
Definition: fd.c:184
Definition: fd.c:176
int fd
Definition: fd.c:178
#define EINTR
Definition: win32.h:295
#define FileIsValid(file)
Definition: fd.c:158
static int FileAccess(File file)
Definition: fd.c:1213
#define Assert(condition)
Definition: c.h:671
void _dosmaperr(unsigned long)
Definition: win32error.c:171
#define INT64_FORMAT
Definition: c.h:312
#define elog
Definition: elog.h:219
#define FileUnknownPos
Definition: fd.c:169
#define read(a, b, c)
Definition: win32.h:18
off_t FileSeek ( File  file,
off_t  offset,
int  whence 
)

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

1803 {
1804  Vfd *vfdP;
1805 
1806  Assert(FileIsValid(file));
1807 
1808  DO_DB(elog(LOG, "FileSeek: %d (%s) " INT64_FORMAT " " INT64_FORMAT " %d",
1809  file, VfdCache[file].fileName,
1810  (int64) VfdCache[file].seekPos,
1811  (int64) offset, whence));
1812 
1813  vfdP = &VfdCache[file];
1814 
1815  if (FileIsNotOpen(file))
1816  {
1817  switch (whence)
1818  {
1819  case SEEK_SET:
1820  if (offset < 0)
1821  {
1822  errno = EINVAL;
1823  return (off_t) -1;
1824  }
1825  vfdP->seekPos = offset;
1826  break;
1827  case SEEK_CUR:
1828  if (FilePosIsUnknown(vfdP->seekPos) ||
1829  vfdP->seekPos + offset < 0)
1830  {
1831  errno = EINVAL;
1832  return (off_t) -1;
1833  }
1834  vfdP->seekPos += offset;
1835  break;
1836  case SEEK_END:
1837  if (FileAccess(file) < 0)
1838  return (off_t) -1;
1839  vfdP->seekPos = lseek(vfdP->fd, offset, whence);
1840  break;
1841  default:
1842  elog(ERROR, "invalid whence: %d", whence);
1843  break;
1844  }
1845  }
1846  else
1847  {
1848  switch (whence)
1849  {
1850  case SEEK_SET:
1851  if (offset < 0)
1852  {
1853  errno = EINVAL;
1854  return (off_t) -1;
1855  }
1856  if (vfdP->seekPos != offset)
1857  vfdP->seekPos = lseek(vfdP->fd, offset, whence);
1858  break;
1859  case SEEK_CUR:
1860  if (offset != 0 || FilePosIsUnknown(vfdP->seekPos))
1861  vfdP->seekPos = lseek(vfdP->fd, offset, whence);
1862  break;
1863  case SEEK_END:
1864  vfdP->seekPos = lseek(vfdP->fd, offset, whence);
1865  break;
1866  default:
1867  elog(ERROR, "invalid whence: %d", whence);
1868  break;
1869  }
1870  }
1871 
1872  return vfdP->seekPos;
1873 }
#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:1213
#define Assert(condition)
Definition: c.h:671
#define INT64_FORMAT
Definition: c.h:312
#define elog
Definition: elog.h:219
int FileSync ( File  file)

Definition at line 1785 of file fd.c.

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

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

1786 {
1787  int returnCode;
1788 
1789  Assert(FileIsValid(file));
1790 
1791  DO_DB(elog(LOG, "FileSync: %d (%s)",
1792  file, VfdCache[file].fileName));
1793 
1794  returnCode = FileAccess(file);
1795  if (returnCode < 0)
1796  return returnCode;
1797 
1798  return pg_fsync(VfdCache[file].fd);
1799 }
#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
#define FileIsValid(file)
Definition: fd.c:158
static int FileAccess(File file)
Definition: fd.c:1213
#define Assert(condition)
Definition: c.h:671
int pg_fsync(int fd)
Definition: fd.c:333
#define elog
Definition: elog.h:219
int FileTruncate ( File  file,
off_t  offset 
)

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

1891 {
1892  int returnCode;
1893 
1894  Assert(FileIsValid(file));
1895 
1896  DO_DB(elog(LOG, "FileTruncate %d (%s)",
1897  file, VfdCache[file].fileName));
1898 
1899  returnCode = FileAccess(file);
1900  if (returnCode < 0)
1901  return returnCode;
1902 
1903  returnCode = ftruncate(VfdCache[file].fd, offset);
1904 
1905  if (returnCode == 0 && VfdCache[file].fileSize > offset)
1906  {
1907  /* adjust our state for truncation of a temp file */
1908  Assert(VfdCache[file].fdstate & FD_TEMPORARY);
1909  temporary_files_size -= VfdCache[file].fileSize - offset;
1910  VfdCache[file].fileSize = offset;
1911  }
1912 
1913  return returnCode;
1914 }
#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
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:67
static int FileAccess(File file)
Definition: fd.c:1213
#define Assert(condition)
Definition: c.h:671
#define elog
Definition: elog.h:219
int FileWrite ( File  file,
char *  buffer,
int  amount 
)

Definition at line 1666 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(), vfd::seekPos, temp_file_limit, temporary_files_size, and write.

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

1667 {
1668  int returnCode;
1669  Vfd *vfdP;
1670 
1671  Assert(FileIsValid(file));
1672 
1673  DO_DB(elog(LOG, "FileWrite: %d (%s) " INT64_FORMAT " %d %p",
1674  file, VfdCache[file].fileName,
1675  (int64) VfdCache[file].seekPos,
1676  amount, buffer));
1677 
1678  returnCode = FileAccess(file);
1679  if (returnCode < 0)
1680  return returnCode;
1681 
1682  vfdP = &VfdCache[file];
1683 
1684  /*
1685  * If enforcing temp_file_limit and it's a temp file, check to see if the
1686  * write would overrun temp_file_limit, and throw error if so. Note: it's
1687  * really a modularity violation to throw error here; we should set errno
1688  * and return -1. However, there's no way to report a suitable error
1689  * message if we do that. All current callers would just throw error
1690  * immediately anyway, so this is safe at present.
1691  */
1692  if (temp_file_limit >= 0 && (vfdP->fdstate & FD_TEMPORARY))
1693  {
1694  off_t newPos;
1695 
1696  /*
1697  * Normally we should know the seek position, but if for some reason
1698  * we have lost track of it, try again to get it. Here, it's fine to
1699  * throw an error if we still can't get it.
1700  */
1701  if (FilePosIsUnknown(vfdP->seekPos))
1702  {
1703  vfdP->seekPos = lseek(vfdP->fd, (off_t) 0, SEEK_CUR);
1704  if (FilePosIsUnknown(vfdP->seekPos))
1705  elog(ERROR, "could not seek file \"%s\": %m", vfdP->fileName);
1706  }
1707 
1708  newPos = vfdP->seekPos + amount;
1709  if (newPos > vfdP->fileSize)
1710  {
1711  uint64 newTotal = temporary_files_size;
1712 
1713  newTotal += newPos - vfdP->fileSize;
1714  if (newTotal > (uint64) temp_file_limit * (uint64) 1024)
1715  ereport(ERROR,
1716  (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
1717  errmsg("temporary file size exceeds temp_file_limit (%dkB)",
1718  temp_file_limit)));
1719  }
1720  }
1721 
1722 retry:
1723  errno = 0;
1724  returnCode = write(vfdP->fd, buffer, amount);
1725 
1726  /* if write didn't set errno, assume problem is no disk space */
1727  if (returnCode != amount && errno == 0)
1728  errno = ENOSPC;
1729 
1730  if (returnCode >= 0)
1731  {
1732  /* if seekPos is unknown, leave it that way */
1733  if (!FilePosIsUnknown(vfdP->seekPos))
1734  vfdP->seekPos += returnCode;
1735 
1736  /*
1737  * Maintain fileSize and temporary_files_size if it's a temp file.
1738  *
1739  * If seekPos is -1 (unknown), this will do nothing; but we could only
1740  * get here in that state if we're not enforcing temporary_files_size,
1741  * so we don't care.
1742  */
1743  if (vfdP->fdstate & FD_TEMPORARY)
1744  {
1745  off_t newPos = vfdP->seekPos;
1746 
1747  if (newPos > vfdP->fileSize)
1748  {
1749  temporary_files_size += newPos - vfdP->fileSize;
1750  vfdP->fileSize = newPos;
1751  }
1752  }
1753  }
1754  else
1755  {
1756  /*
1757  * See comments in FileRead()
1758  */
1759 #ifdef WIN32
1760  DWORD error = GetLastError();
1761 
1762  switch (error)
1763  {
1764  case ERROR_NO_SYSTEM_RESOURCES:
1765  pg_usleep(1000L);
1766  errno = EINTR;
1767  break;
1768  default:
1769  _dosmaperr(error);
1770  break;
1771  }
1772 #endif
1773  /* OK to retry if interrupted */
1774  if (errno == EINTR)
1775  goto retry;
1776 
1777  /* Trouble, so assume we don't know the file position anymore */
1778  vfdP->seekPos = FileUnknownPos;
1779  }
1780 
1781  return returnCode;
1782 }
static void error(void)
Definition: sql-dyntest.c:147
#define write(a, b, c)
Definition: win32.h:19
#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
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:295
#define FileIsValid(file)
Definition: fd.c:158
static uint64 temporary_files_size
Definition: fd.c:217
static int FileAccess(File file)
Definition: fd.c:1213
#define Assert(condition)
Definition: c.h:671
void _dosmaperr(unsigned long)
Definition: win32error.c:171
#define INT64_FORMAT
Definition: c.h:312
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:459
void FileWriteback ( File  file,
off_t  offset,
off_t  nbytes 
)

Definition at line 1579 of file fd.c.

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

Referenced by mdwriteback().

1580 {
1581  int returnCode;
1582 
1583  Assert(FileIsValid(file));
1584 
1585  DO_DB(elog(LOG, "FileWriteback: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
1586  file, VfdCache[file].fileName,
1587  (int64) offset, (int64) nbytes));
1588 
1589  /*
1590  * Caution: do not call pg_flush_data with nbytes = 0, it could trash the
1591  * file's seek position. We prefer to define that as a no-op here.
1592  */
1593  if (nbytes <= 0)
1594  return;
1595 
1596  returnCode = FileAccess(file);
1597  if (returnCode < 0)
1598  return;
1599 
1600  pg_flush_data(VfdCache[file].fd, offset, nbytes);
1601 }
#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
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:1213
#define Assert(condition)
Definition: c.h:671
#define INT64_FORMAT
Definition: c.h:312
#define elog
Definition: elog.h:219
int FreeDir ( DIR dir)

Definition at line 2393 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_start_backup(), pg_tablespace_databases(), pg_tzenumerate_end(), pg_tzenumerate_next(), pgarch_readyXlog(), pgstat_reset_remove_files(), PrescanPreparedTransactions(), RecoverPreparedTransactions(), RelationCacheInitFileRemove(), RelationCacheInitFileRemoveInDir(), RemoveNonParentXlogFiles(), RemoveOldXlogFiles(), RemovePgTempFiles(), RemovePgTempFilesInDir(), RemovePgTempRelationFiles(), RemovePgTempRelationFilesInDbspace(), ResetUnloggedRelations(), ResetUnloggedRelationsInDbspaceDir(), ResetUnloggedRelationsInTablespaceDir(), scan_directory_ci(), SendBaseBackup(), sendDir(), SlruScanDirectory(), StandbyRecoverPreparedTransactions(), StartupReorderBuffer(), StartupReplicationSlots(), UpdateLogicalMappings(), and walkdir().

2394 {
2395  int i;
2396 
2397  DO_DB(elog(LOG, "FreeDir: Allocated %d", numAllocatedDescs));
2398 
2399  /* Remove dir from list of allocated dirs, if it's present */
2400  for (i = numAllocatedDescs; --i >= 0;)
2401  {
2402  AllocateDesc *desc = &allocatedDescs[i];
2403 
2404  if (desc->kind == AllocateDescDir && desc->desc.dir == dir)
2405  return FreeDesc(desc);
2406  }
2407 
2408  /* Only get here if someone passes us a dir not in allocatedDescs */
2409  elog(WARNING, "dir passed to FreeDir was not obtained from AllocateDir");
2410 
2411  return closedir(dir);
2412 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
DIR * dir
Definition: fd.c:238
#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:2187
#define WARNING
Definition: elog.h:40
union AllocateDesc::@25 desc
int i
#define elog
Definition: elog.h:219
static int numAllocatedDescs
Definition: fd.c:243
int FreeFile ( FILE *  file)

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

2227 {
2228  int i;
2229 
2230  DO_DB(elog(LOG, "FreeFile: Allocated %d", numAllocatedDescs));
2231 
2232  /* Remove file from list of allocated files, if it's present */
2233  for (i = numAllocatedDescs; --i >= 0;)
2234  {
2235  AllocateDesc *desc = &allocatedDescs[i];
2236 
2237  if (desc->kind == AllocateDescFile && desc->desc.file == file)
2238  return FreeDesc(desc);
2239  }
2240 
2241  /* Only get here if someone passes us a file not in allocatedDescs */
2242  elog(WARNING, "file passed to FreeFile was not obtained from AllocateFile");
2243 
2244  return fclose(file);
2245 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
#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:2187
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:237
union AllocateDesc::@25 desc
int i
#define elog
Definition: elog.h:219
static int numAllocatedDescs
Definition: fd.c:243
void fsync_fname ( const char *  fname,
bool  isdir 
)

Definition at line 567 of file fd.c.

References ERROR, and fsync_fname_ext().

Referenced by BaseBackup(), copydir(), CreateSlotOnDisk(), dir_close(), dir_finish(), dir_open_for_write(), ReceiveTarFile(), ReplicationSlotDropPtr(), ResetUnloggedRelationsInDbspaceDir(), RestoreSlotFromDisk(), SaveSlotToPath(), SnapBuildRestore(), SnapBuildSerialize(), StartupReplicationSlots(), and tar_finish().

568 {
569  fsync_fname_ext(fname, isdir, false, ERROR);
570 }
#define ERROR
Definition: elog.h:43
static int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3075
Oid GetNextTempTableSpace ( void  )

Definition at line 2514 of file fd.c.

References InvalidOid, nextTempTableSpace, numTempTableSpaces, and tempTableSpaces.

Referenced by GetDefaultTablespace(), and OpenTemporaryFile().

2515 {
2516  if (numTempTableSpaces > 0)
2517  {
2518  /* Advance nextTempTableSpace counter with wraparound */
2520  nextTempTableSpace = 0;
2522  }
2523  return InvalidOid;
2524 }
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 727 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().

728 {
729  Assert(SizeVfdCache == 0); /* call me only once */
730 
731  /* initialize cache header entry */
732  VfdCache = (Vfd *) malloc(sizeof(Vfd));
733  if (VfdCache == NULL)
734  ereport(FATAL,
735  (errcode(ERRCODE_OUT_OF_MEMORY),
736  errmsg("out of memory")));
737 
738  MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));
740 
741  SizeVfdCache = 1;
742 
743  /* register proc-exit hook to ensure temp files are dropped at exit */
745 }
static void AtProcExit_Files(int code, Datum arg)
Definition: fd.c:2580
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:853
#define malloc(a)
Definition: header.h:45
#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:226
#define Assert(condition)
Definition: c.h:671
int errmsg(const char *fmt,...)
Definition: elog.c:797
FILE* OpenPipeStream ( const char *  command,
const char *  mode 
)

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

2134 {
2135  FILE *file;
2136 
2137  DO_DB(elog(LOG, "OpenPipeStream: Allocated %d (%s)",
2138  numAllocatedDescs, command));
2139 
2140  /* Can we allocate another non-virtual FD? */
2141  if (!reserveAllocatedDesc())
2142  ereport(ERROR,
2143  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2144  errmsg("exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"",
2145  maxAllocatedDescs, command)));
2146 
2147  /* Close excess kernel FDs. */
2148  ReleaseLruFiles();
2149 
2150 TryAgain:
2151  fflush(stdout);
2152  fflush(stderr);
2153  errno = 0;
2154  if ((file = popen(command, mode)) != NULL)
2155  {
2157 
2158  desc->kind = AllocateDescPipe;
2159  desc->desc.file = file;
2162  return desc->desc.file;
2163  }
2164 
2165  if (errno == EMFILE || errno == ENFILE)
2166  {
2167  int save_errno = errno;
2168 
2169  ereport(LOG,
2170  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2171  errmsg("out of file descriptors: %m; release and retry")));
2172  errno = 0;
2173  if (ReleaseLruFile())
2174  goto TryAgain;
2175  errno = save_errno;
2176  }
2177 
2178  return NULL;
2179 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
#define DO_DB(A)
Definition: fd.c:152
int errcode(int sqlerrcode)
Definition: elog.c:575
static bool reserveAllocatedDesc(void)
Definition: fd.c:1970
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static bool ReleaseLruFile(void)
Definition: fd.c:1103
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static void ReleaseLruFiles(void)
Definition: fd.c:1125
FILE * file
Definition: fd.c:237
#define NULL
Definition: c.h:226
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:648
SubTransactionId create_subid
Definition: fd.c:234
union AllocateDesc::@25 desc
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 1334 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().

1335 {
1336  File file = 0;
1337 
1338  /*
1339  * If some temp tablespace(s) have been given to us, try to use the next
1340  * one. If a given tablespace can't be found, we silently fall back to
1341  * the database's default tablespace.
1342  *
1343  * BUT: if the temp file is slated to outlive the current transaction,
1344  * force it into the database's default tablespace, so that it will not
1345  * pose a threat to possible tablespace drop attempts.
1346  */
1347  if (numTempTableSpaces > 0 && !interXact)
1348  {
1349  Oid tblspcOid = GetNextTempTableSpace();
1350 
1351  if (OidIsValid(tblspcOid))
1352  file = OpenTemporaryFileInTablespace(tblspcOid, false);
1353  }
1354 
1355  /*
1356  * If not, or if tablespace is bad, create in database's default
1357  * tablespace. MyDatabaseTableSpace should normally be set before we get
1358  * here, but just in case it isn't, fall back to pg_default tablespace.
1359  */
1360  if (file <= 0)
1364  true);
1365 
1366  /* Mark it for deletion at close */
1367  VfdCache[file].fdstate |= FD_TEMPORARY;
1368 
1369  /* Register it with the current resource owner */
1370  if (!interXact)
1371  {
1373 
1377 
1378  /* ensure cleanup happens at eoxact */
1380  }
1381 
1382  return file;
1383 }
static File OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError)
Definition: fd.c:1390
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:534
Oid MyDatabaseTableSpace
Definition: globals.c:78
static bool have_xact_temporary_files
Definition: fd.c:209
Oid GetNextTempTableSpace(void)
Definition: fd.c:2514
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 2093 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().

2094 {
2095  int fd;
2096 
2097  DO_DB(elog(LOG, "OpenTransientFile: Allocated %d (%s)",
2098  numAllocatedDescs, fileName));
2099 
2100  /* Can we allocate another non-virtual FD? */
2101  if (!reserveAllocatedDesc())
2102  ereport(ERROR,
2103  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2104  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2105  maxAllocatedDescs, fileName)));
2106 
2107  /* Close excess kernel FDs. */
2108  ReleaseLruFiles();
2109 
2110  fd = BasicOpenFile(fileName, fileFlags, fileMode);
2111 
2112  if (fd >= 0)
2113  {
2115 
2116  desc->kind = AllocateDescRawFD;
2117  desc->desc.fd = fd;
2120 
2121  return fd;
2122  }
2123 
2124  return -1; /* failure */
2125 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
#define DO_DB(A)
Definition: fd.c:152
int errcode(int sqlerrcode)
Definition: elog.c:575
static bool reserveAllocatedDesc(void)
Definition: fd.c:1970
#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:1125
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:648
SubTransactionId create_subid
Definition: fd.c:234
int fd
Definition: fd.c:239
union AllocateDesc::@25 desc
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:899
File PathNameOpenFile ( FileName  fileName,
int  fileFlags,
int  fileMode 
)

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

1267 {
1268  char *fnamecopy;
1269  File file;
1270  Vfd *vfdP;
1271 
1272  DO_DB(elog(LOG, "PathNameOpenFile: %s %x %o",
1273  fileName, fileFlags, fileMode));
1274 
1275  /*
1276  * We need a malloc'd copy of the file name; fail cleanly if no room.
1277  */
1278  fnamecopy = strdup(fileName);
1279  if (fnamecopy == NULL)
1280  ereport(ERROR,
1281  (errcode(ERRCODE_OUT_OF_MEMORY),
1282  errmsg("out of memory")));
1283 
1284  file = AllocateVfd();
1285  vfdP = &VfdCache[file];
1286 
1287  /* Close excess kernel FDs. */
1288  ReleaseLruFiles();
1289 
1290  vfdP->fd = BasicOpenFile(fileName, fileFlags, fileMode);
1291 
1292  if (vfdP->fd < 0)
1293  {
1294  int save_errno = errno;
1295 
1296  FreeVfd(file);
1297  free(fnamecopy);
1298  errno = save_errno;
1299  return -1;
1300  }
1301  ++nfile;
1302  DO_DB(elog(LOG, "PathNameOpenFile: success %d",
1303  vfdP->fd));
1304 
1305  Insert(file);
1306 
1307  vfdP->fileName = fnamecopy;
1308  /* Saved flags are adjusted to be OK for re-opening file */
1309  vfdP->fileFlags = fileFlags & ~(O_CREAT | O_TRUNC | O_EXCL);
1310  vfdP->fileMode = fileMode;
1311  vfdP->seekPos = 0;
1312  vfdP->fileSize = 0;
1313  vfdP->fdstate = 0x0;
1314  vfdP->resowner = NULL;
1315 
1316  return file;
1317 }
#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:1135
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:1007
ResourceOwner resowner
Definition: fd.c:180
static void ReleaseLruFiles(void)
Definition: fd.c:1125
#define free(a)
Definition: header.h:60
#define NULL
Definition: c.h:226
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void FreeVfd(File file)
Definition: fd.c:1193
#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:899
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:70
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:226
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:102
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:70
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 2655 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().

2656 {
2657  char temp_path[MAXPGPATH];
2658  DIR *spc_dir;
2659  struct dirent *spc_de;
2660 
2661  /*
2662  * First process temp files in pg_default ($PGDATA/base)
2663  */
2664  snprintf(temp_path, sizeof(temp_path), "base/%s", PG_TEMP_FILES_DIR);
2665  RemovePgTempFilesInDir(temp_path);
2666  RemovePgTempRelationFiles("base");
2667 
2668  /*
2669  * Cycle through temp directories for all non-default tablespaces.
2670  */
2671  spc_dir = AllocateDir("pg_tblspc");
2672 
2673  while ((spc_de = ReadDir(spc_dir, "pg_tblspc")) != NULL)
2674  {
2675  if (strcmp(spc_de->d_name, ".") == 0 ||
2676  strcmp(spc_de->d_name, "..") == 0)
2677  continue;
2678 
2679  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s/%s",
2681  RemovePgTempFilesInDir(temp_path);
2682 
2683  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s",
2685  RemovePgTempRelationFiles(temp_path);
2686  }
2687 
2688  FreeDir(spc_dir);
2689 
2690  /*
2691  * In EXEC_BACKEND case there is a pgsql_tmp directory at the top level of
2692  * DataDir as well.
2693  */
2694 #ifdef EXEC_BACKEND
2696 #endif
2697 }
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
static void RemovePgTempFilesInDir(const char *tmpdirname)
Definition: fd.c:2701
Definition: dirent.h:9
static void RemovePgTempRelationFiles(const char *tsdirname)
Definition: fd.c:2742
Definition: dirent.c:25
#define MAXPGPATH
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2284
#define PG_TEMP_FILES_DIR
Definition: fd.h:126
#define NULL
Definition: c.h:226
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2350
#define TABLESPACE_VERSION_DIRECTORY
Definition: catalog.h:26
char d_name[MAX_PATH]
Definition: dirent.h:14
int FreeDir(DIR *dir)
Definition: fd.c:2393
void set_max_safe_fds ( void  )

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

845 {
846  int usable_fds;
847  int already_open;
848 
849  /*----------
850  * We want to set max_safe_fds to
851  * MIN(usable_fds, max_files_per_process - already_open)
852  * less the slop factor for files that are opened without consulting
853  * fd.c. This ensures that we won't exceed either max_files_per_process
854  * or the experimentally-determined EMFILE limit.
855  *----------
856  */
858  &usable_fds, &already_open);
859 
860  max_safe_fds = Min(usable_fds, max_files_per_process - already_open);
861 
862  /*
863  * Take off the FDs reserved for system() etc.
864  */
866 
867  /*
868  * Make sure we still have enough to get by.
869  */
870  if (max_safe_fds < FD_MINFREE)
871  ereport(FATAL,
872  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
873  errmsg("insufficient file descriptors available to start server process"),
874  errdetail("System allows %d, we need at least %d.",
877 
878  elog(DEBUG2, "max_safe_fds = %d, usable_fds = %d, already_open = %d",
879  max_safe_fds, usable_fds, already_open);
880 }
static void count_usable_fds(int max_to_probe, int *usable_fds, int *already_open)
Definition: fd.c:760
#define NUM_RESERVED_FDS
Definition: fd.c:111
int max_safe_fds
Definition: fd.c:139
#define Min(x, y)
Definition: c.h:802
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 2474 of file fd.c.

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

Referenced by assign_temp_tablespaces(), and PrepareTempTablespaces().

2475 {
2476  Assert(numSpaces >= 0);
2477  tempTableSpaces = tableSpaces;
2478  numTempTableSpaces = numSpaces;
2479 
2480  /*
2481  * Select a random starting point in the list. This is to minimize
2482  * conflicts between backends that are most likely sharing the same list
2483  * of temp tablespaces. Note that if we create multiple temp files in the
2484  * same transaction, we'll advance circularly through the list --- this
2485  * ensures that large temporary sort files are nicely spread across all
2486  * available tablespaces.
2487  */
2488  if (numSpaces > 1)
2489  nextTempTableSpace = random() % numSpaces;
2490  else
2491  nextTempTableSpace = 0;
2492 }
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:671
static Oid * tempTableSpaces
Definition: fd.c:257
void SyncDataDirectory ( void  )

Definition at line 2882 of file fd.c.

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

Referenced by StartupXLOG().

2883 {
2884  bool xlog_is_symlink;
2885 
2886  /* We can skip this whole thing if fsync is disabled. */
2887  if (!enableFsync)
2888  return;
2889 
2890  /*
2891  * If pg_wal is a symlink, we'll need to recurse into it separately,
2892  * because the first walkdir below will ignore it.
2893  */
2894  xlog_is_symlink = false;
2895 
2896 #ifndef WIN32
2897  {
2898  struct stat st;
2899 
2900  if (lstat("pg_wal", &st) < 0)
2901  ereport(LOG,
2903  errmsg("could not stat file \"%s\": %m",
2904  "pg_wal")));
2905  else if (S_ISLNK(st.st_mode))
2906  xlog_is_symlink = true;
2907  }
2908 #else
2909  if (pgwin32_is_junction("pg_wal"))
2910  xlog_is_symlink = true;
2911 #endif
2912 
2913  /*
2914  * If possible, hint to the kernel that we're soon going to fsync the data
2915  * directory and its contents. Errors in this step are even less
2916  * interesting than normal, so log them only at DEBUG1.
2917  */
2918 #ifdef PG_FLUSH_DATA_WORKS
2919  walkdir(".", pre_sync_fname, false, DEBUG1);
2920  if (xlog_is_symlink)
2921  walkdir("pg_wal", pre_sync_fname, false, DEBUG1);
2922  walkdir("pg_tblspc", pre_sync_fname, true, DEBUG1);
2923 #endif
2924 
2925  /*
2926  * Now we do the fsync()s in the same order.
2927  *
2928  * The main call ignores symlinks, so in addition to specially processing
2929  * pg_wal if it's a symlink, pg_tblspc has to be visited separately with
2930  * process_symlinks = true. Note that if there are any plain directories
2931  * in pg_tblspc, they'll get fsync'd twice. That's not an expected case
2932  * so we don't worry about optimizing it.
2933  */
2934  walkdir(".", datadir_fsync_fname, false, LOG);
2935  if (xlog_is_symlink)
2936  walkdir("pg_wal", datadir_fsync_fname, false, LOG);
2937  walkdir("pg_tblspc", datadir_fsync_fname, true, LOG);
2938 }
#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:2955
#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:3057
bool enableFsync
Definition: globals.c:110
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define lstat(path, sb)
Definition: win32.h:272
bool TempTablespacesAreSet ( void  )

Definition at line 2502 of file fd.c.

References numTempTableSpaces.

Referenced by PrepareTempTablespaces().

2503 {
2504  return (numTempTableSpaces >= 0);
2505 }
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().