PostgreSQL Source Code  git master
fd.c File Reference
#include "postgres.h"
#include <sys/file.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include "access/xact.h"
#include "access/xlog.h"
#include "catalog/pg_tablespace.h"
#include "common/file_perm.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "portability/mem.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "utils/guc.h"
#include "utils/resowner_private.h"
Include dependency graph for fd.c:

Go to the source code of this file.

Data Structures

struct  vfd
 
struct  AllocateDesc
 

Macros

#define NUM_RESERVED_FDS   10
 
#define FD_MINFREE   48
 
#define DO_DB(A)   ((void) 0)
 
#define VFD_CLOSED   (-1)
 
#define FileIsValid(file)   ((file) > 0 && (file) < (int) SizeVfdCache && VfdCache[file].fileName != NULL)
 
#define FileIsNotOpen(file)   (VfdCache[file].fd == VFD_CLOSED)
 
#define FD_DELETE_AT_CLOSE   (1 << 0) /* T = delete when closed */
 
#define FD_CLOSE_AT_EOXACT   (1 << 1) /* T = close at eoXact */
 
#define FD_TEMP_FILE_LIMIT   (1 << 2) /* T = respect temp_file_limit */
 

Typedefs

typedef struct vfd Vfd
 

Enumerations

enum  AllocateDescKind { AllocateDescFile, AllocateDescPipe, AllocateDescDir, AllocateDescRawFD }
 

Functions

static void Delete (File file)
 
static void LruDelete (File file)
 
static void Insert (File file)
 
static int LruInsert (File file)
 
static bool ReleaseLruFile (void)
 
static void ReleaseLruFiles (void)
 
static File AllocateVfd (void)
 
static void FreeVfd (File file)
 
static int FileAccess (File file)
 
static File OpenTemporaryFileInTablespace (Oid tblspcOid, bool rejectError)
 
static bool reserveAllocatedDesc (void)
 
static int FreeDesc (AllocateDesc *desc)
 
static void AtProcExit_Files (int code, Datum arg)
 
static void CleanupTempFiles (bool isCommit, bool isProcExit)
 
static void RemovePgTempRelationFiles (const char *tsdirname)
 
static void RemovePgTempRelationFilesInDbspace (const char *dbspacedirname)
 
static void walkdir (const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
 
static void datadir_fsync_fname (const char *fname, bool isdir, int elevel)
 
static void unlink_if_exists_fname (const char *fname, bool isdir, int elevel)
 
static int fsync_parent_path (const char *fname, int elevel)
 
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 nbytes)
 
void fsync_fname (const char *fname, bool isdir)
 
int durable_rename (const char *oldfile, const char *newfile, int elevel)
 
int durable_unlink (const char *fname, int elevel)
 
int durable_rename_excl (const char *oldfile, const char *newfile, int elevel)
 
void InitFileAccess (void)
 
static void count_usable_fds (int max_to_probe, int *usable_fds, int *already_open)
 
void set_max_safe_fds (void)
 
int BasicOpenFile (const char *fileName, int fileFlags)
 
int BasicOpenFilePerm (const char *fileName, int fileFlags, mode_t fileMode)
 
bool AcquireExternalFD (void)
 
void ReserveExternalFD (void)
 
void ReleaseExternalFD (void)
 
static void ReportTemporaryFileUsage (const char *path, off_t size)
 
static void RegisterTemporaryFile (File file)
 
File PathNameOpenFile (const char *fileName, int fileFlags)
 
File PathNameOpenFilePerm (const char *fileName, int fileFlags, mode_t fileMode)
 
void PathNameCreateTemporaryDir (const char *basedir, const char *directory)
 
void PathNameDeleteTemporaryDir (const char *dirname)
 
File OpenTemporaryFile (bool interXact)
 
void TempTablespacePath (char *path, Oid tablespace)
 
File PathNameCreateTemporaryFile (const char *path, bool error_on_failure)
 
File PathNameOpenTemporaryFile (const char *path)
 
bool PathNameDeleteTemporaryFile (const char *path, bool error_on_failure)
 
void FileClose (File file)
 
int FilePrefetch (File file, off_t offset, int amount, uint32 wait_event_info)
 
void FileWriteback (File file, off_t offset, off_t nbytes, uint32 wait_event_info)
 
int FileRead (File file, char *buffer, int amount, off_t offset, uint32 wait_event_info)
 
int FileWrite (File file, char *buffer, int amount, off_t offset, uint32 wait_event_info)
 
int FileSync (File file, uint32 wait_event_info)
 
off_t FileSize (File file)
 
int FileTruncate (File file, off_t offset, uint32 wait_event_info)
 
char * FilePathName (File file)
 
int FileGetRawDesc (File file)
 
int FileGetRawFlags (File file)
 
mode_t FileGetRawMode (File file)
 
FILE * AllocateFile (const char *name, const char *mode)
 
int OpenTransientFile (const char *fileName, int fileFlags)
 
int OpenTransientFilePerm (const char *fileName, int fileFlags, mode_t fileMode)
 
FILE * OpenPipeStream (const char *command, const char *mode)
 
int FreeFile (FILE *file)
 
int CloseTransientFile (int fd)
 
DIRAllocateDir (const char *dirname)
 
struct direntReadDir (DIR *dir, const char *dirname)
 
struct direntReadDirExtended (DIR *dir, const char *dirname, int elevel)
 
int FreeDir (DIR *dir)
 
int ClosePipeStream (FILE *file)
 
void closeAllVfds (void)
 
void SetTempTablespaces (Oid *tableSpaces, int numSpaces)
 
bool TempTablespacesAreSet (void)
 
int GetTempTablespaces (Oid *tableSpaces, int numSpaces)
 
Oid GetNextTempTableSpace (void)
 
void AtEOSubXact_Files (bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
 
void AtEOXact_Files (bool isCommit)
 
void RemovePgTempFiles (void)
 
void RemovePgTempFilesInDir (const char *tmpdirname, bool missing_ok, bool unlink_all)
 
bool looks_like_temp_rel_name (const char *name)
 
void SyncDataDirectory (void)
 
int fsync_fname_ext (const char *fname, bool isdir, bool ignore_perm, int elevel)
 
int MakePGDirectory (const char *directoryName)
 
int data_sync_elevel (int elevel)
 

Variables

int max_files_per_process = 1000
 
int max_safe_fds = FD_MINFREE
 
bool data_sync_retry = false
 
static VfdVfdCache
 
static Size SizeVfdCache = 0
 
static int nfile = 0
 
static bool have_xact_temporary_files = false
 
static uint64 temporary_files_size = 0
 
static int numAllocatedDescs = 0
 
static int maxAllocatedDescs = 0
 
static AllocateDescallocatedDescs = NULL
 
static int numExternalFDs = 0
 
static long tempFileCounter = 0
 
static OidtempTableSpaces = NULL
 
static int numTempTableSpaces = -1
 
static int nextTempTableSpace = 0
 

Macro Definition Documentation

◆ DO_DB

◆ FD_CLOSE_AT_EOXACT

#define FD_CLOSE_AT_EOXACT   (1 << 1) /* T = close at eoXact */

Definition at line 182 of file fd.c.

Referenced by CleanupTempFiles(), and RegisterTemporaryFile().

◆ FD_DELETE_AT_CLOSE

#define FD_DELETE_AT_CLOSE   (1 << 0) /* T = delete when closed */

Definition at line 181 of file fd.c.

Referenced by CleanupTempFiles(), FileClose(), and OpenTemporaryFile().

◆ FD_MINFREE

#define FD_MINFREE   48

Definition at line 133 of file fd.c.

Referenced by reserveAllocatedDesc(), and set_max_safe_fds().

◆ FD_TEMP_FILE_LIMIT

#define FD_TEMP_FILE_LIMIT   (1 << 2) /* T = respect temp_file_limit */

◆ FileIsNotOpen

#define FileIsNotOpen (   file)    (VfdCache[file].fd == VFD_CLOSED)

◆ FileIsValid

#define FileIsValid (   file)    ((file) > 0 && (file) < (int) SizeVfdCache && VfdCache[file].fileName != NULL)

◆ NUM_RESERVED_FDS

#define NUM_RESERVED_FDS   10

Definition at line 124 of file fd.c.

Referenced by set_max_safe_fds().

◆ VFD_CLOSED

#define VFD_CLOSED   (-1)

Definition at line 173 of file fd.c.

Referenced by AllocateVfd(), FileClose(), InitFileAccess(), and LruDelete().

Typedef Documentation

◆ Vfd

typedef struct vfd Vfd

Enumeration Type Documentation

◆ AllocateDescKind

Enumerator
AllocateDescFile 
AllocateDescPipe 
AllocateDescDir 
AllocateDescRawFD 

Definition at line 231 of file fd.c.

Function Documentation

◆ AcquireExternalFD()

bool AcquireExternalFD ( void  )

Definition at line 1045 of file fd.c.

References max_safe_fds, numExternalFDs, and ReserveExternalFD().

Referenced by connect_pg_server(), CreateWaitEventSet(), dblink_connect(), and dblink_get_conn().

1046 {
1047  /*
1048  * We don't want more than max_safe_fds / 3 FDs to be consumed for
1049  * "external" FDs.
1050  */
1051  if (numExternalFDs < max_safe_fds / 3)
1052  {
1054  return true;
1055  }
1056  errno = EMFILE;
1057  return false;
1058 }
static int numExternalFDs
Definition: fd.c:258
int max_safe_fds
Definition: fd.c:154
void ReserveExternalFD(void)
Definition: fd.c:1080

◆ AllocateDir()

DIR* AllocateDir ( const char *  dirname)

Definition at line 2581 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, 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(), do_pg_start_backup(), dsm_cleanup_for_mmap(), extension_file_exists(), get_ext_ver_list(), getInstallationPaths(), movedb(), ParseTzFile(), perform_base_backup(), pg_available_extension_versions(), pg_available_extensions(), pg_logdir_ls_internal(), pg_ls_dir(), pg_ls_dir_files(), pg_tablespace_databases(), pg_tzenumerate_next(), pg_tzenumerate_start(), pgarch_readyXlog(), pgstat_reset_remove_files(), RelationCacheInitFileRemove(), RelationCacheInitFileRemoveInDir(), RemoveNonParentXlogFiles(), RemoveOldXlogFiles(), RemovePgTempFiles(), RemovePgTempFilesInDir(), RemovePgTempRelationFiles(), RemovePgTempRelationFilesInDbspace(), RemoveTempXlogFiles(), ReorderBufferCleanupSerializedTXNs(), ResetUnloggedRelations(), ResetUnloggedRelationsInDbspaceDir(), ResetUnloggedRelationsInTablespaceDir(), restoreTwoPhaseData(), scan_directory_ci(), sendDir(), SlruScanDirectory(), StartupReorderBuffer(), StartupReplicationSlots(), UpdateLogicalMappings(), and walkdir().

2582 {
2583  DIR *dir;
2584 
2585  DO_DB(elog(LOG, "AllocateDir: Allocated %d (%s)",
2586  numAllocatedDescs, dirname));
2587 
2588  /* Can we allocate another non-virtual FD? */
2589  if (!reserveAllocatedDesc())
2590  ereport(ERROR,
2591  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2592  errmsg("exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"",
2593  maxAllocatedDescs, dirname)));
2594 
2595  /* Close excess kernel FDs. */
2596  ReleaseLruFiles();
2597 
2598 TryAgain:
2599  if ((dir = opendir(dirname)) != NULL)
2600  {
2602 
2603  desc->kind = AllocateDescDir;
2604  desc->desc.dir = dir;
2607  return desc->desc.dir;
2608  }
2609 
2610  if (errno == EMFILE || errno == ENFILE)
2611  {
2612  int save_errno = errno;
2613 
2614  ereport(LOG,
2615  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2616  errmsg("out of file descriptors: %m; release and retry")));
2617  errno = 0;
2618  if (ReleaseLruFile())
2619  goto TryAgain;
2620  errno = save_errno;
2621  }
2622 
2623  return NULL;
2624 }
static AllocateDesc * allocatedDescs
Definition: fd.c:253
DIR * dir
Definition: fd.c:246
#define DO_DB(A)
Definition: fd.c:169
int errcode(int sqlerrcode)
Definition: elog.c:610
static bool reserveAllocatedDesc(void)
Definition: fd.c:2245
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:241
static bool ReleaseLruFile(void)
Definition: fd.c:1241
Definition: dirent.c:25
#define ERROR
Definition: elog.h:43
DIR * opendir(const char *)
Definition: dirent.c:33
static void ReleaseLruFiles(void)
Definition: fd.c:1263
#define ereport(elevel,...)
Definition: elog.h:144
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:707
SubTransactionId create_subid
Definition: fd.c:242
union AllocateDesc::@25 desc
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
static int maxAllocatedDescs
Definition: fd.c:252
static int numAllocatedDescs
Definition: fd.c:251

◆ AllocateFile()

FILE* AllocateFile ( const char *  name,
const char *  mode 
)

Definition at line 2320 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, numAllocatedDescs, ReleaseLruFile(), ReleaseLruFiles(), and reserveAllocatedDesc().

Referenced by _ShowOption(), AlterSystemSetConfigFile(), apw_dump_now(), apw_load_buffers(), BackendRun(), BeginCopyFrom(), BeginCopyTo(), checkControlFile(), do_pg_start_backup(), do_pg_stop_backup(), entry_reset(), existsTimeLineHistory(), ExportSnapshot(), fill_hba_view(), gc_qtexts(), ImportSnapshot(), load_dh_file(), 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_internal(), pg_promote(), PGSharedMemoryAttach(), 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(), PostmasterMarkPIDForWorkerNotify(), read_backup_label(), read_binary_file(), read_tablespace_map(), read_whole_file(), readTimeLineHistory(), sendFile(), tokenize_inc_file(), tsearch_readline_begin(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

2321 {
2322  FILE *file;
2323 
2324  DO_DB(elog(LOG, "AllocateFile: Allocated %d (%s)",
2326 
2327  /* Can we allocate another non-virtual FD? */
2328  if (!reserveAllocatedDesc())
2329  ereport(ERROR,
2330  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2331  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2332  maxAllocatedDescs, name)));
2333 
2334  /* Close excess kernel FDs. */
2335  ReleaseLruFiles();
2336 
2337 TryAgain:
2338  if ((file = fopen(name, mode)) != NULL)
2339  {
2341 
2342  desc->kind = AllocateDescFile;
2343  desc->desc.file = file;
2346  return desc->desc.file;
2347  }
2348 
2349  if (errno == EMFILE || errno == ENFILE)
2350  {
2351  int save_errno = errno;
2352 
2353  ereport(LOG,
2354  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2355  errmsg("out of file descriptors: %m; release and retry")));
2356  errno = 0;
2357  if (ReleaseLruFile())
2358  goto TryAgain;
2359  errno = save_errno;
2360  }
2361 
2362  return NULL;
2363 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
static AllocateDesc * allocatedDescs
Definition: fd.c:253
#define DO_DB(A)
Definition: fd.c:169
int errcode(int sqlerrcode)
Definition: elog.c:610
static bool reserveAllocatedDesc(void)
Definition: fd.c:2245
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:241
static bool ReleaseLruFile(void)
Definition: fd.c:1241
#define ERROR
Definition: elog.h:43
static void ReleaseLruFiles(void)
Definition: fd.c:1263
FILE * file
Definition: fd.c:245
#define ereport(elevel,...)
Definition: elog.h:144
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:707
SubTransactionId create_subid
Definition: fd.c:242
const char * name
Definition: encode.c:521
union AllocateDesc::@25 desc
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
static int maxAllocatedDescs
Definition: fd.c:252
static int numAllocatedDescs
Definition: fd.c:251

◆ AllocateVfd()

static File AllocateVfd ( void  )
static

Definition at line 1273 of file fd.c.

References Assert, DO_DB, elog, ereport, errcode(), errmsg(), ERROR, vfd::fd, i, LOG, MemSet, vfd::nextFree, realloc, SizeVfdCache, and VFD_CLOSED.

Referenced by PathNameOpenFilePerm().

1274 {
1275  Index i;
1276  File file;
1277 
1278  DO_DB(elog(LOG, "AllocateVfd. Size %zu", SizeVfdCache));
1279 
1280  Assert(SizeVfdCache > 0); /* InitFileAccess not called? */
1281 
1282  if (VfdCache[0].nextFree == 0)
1283  {
1284  /*
1285  * The free list is empty so it is time to increase the size of the
1286  * array. We choose to double it each time this happens. However,
1287  * there's not much point in starting *real* small.
1288  */
1289  Size newCacheSize = SizeVfdCache * 2;
1290  Vfd *newVfdCache;
1291 
1292  if (newCacheSize < 32)
1293  newCacheSize = 32;
1294 
1295  /*
1296  * Be careful not to clobber VfdCache ptr if realloc fails.
1297  */
1298  newVfdCache = (Vfd *) realloc(VfdCache, sizeof(Vfd) * newCacheSize);
1299  if (newVfdCache == NULL)
1300  ereport(ERROR,
1301  (errcode(ERRCODE_OUT_OF_MEMORY),
1302  errmsg("out of memory")));
1303  VfdCache = newVfdCache;
1304 
1305  /*
1306  * Initialize the new entries and link them into the free list.
1307  */
1308  for (i = SizeVfdCache; i < newCacheSize; i++)
1309  {
1310  MemSet((char *) &(VfdCache[i]), 0, sizeof(Vfd));
1311  VfdCache[i].nextFree = i + 1;
1312  VfdCache[i].fd = VFD_CLOSED;
1313  }
1314  VfdCache[newCacheSize - 1].nextFree = 0;
1316 
1317  /*
1318  * Record the new size
1319  */
1320  SizeVfdCache = newCacheSize;
1321  }
1322 
1323  file = VfdCache[0].nextFree;
1324 
1325  VfdCache[0].nextFree = VfdCache[file].nextFree;
1326 
1327  return file;
1328 }
File nextFree
Definition: fd.c:190
static Size SizeVfdCache
Definition: fd.c:206
#define DO_DB(A)
Definition: fd.c:169
static Vfd * VfdCache
Definition: fd.c:205
int errcode(int sqlerrcode)
Definition: elog.c:610
#define MemSet(start, val, len)
Definition: c.h:971
#define LOG
Definition: elog.h:26
#define ERROR
Definition: elog.h:43
Definition: fd.c:185
int fd
Definition: fd.c:187
unsigned int Index
Definition: c.h:475
#define VFD_CLOSED
Definition: fd.c:173
#define ereport(elevel,...)
Definition: elog.h:144
#define Assert(condition)
Definition: c.h:738
size_t Size
Definition: c.h:466
#define realloc(a, b)
Definition: header.h:60
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
int i
int File
Definition: fd.h:49

◆ AtEOSubXact_Files()

void AtEOSubXact_Files ( bool  isCommit,
SubTransactionId  mySubid,
SubTransactionId  parentSubid 
)

Definition at line 2863 of file fd.c.

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

2865 {
2866  Index i;
2867 
2868  for (i = 0; i < numAllocatedDescs; i++)
2869  {
2870  if (allocatedDescs[i].create_subid == mySubid)
2871  {
2872  if (isCommit)
2873  allocatedDescs[i].create_subid = parentSubid;
2874  else
2875  {
2876  /* have to recheck the item after FreeDesc (ugly) */
2877  FreeDesc(&allocatedDescs[i--]);
2878  }
2879  }
2880  }
2881 }
static AllocateDesc * allocatedDescs
Definition: fd.c:253
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2480
unsigned int Index
Definition: c.h:475
SubTransactionId create_subid
Definition: fd.c:242
int i
static int numAllocatedDescs
Definition: fd.c:251

◆ AtEOXact_Files()

void AtEOXact_Files ( bool  isCommit)

Definition at line 2896 of file fd.c.

References CleanupTempFiles(), numTempTableSpaces, and tempTableSpaces.

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

2897 {
2898  CleanupTempFiles(isCommit, false);
2899  tempTableSpaces = NULL;
2900  numTempTableSpaces = -1;
2901 }
static int numTempTableSpaces
Definition: fd.c:271
static Oid * tempTableSpaces
Definition: fd.c:270
static void CleanupTempFiles(bool isCommit, bool isProcExit)
Definition: fd.c:2928

◆ AtProcExit_Files()

static void AtProcExit_Files ( int  code,
Datum  arg 
)
static

Definition at line 2910 of file fd.c.

References CleanupTempFiles().

Referenced by InitFileAccess().

2911 {
2912  CleanupTempFiles(false, true);
2913 }
static void CleanupTempFiles(bool isCommit, bool isProcExit)
Definition: fd.c:2928

◆ BasicOpenFile()

int BasicOpenFile ( const char *  fileName,
int  fileFlags 
)

Definition at line 983 of file fd.c.

References BasicOpenFilePerm(), and pg_file_create_mode.

Referenced by AlterSystemSetConfigFile(), ReadControlFile(), update_controlfile(), wal_segment_open(), WalSndSegmentOpen(), WriteControlFile(), XLogFileInit(), XLogFileOpen(), and XLogFileRead().

984 {
985  return BasicOpenFilePerm(fileName, fileFlags, pg_file_create_mode);
986 }
int pg_file_create_mode
Definition: file_perm.c:19
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1005

◆ BasicOpenFilePerm()

int BasicOpenFilePerm ( const char *  fileName,
int  fileFlags,
mode_t  fileMode 
)

Definition at line 1005 of file fd.c.

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

Referenced by BasicOpenFile(), LruInsert(), OpenTransientFilePerm(), PathNameOpenFilePerm(), and readRecoverySignalFile().

1006 {
1007  int fd;
1008 
1009 tryAgain:
1010  fd = open(fileName, fileFlags, fileMode);
1011 
1012  if (fd >= 0)
1013  return fd; /* success! */
1014 
1015  if (errno == EMFILE || errno == ENFILE)
1016  {
1017  int save_errno = errno;
1018 
1019  ereport(LOG,
1020  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
1021  errmsg("out of file descriptors: %m; release and retry")));
1022  errno = 0;
1023  if (ReleaseLruFile())
1024  goto tryAgain;
1025  errno = save_errno;
1026  }
1027 
1028  return -1; /* failure */
1029 }
int errcode(int sqlerrcode)
Definition: elog.c:610
#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:1241
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ CleanupTempFiles()

static void CleanupTempFiles ( bool  isCommit,
bool  isProcExit 
)
static

Definition at line 2928 of file fd.c.

References Assert, elog, FD_CLOSE_AT_EOXACT, FD_DELETE_AT_CLOSE, vfd::fdstate, FileClose(), FileIsNotOpen, vfd::fileName, FreeDesc(), have_xact_temporary_files, i, numAllocatedDescs, SizeVfdCache, and WARNING.

Referenced by AtEOXact_Files(), and AtProcExit_Files().

2929 {
2930  Index i;
2931 
2932  /*
2933  * Careful here: at proc_exit we need extra cleanup, not just
2934  * xact_temporary files.
2935  */
2936  if (isProcExit || have_xact_temporary_files)
2937  {
2938  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2939  for (i = 1; i < SizeVfdCache; i++)
2940  {
2941  unsigned short fdstate = VfdCache[i].fdstate;
2942 
2943  if (((fdstate & FD_DELETE_AT_CLOSE) || (fdstate & FD_CLOSE_AT_EOXACT)) &&
2944  VfdCache[i].fileName != NULL)
2945  {
2946  /*
2947  * If we're in the process of exiting a backend process, close
2948  * all temporary files. Otherwise, only close temporary files
2949  * local to the current transaction. They should be closed by
2950  * the ResourceOwner mechanism already, so this is just a
2951  * debugging cross-check.
2952  */
2953  if (isProcExit)
2954  FileClose(i);
2955  else if (fdstate & FD_CLOSE_AT_EOXACT)
2956  {
2957  elog(WARNING,
2958  "temporary file %s not closed at end-of-transaction",
2959  VfdCache[i].fileName);
2960  FileClose(i);
2961  }
2962  }
2963  }
2964 
2965  have_xact_temporary_files = false;
2966  }
2967 
2968  /* Complain if any allocated files remain open at commit. */
2969  if (isCommit && numAllocatedDescs > 0)
2970  elog(WARNING, "%d temporary files and directories not closed at end-of-transaction",
2972 
2973  /* Clean up "allocated" stdio files, dirs and fds. */
2974  while (numAllocatedDescs > 0)
2975  FreeDesc(&allocatedDescs[0]);
2976 }
static AllocateDesc * allocatedDescs
Definition: fd.c:253
static Size SizeVfdCache
Definition: fd.c:206
#define FD_DELETE_AT_CLOSE
Definition: fd.c:181
static Vfd * VfdCache
Definition: fd.c:205
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2480
static bool have_xact_temporary_files
Definition: fd.c:217
unsigned short fdstate
Definition: fd.c:188
#define WARNING
Definition: elog.h:40
#define FileIsNotOpen(file)
Definition: fd.c:178
unsigned int Index
Definition: c.h:475
void FileClose(File file)
Definition: fd.c:1824
#define Assert(condition)
Definition: c.h:738
#define elog(elevel,...)
Definition: elog.h:214
int i
#define FD_CLOSE_AT_EOXACT
Definition: fd.c:182
static int numAllocatedDescs
Definition: fd.c:251

◆ closeAllVfds()

void closeAllVfds ( void  )

Definition at line 2758 of file fd.c.

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

Referenced by standard_ProcessUtility().

2759 {
2760  Index i;
2761 
2762  if (SizeVfdCache > 0)
2763  {
2764  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2765  for (i = 1; i < SizeVfdCache; i++)
2766  {
2767  if (!FileIsNotOpen(i))
2768  LruDelete(i);
2769  }
2770  }
2771 }
static Size SizeVfdCache
Definition: fd.c:206
static void LruDelete(File file)
Definition: fd.c:1146
#define FileIsNotOpen(file)
Definition: fd.c:178
unsigned int Index
Definition: c.h:475
#define Assert(condition)
Definition: c.h:738
int i

◆ ClosePipeStream()

int ClosePipeStream ( FILE *  file)

Definition at line 2729 of file fd.c.

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

Referenced by ClosePipeToProgram(), pg_import_system_collations(), and run_ssl_passphrase_command().

2730 {
2731  int i;
2732 
2733  DO_DB(elog(LOG, "ClosePipeStream: Allocated %d", numAllocatedDescs));
2734 
2735  /* Remove file from list of allocated files, if it's present */
2736  for (i = numAllocatedDescs; --i >= 0;)
2737  {
2738  AllocateDesc *desc = &allocatedDescs[i];
2739 
2740  if (desc->kind == AllocateDescPipe && desc->desc.file == file)
2741  return FreeDesc(desc);
2742  }
2743 
2744  /* Only get here if someone passes us a file not in allocatedDescs */
2745  elog(WARNING, "file passed to ClosePipeStream was not obtained from OpenPipeStream");
2746 
2747  return pclose(file);
2748 }
static AllocateDesc * allocatedDescs
Definition: fd.c:253
#define DO_DB(A)
Definition: fd.c:169
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:241
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2480
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:245
union AllocateDesc::@25 desc
#define elog(elevel,...)
Definition: elog.h:214
int i
static int numAllocatedDescs
Definition: fd.c:251

◆ CloseTransientFile()

int CloseTransientFile ( int  fd)

Definition at line 2547 of file fd.c.

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

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

2548 {
2549  int i;
2550 
2551  DO_DB(elog(LOG, "CloseTransientFile: Allocated %d", numAllocatedDescs));
2552 
2553  /* Remove fd from list of allocated files, if it's present */
2554  for (i = numAllocatedDescs; --i >= 0;)
2555  {
2556  AllocateDesc *desc = &allocatedDescs[i];
2557 
2558  if (desc->kind == AllocateDescRawFD && desc->desc.fd == fd)
2559  return FreeDesc(desc);
2560  }
2561 
2562  /* Only get here if someone passes us a file not in allocatedDescs */
2563  elog(WARNING, "fd passed to CloseTransientFile was not obtained from OpenTransientFile");
2564 
2565  return close(fd);
2566 }
static AllocateDesc * allocatedDescs
Definition: fd.c:253
#define DO_DB(A)
Definition: fd.c:169
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:241
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2480
#define WARNING
Definition: elog.h:40
int fd
Definition: fd.c:247
union AllocateDesc::@25 desc
#define elog(elevel,...)
Definition: elog.h:214
int i
#define close(a)
Definition: win32.h:12
static int numAllocatedDescs
Definition: fd.c:251

◆ count_usable_fds()

static void count_usable_fds ( int  max_to_probe,
int *  usable_fds,
int *  already_open 
)
static

Definition at line 856 of file fd.c.

References close, elog, ereport, errmsg(), vfd::fd, palloc(), pfree(), repalloc(), and WARNING.

Referenced by set_max_safe_fds().

857 {
858  int *fd;
859  int size;
860  int used = 0;
861  int highestfd = 0;
862  int j;
863 
864 #ifdef HAVE_GETRLIMIT
865  struct rlimit rlim;
866  int getrlimit_status;
867 #endif
868 
869  size = 1024;
870  fd = (int *) palloc(size * sizeof(int));
871 
872 #ifdef HAVE_GETRLIMIT
873 #ifdef RLIMIT_NOFILE /* most platforms use RLIMIT_NOFILE */
874  getrlimit_status = getrlimit(RLIMIT_NOFILE, &rlim);
875 #else /* but BSD doesn't ... */
876  getrlimit_status = getrlimit(RLIMIT_OFILE, &rlim);
877 #endif /* RLIMIT_NOFILE */
878  if (getrlimit_status != 0)
879  ereport(WARNING, (errmsg("getrlimit failed: %m")));
880 #endif /* HAVE_GETRLIMIT */
881 
882  /* dup until failure or probe limit reached */
883  for (;;)
884  {
885  int thisfd;
886 
887 #ifdef HAVE_GETRLIMIT
888 
889  /*
890  * don't go beyond RLIMIT_NOFILE; causes irritating kernel logs on
891  * some platforms
892  */
893  if (getrlimit_status == 0 && highestfd >= rlim.rlim_cur - 1)
894  break;
895 #endif
896 
897  thisfd = dup(0);
898  if (thisfd < 0)
899  {
900  /* Expect EMFILE or ENFILE, else it's fishy */
901  if (errno != EMFILE && errno != ENFILE)
902  elog(WARNING, "dup(0) failed after %d successes: %m", used);
903  break;
904  }
905 
906  if (used >= size)
907  {
908  size *= 2;
909  fd = (int *) repalloc(fd, size * sizeof(int));
910  }
911  fd[used++] = thisfd;
912 
913  if (highestfd < thisfd)
914  highestfd = thisfd;
915 
916  if (used >= max_to_probe)
917  break;
918  }
919 
920  /* release the files we opened */
921  for (j = 0; j < used; j++)
922  close(fd[j]);
923 
924  pfree(fd);
925 
926  /*
927  * Return results. usable_fds is just the number of successful dups. We
928  * assume that the system limit is highestfd+1 (remember 0 is a legal FD
929  * number) and so already_open is highestfd+1 - usable_fds.
930  */
931  *usable_fds = used;
932  *already_open = highestfd + 1 - used;
933 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
void pfree(void *pointer)
Definition: mcxt.c:1056
#define WARNING
Definition: elog.h:40
#define ereport(elevel,...)
Definition: elog.h:144
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1069
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
#define close(a)
Definition: win32.h:12

◆ data_sync_elevel()

◆ datadir_fsync_fname()

static void datadir_fsync_fname ( const char *  fname,
bool  isdir,
int  elevel 
)
static

Definition at line 3423 of file fd.c.

References fsync_fname_ext().

Referenced by SyncDataDirectory().

3424 {
3425  /*
3426  * We want to silently ignoring errors about unreadable files. Pass that
3427  * desire on to fsync_fname_ext().
3428  */
3429  fsync_fname_ext(fname, isdir, true, elevel);
3430 }
static int elevel
Definition: vacuumlazy.c:323
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3458

◆ Delete()

static void Delete ( File  file)
static

Definition at line 1127 of file fd.c.

References Assert, DO_DB, elog, vfd::fileName, LOG, vfd::lruLessRecently, and vfd::lruMoreRecently.

Referenced by FileAccess(), FileClose(), and LruDelete().

1128 {
1129  Vfd *vfdP;
1130 
1131  Assert(file != 0);
1132 
1133  DO_DB(elog(LOG, "Delete %d (%s)",
1134  file, VfdCache[file].fileName));
1135  DO_DB(_dump_lru());
1136 
1137  vfdP = &VfdCache[file];
1138 
1141 
1142  DO_DB(_dump_lru());
1143 }
File lruLessRecently
Definition: fd.c:192
#define DO_DB(A)
Definition: fd.c:169
static Vfd * VfdCache
Definition: fd.c:205
#define LOG
Definition: elog.h:26
Definition: fd.c:185
#define Assert(condition)
Definition: c.h:738
File lruMoreRecently
Definition: fd.c:191
#define elog(elevel,...)
Definition: elog.h:214

◆ durable_rename()

int durable_rename ( const char *  oldfile,
const char *  newfile,
int  elevel 
)

Definition at line 656 of file fd.c.

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

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

657 {
658  int fd;
659 
660  /*
661  * First fsync the old and target path (if it exists), to ensure that they
662  * are properly persistent on disk. Syncing the target file is not
663  * strictly necessary, but it makes it easier to reason about crashes;
664  * because it's then guaranteed that either source or target file exists
665  * after a crash.
666  */
667  if (fsync_fname_ext(oldfile, false, false, elevel) != 0)
668  return -1;
669 
670  fd = OpenTransientFile(newfile, PG_BINARY | O_RDWR);
671  if (fd < 0)
672  {
673  if (errno != ENOENT)
674  {
675  ereport(elevel,
677  errmsg("could not open file \"%s\": %m", newfile)));
678  return -1;
679  }
680  }
681  else
682  {
683  if (pg_fsync(fd) != 0)
684  {
685  int save_errno;
686 
687  /* close file upon error, might not be in transaction context */
688  save_errno = errno;
689  CloseTransientFile(fd);
690  errno = save_errno;
691 
692  ereport(elevel,
694  errmsg("could not fsync file \"%s\": %m", newfile)));
695  return -1;
696  }
697 
698  if (CloseTransientFile(fd) != 0)
699  {
700  ereport(elevel,
702  errmsg("could not close file \"%s\": %m", newfile)));
703  return -1;
704  }
705  }
706 
707  /* Time to do the real deal... */
708  if (rename(oldfile, newfile) < 0)
709  {
710  ereport(elevel,
712  errmsg("could not rename file \"%s\" to \"%s\": %m",
713  oldfile, newfile)));
714  return -1;
715  }
716 
717  /*
718  * To guarantee renaming the file is persistent, fsync the file with its
719  * new name, and its containing directory.
720  */
721  if (fsync_fname_ext(newfile, false, false, elevel) != 0)
722  return -1;
723 
724  if (fsync_parent_path(newfile, elevel) != 0)
725  return -1;
726 
727  return 0;
728 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1234
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2370
int errcode_for_file_access(void)
Definition: elog.c:633
int CloseTransientFile(int fd)
Definition: fd.c:2547
static int elevel
Definition: vacuumlazy.c:323
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824
int pg_fsync(int fd)
Definition: fd.c:343
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3458
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3534

◆ durable_rename_excl()

int durable_rename_excl ( const char *  oldfile,
const char *  newfile,
int  elevel 
)

Definition at line 783 of file fd.c.

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

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

784 {
785  /*
786  * Ensure that, if we crash directly after the rename/link, a file with
787  * valid contents is moved into place.
788  */
789  if (fsync_fname_ext(oldfile, false, false, elevel) != 0)
790  return -1;
791 
792  if (link(oldfile, newfile) < 0)
793  {
794  ereport(elevel,
796  errmsg("could not link file \"%s\" to \"%s\": %m",
797  oldfile, newfile)));
798  return -1;
799  }
800  unlink(oldfile);
801 
802  /*
803  * Make change persistent in case of an OS crash, both the new entry and
804  * its parent directory need to be flushed.
805  */
806  if (fsync_fname_ext(newfile, false, false, elevel) != 0)
807  return -1;
808 
809  /* Same for parent directory */
810  if (fsync_parent_path(newfile, elevel) != 0)
811  return -1;
812 
813  return 0;
814 }
int errcode_for_file_access(void)
Definition: elog.c:633
static int elevel
Definition: vacuumlazy.c:323
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824
int link(const char *src, const char *dst)
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3458
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3534

◆ durable_unlink()

int durable_unlink ( const char *  fname,
int  elevel 
)

Definition at line 746 of file fd.c.

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

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

747 {
748  if (unlink(fname) < 0)
749  {
750  ereport(elevel,
752  errmsg("could not remove file \"%s\": %m",
753  fname)));
754  return -1;
755  }
756 
757  /*
758  * To guarantee that the removal of the file is persistent, fsync its
759  * parent directory.
760  */
761  if (fsync_parent_path(fname, elevel) != 0)
762  return -1;
763 
764  return 0;
765 }
int errcode_for_file_access(void)
Definition: elog.c:633
static int elevel
Definition: vacuumlazy.c:323
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3534

◆ FileAccess()

static int FileAccess ( File  file)
static

Definition at line 1351 of file fd.c.

References Delete(), DO_DB, elog, FileIsNotOpen, vfd::fileName, Insert(), LOG, LruInsert(), and vfd::lruLessRecently.

Referenced by FilePrefetch(), FileRead(), FileSize(), FileSync(), FileTruncate(), FileWrite(), and FileWriteback().

1352 {
1353  int returnValue;
1354 
1355  DO_DB(elog(LOG, "FileAccess %d (%s)",
1356  file, VfdCache[file].fileName));
1357 
1358  /*
1359  * Is the file open? If not, open it and put it at the head of the LRU
1360  * ring (possibly closing the least recently used file to get an FD).
1361  */
1362 
1363  if (FileIsNotOpen(file))
1364  {
1365  returnValue = LruInsert(file);
1366  if (returnValue != 0)
1367  return returnValue;
1368  }
1369  else if (VfdCache[0].lruLessRecently != file)
1370  {
1371  /*
1372  * We now know that the file is open and that it is not the last one
1373  * accessed, so we need to move it to the head of the Lru ring.
1374  */
1375 
1376  Delete(file);
1377  Insert(file);
1378  }
1379 
1380  return 0;
1381 }
#define DO_DB(A)
Definition: fd.c:169
static Vfd * VfdCache
Definition: fd.c:205
static void Delete(File file)
Definition: fd.c:1127
#define LOG
Definition: elog.h:26
static int LruInsert(File file)
Definition: fd.c:1194
static void Insert(File file)
Definition: fd.c:1172
#define FileIsNotOpen(file)
Definition: fd.c:178
#define elog(elevel,...)
Definition: elog.h:214

◆ FileClose()

void FileClose ( File  file)

Definition at line 1824 of file fd.c.

References Assert, close, data_sync_elevel(), Delete(), DO_DB, elog, vfd::fd, FD_DELETE_AT_CLOSE, FD_TEMP_FILE_LIMIT, vfd::fdstate, FileIsNotOpen, FileIsValid, vfd::fileName, vfd::fileSize, FreeVfd(), LOG, nfile, ReportTemporaryFileUsage(), ResourceOwnerForgetFile(), vfd::resowner, stat, temporary_files_size, and VFD_CLOSED.

Referenced by BufFileClose(), CleanupTempFiles(), logical_end_heap_rewrite(), mdclose(), mdimmedsync(), mdsyncfiletag(), mdtruncate(), ReorderBufferIterTXNFinish(), ReorderBufferRestoreChanges(), and ResourceOwnerReleaseInternal().

1825 {
1826  Vfd *vfdP;
1827 
1828  Assert(FileIsValid(file));
1829 
1830  DO_DB(elog(LOG, "FileClose: %d (%s)",
1831  file, VfdCache[file].fileName));
1832 
1833  vfdP = &VfdCache[file];
1834 
1835  if (!FileIsNotOpen(file))
1836  {
1837  /* close the file */
1838  if (close(vfdP->fd) != 0)
1839  {
1840  /*
1841  * We may need to panic on failure to close non-temporary files;
1842  * see LruDelete.
1843  */
1845  "could not close file \"%s\": %m", vfdP->fileName);
1846  }
1847 
1848  --nfile;
1849  vfdP->fd = VFD_CLOSED;
1850 
1851  /* remove the file from the lru ring */
1852  Delete(file);
1853  }
1854 
1855  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
1856  {
1857  /* Subtract its size from current usage (do first in case of error) */
1858  temporary_files_size -= vfdP->fileSize;
1859  vfdP->fileSize = 0;
1860  }
1861 
1862  /*
1863  * Delete the file if it was temporary, and make a log entry if wanted
1864  */
1865  if (vfdP->fdstate & FD_DELETE_AT_CLOSE)
1866  {
1867  struct stat filestats;
1868  int stat_errno;
1869 
1870  /*
1871  * If we get an error, as could happen within the ereport/elog calls,
1872  * we'll come right back here during transaction abort. Reset the
1873  * flag to ensure that we can't get into an infinite loop. This code
1874  * is arranged to ensure that the worst-case consequence is failing to
1875  * emit log message(s), not failing to attempt the unlink.
1876  */
1877  vfdP->fdstate &= ~FD_DELETE_AT_CLOSE;
1878 
1879 
1880  /* first try the stat() */
1881  if (stat(vfdP->fileName, &filestats))
1882  stat_errno = errno;
1883  else
1884  stat_errno = 0;
1885 
1886  /* in any case do the unlink */
1887  if (unlink(vfdP->fileName))
1888  elog(LOG, "could not unlink file \"%s\": %m", vfdP->fileName);
1889 
1890  /* and last report the stat results */
1891  if (stat_errno == 0)
1892  ReportTemporaryFileUsage(vfdP->fileName, filestats.st_size);
1893  else
1894  {
1895  errno = stat_errno;
1896  elog(LOG, "could not stat file \"%s\": %m", vfdP->fileName);
1897  }
1898  }
1899 
1900  /* Unregister it from the resource owner */
1901  if (vfdP->resowner)
1902  ResourceOwnerForgetFile(vfdP->resowner, file);
1903 
1904  /*
1905  * Return the Vfd slot to the free list
1906  */
1907  FreeVfd(file);
1908 }
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:183
#define DO_DB(A)
Definition: fd.c:169
#define FD_DELETE_AT_CLOSE
Definition: fd.c:181
static Vfd * VfdCache
Definition: fd.c:205
static void Delete(File file)
Definition: fd.c:1127
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:194
static int nfile
Definition: fd.c:211
unsigned short fdstate
Definition: fd.c:188
Definition: fd.c:185
off_t fileSize
Definition: fd.c:193
int fd
Definition: fd.c:187
ResourceOwner resowner
Definition: fd.c:189
static void ReportTemporaryFileUsage(const char *path, off_t size)
Definition: fd.c:1387
#define stat(a, b)
Definition: win32_port.h:255
#define FileIsNotOpen(file)
Definition: fd.c:178
int data_sync_elevel(int elevel)
Definition: fd.c:3597
#define FileIsValid(file)
Definition: fd.c:175
#define VFD_CLOSED
Definition: fd.c:173
static uint64 temporary_files_size
Definition: fd.c:225
#define Assert(condition)
Definition: c.h:738
#define elog(elevel,...)
Definition: elog.h:214
static void FreeVfd(File file)
Definition: fd.c:1331
#define close(a)
Definition: win32.h:12
void ResourceOwnerForgetFile(ResourceOwner owner, File file)
Definition: resowner.c:1277

◆ FileGetRawDesc()

int FileGetRawDesc ( File  file)

Definition at line 2214 of file fd.c.

References Assert, vfd::fd, and FileIsValid.

2215 {
2216  Assert(FileIsValid(file));
2217  return VfdCache[file].fd;
2218 }
static Vfd * VfdCache
Definition: fd.c:205
int fd
Definition: fd.c:187
#define FileIsValid(file)
Definition: fd.c:175
#define Assert(condition)
Definition: c.h:738

◆ FileGetRawFlags()

int FileGetRawFlags ( File  file)

Definition at line 2224 of file fd.c.

References Assert, vfd::fileFlags, and FileIsValid.

2225 {
2226  Assert(FileIsValid(file));
2227  return VfdCache[file].fileFlags;
2228 }
static Vfd * VfdCache
Definition: fd.c:205
#define FileIsValid(file)
Definition: fd.c:175
#define Assert(condition)
Definition: c.h:738
int fileFlags
Definition: fd.c:196

◆ FileGetRawMode()

mode_t FileGetRawMode ( File  file)

Definition at line 2234 of file fd.c.

References Assert, FileIsValid, and vfd::fileMode.

2235 {
2236  Assert(FileIsValid(file));
2237  return VfdCache[file].fileMode;
2238 }
static Vfd * VfdCache
Definition: fd.c:205
mode_t fileMode
Definition: fd.c:197
#define FileIsValid(file)
Definition: fd.c:175
#define Assert(condition)
Definition: c.h:738

◆ FilePathName()

char* FilePathName ( File  file)

Definition at line 2198 of file fd.c.

References Assert, FileIsValid, and vfd::fileName.

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

2199 {
2200  Assert(FileIsValid(file));
2201 
2202  return VfdCache[file].fileName;
2203 }
static Vfd * VfdCache
Definition: fd.c:205
char * fileName
Definition: fd.c:194
#define FileIsValid(file)
Definition: fd.c:175
#define Assert(condition)
Definition: c.h:738

◆ FilePrefetch()

int FilePrefetch ( File  file,
off_t  offset,
int  amount,
uint32  wait_event_info 
)

Definition at line 1920 of file fd.c.

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

Referenced by mdprefetch().

1921 {
1922 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
1923  int returnCode;
1924 
1925  Assert(FileIsValid(file));
1926 
1927  DO_DB(elog(LOG, "FilePrefetch: %d (%s) " INT64_FORMAT " %d",
1928  file, VfdCache[file].fileName,
1929  (int64) offset, amount));
1930 
1931  returnCode = FileAccess(file);
1932  if (returnCode < 0)
1933  return returnCode;
1934 
1935  pgstat_report_wait_start(wait_event_info);
1936  returnCode = posix_fadvise(VfdCache[file].fd, offset, amount,
1937  POSIX_FADV_WILLNEED);
1939 
1940  return returnCode;
1941 #else
1942  Assert(FileIsValid(file));
1943  return 0;
1944 #endif
1945 }
#define DO_DB(A)
Definition: fd.c:169
static Vfd * VfdCache
Definition: fd.c:205
#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:1386
#define FileIsValid(file)
Definition: fd.c:175
static int FileAccess(File file)
Definition: fd.c:1351
#define Assert(condition)
Definition: c.h:738
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1362
#define INT64_FORMAT
Definition: c.h:409
#define elog(elevel,...)
Definition: elog.h:214

◆ FileRead()

int FileRead ( File  file,
char *  buffer,
int  amount,
off_t  offset,
uint32  wait_event_info 
)

Definition at line 1971 of file fd.c.

References _dosmaperr(), Assert, DO_DB, EINTR, elog, error(), vfd::fd, FileAccess(), FileIsValid, vfd::fileName, INT64_FORMAT, LOG, pg_pread(), pg_usleep(), pgstat_report_wait_end(), and pgstat_report_wait_start().

Referenced by BufFileLoadBuffer(), mdread(), and ReorderBufferRestoreChanges().

1973 {
1974  int returnCode;
1975  Vfd *vfdP;
1976 
1977  Assert(FileIsValid(file));
1978 
1979  DO_DB(elog(LOG, "FileRead: %d (%s) " INT64_FORMAT " %d %p",
1980  file, VfdCache[file].fileName,
1981  (int64) offset,
1982  amount, buffer));
1983 
1984  returnCode = FileAccess(file);
1985  if (returnCode < 0)
1986  return returnCode;
1987 
1988  vfdP = &VfdCache[file];
1989 
1990 retry:
1991  pgstat_report_wait_start(wait_event_info);
1992  returnCode = pg_pread(vfdP->fd, buffer, amount, offset);
1994 
1995  if (returnCode < 0)
1996  {
1997  /*
1998  * Windows may run out of kernel buffers and return "Insufficient
1999  * system resources" error. Wait a bit and retry to solve it.
2000  *
2001  * It is rumored that EINTR is also possible on some Unix filesystems,
2002  * in which case immediate retry is indicated.
2003  */
2004 #ifdef WIN32
2005  DWORD error = GetLastError();
2006 
2007  switch (error)
2008  {
2009  case ERROR_NO_SYSTEM_RESOURCES:
2010  pg_usleep(1000L);
2011  errno = EINTR;
2012  break;
2013  default:
2014  _dosmaperr(error);
2015  break;
2016  }
2017 #endif
2018  /* OK to retry if interrupted */
2019  if (errno == EINTR)
2020  goto retry;
2021  }
2022 
2023  return returnCode;
2024 }
static void error(void)
Definition: sql-dyntest.c:147
#define DO_DB(A)
Definition: fd.c:169
void _dosmaperr(unsigned long)
Definition: win32error.c:171
static Vfd * VfdCache
Definition: fd.c:205
#define LOG
Definition: elog.h:26
ssize_t pg_pread(int fd, void *buf, size_t nbyte, off_t offset)
Definition: pread.c:27
void pg_usleep(long microsec)
Definition: signal.c:53
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1386
Definition: fd.c:185
int fd
Definition: fd.c:187
#define FileIsValid(file)
Definition: fd.c:175
static int FileAccess(File file)
Definition: fd.c:1351
#define Assert(condition)
Definition: c.h:738
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1362
#define INT64_FORMAT
Definition: c.h:409
#define elog(elevel,...)
Definition: elog.h:214
#define EINTR
Definition: win32_port.h:323

◆ FileSize()

off_t FileSize ( File  file)

Definition at line 2146 of file fd.c.

References Assert, DO_DB, elog, vfd::fd, FileAccess(), FileIsNotOpen, FileIsValid, vfd::fileName, and LOG.

Referenced by _mdnblocks(), and BufFileSize().

2147 {
2148  Assert(FileIsValid(file));
2149 
2150  DO_DB(elog(LOG, "FileSize %d (%s)",
2151  file, VfdCache[file].fileName));
2152 
2153  if (FileIsNotOpen(file))
2154  {
2155  if (FileAccess(file) < 0)
2156  return (off_t) -1;
2157  }
2158 
2159  return lseek(VfdCache[file].fd, 0, SEEK_END);
2160 }
#define DO_DB(A)
Definition: fd.c:169
static Vfd * VfdCache
Definition: fd.c:205
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define FileIsNotOpen(file)
Definition: fd.c:178
#define FileIsValid(file)
Definition: fd.c:175
static int FileAccess(File file)
Definition: fd.c:1351
#define Assert(condition)
Definition: c.h:738
#define elog(elevel,...)
Definition: elog.h:214

◆ FileSync()

int FileSync ( File  file,
uint32  wait_event_info 
)

Definition at line 2125 of file fd.c.

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

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

2126 {
2127  int returnCode;
2128 
2129  Assert(FileIsValid(file));
2130 
2131  DO_DB(elog(LOG, "FileSync: %d (%s)",
2132  file, VfdCache[file].fileName));
2133 
2134  returnCode = FileAccess(file);
2135  if (returnCode < 0)
2136  return returnCode;
2137 
2138  pgstat_report_wait_start(wait_event_info);
2139  returnCode = pg_fsync(VfdCache[file].fd);
2141 
2142  return returnCode;
2143 }
#define DO_DB(A)
Definition: fd.c:169
static Vfd * VfdCache
Definition: fd.c:205
#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:1386
#define FileIsValid(file)
Definition: fd.c:175
static int FileAccess(File file)
Definition: fd.c:1351
#define Assert(condition)
Definition: c.h:738
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1362
#define elog(elevel,...)
Definition: elog.h:214
int pg_fsync(int fd)
Definition: fd.c:343

◆ FileTruncate()

int FileTruncate ( File  file,
off_t  offset,
uint32  wait_event_info 
)

Definition at line 2163 of file fd.c.

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

Referenced by mdtruncate().

2164 {
2165  int returnCode;
2166 
2167  Assert(FileIsValid(file));
2168 
2169  DO_DB(elog(LOG, "FileTruncate %d (%s)",
2170  file, VfdCache[file].fileName));
2171 
2172  returnCode = FileAccess(file);
2173  if (returnCode < 0)
2174  return returnCode;
2175 
2176  pgstat_report_wait_start(wait_event_info);
2177  returnCode = ftruncate(VfdCache[file].fd, offset);
2179 
2180  if (returnCode == 0 && VfdCache[file].fileSize > offset)
2181  {
2182  /* adjust our state for truncation of a temp file */
2183  Assert(VfdCache[file].fdstate & FD_TEMP_FILE_LIMIT);
2184  temporary_files_size -= VfdCache[file].fileSize - offset;
2185  VfdCache[file].fileSize = offset;
2186  }
2187 
2188  return returnCode;
2189 }
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:183
#define DO_DB(A)
Definition: fd.c:169
static Vfd * VfdCache
Definition: fd.c:205
#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:1386
off_t fileSize
Definition: fd.c:193
#define FileIsValid(file)
Definition: fd.c:175
static uint64 temporary_files_size
Definition: fd.c:225
static int FileAccess(File file)
Definition: fd.c:1351
#define Assert(condition)
Definition: c.h:738
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1362
#define elog(elevel,...)
Definition: elog.h:214
#define ftruncate(a, b)
Definition: win32_port.h:59

◆ FileWrite()

int FileWrite ( File  file,
char *  buffer,
int  amount,
off_t  offset,
uint32  wait_event_info 
)

Definition at line 2027 of file fd.c.

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

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

2029 {
2030  int returnCode;
2031  Vfd *vfdP;
2032 
2033  Assert(FileIsValid(file));
2034 
2035  DO_DB(elog(LOG, "FileWrite: %d (%s) " INT64_FORMAT " %d %p",
2036  file, VfdCache[file].fileName,
2037  (int64) offset,
2038  amount, buffer));
2039 
2040  returnCode = FileAccess(file);
2041  if (returnCode < 0)
2042  return returnCode;
2043 
2044  vfdP = &VfdCache[file];
2045 
2046  /*
2047  * If enforcing temp_file_limit and it's a temp file, check to see if the
2048  * write would overrun temp_file_limit, and throw error if so. Note: it's
2049  * really a modularity violation to throw error here; we should set errno
2050  * and return -1. However, there's no way to report a suitable error
2051  * message if we do that. All current callers would just throw error
2052  * immediately anyway, so this is safe at present.
2053  */
2054  if (temp_file_limit >= 0 && (vfdP->fdstate & FD_TEMP_FILE_LIMIT))
2055  {
2056  off_t past_write = offset + amount;
2057 
2058  if (past_write > vfdP->fileSize)
2059  {
2060  uint64 newTotal = temporary_files_size;
2061 
2062  newTotal += past_write - vfdP->fileSize;
2063  if (newTotal > (uint64) temp_file_limit * (uint64) 1024)
2064  ereport(ERROR,
2065  (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
2066  errmsg("temporary file size exceeds temp_file_limit (%dkB)",
2067  temp_file_limit)));
2068  }
2069  }
2070 
2071 retry:
2072  errno = 0;
2073  pgstat_report_wait_start(wait_event_info);
2074  returnCode = pg_pwrite(VfdCache[file].fd, buffer, amount, offset);
2076 
2077  /* if write didn't set errno, assume problem is no disk space */
2078  if (returnCode != amount && errno == 0)
2079  errno = ENOSPC;
2080 
2081  if (returnCode >= 0)
2082  {
2083  /*
2084  * Maintain fileSize and temporary_files_size if it's a temp file.
2085  */
2086  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
2087  {
2088  off_t past_write = offset + amount;
2089 
2090  if (past_write > vfdP->fileSize)
2091  {
2092  temporary_files_size += past_write - vfdP->fileSize;
2093  vfdP->fileSize = past_write;
2094  }
2095  }
2096  }
2097  else
2098  {
2099  /*
2100  * See comments in FileRead()
2101  */
2102 #ifdef WIN32
2103  DWORD error = GetLastError();
2104 
2105  switch (error)
2106  {
2107  case ERROR_NO_SYSTEM_RESOURCES:
2108  pg_usleep(1000L);
2109  errno = EINTR;
2110  break;
2111  default:
2112  _dosmaperr(error);
2113  break;
2114  }
2115 #endif
2116  /* OK to retry if interrupted */
2117  if (errno == EINTR)
2118  goto retry;
2119  }
2120 
2121  return returnCode;
2122 }
static void error(void)
Definition: sql-dyntest.c:147
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:183
#define DO_DB(A)
Definition: fd.c:169
void _dosmaperr(unsigned long)
Definition: win32error.c:171
static Vfd * VfdCache
Definition: fd.c:205
int errcode(int sqlerrcode)
Definition: elog.c:610
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ssize_t pg_pwrite(int fd, const void *buf, size_t nbyte, off_t offset)
Definition: pwrite.c:27
void pg_usleep(long microsec)
Definition: signal.c:53
#define ERROR
Definition: elog.h:43
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1386
unsigned short fdstate
Definition: fd.c:188
Definition: fd.c:185
off_t fileSize
Definition: fd.c:193
#define FileIsValid(file)
Definition: fd.c:175
static uint64 temporary_files_size
Definition: fd.c:225
#define ereport(elevel,...)
Definition: elog.h:144
static int FileAccess(File file)
Definition: fd.c:1351
#define Assert(condition)
Definition: c.h:738
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1362
#define INT64_FORMAT
Definition: c.h:409
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
#define EINTR
Definition: win32_port.h:323
int temp_file_limit
Definition: guc.c:556

◆ FileWriteback()

void FileWriteback ( File  file,
off_t  offset,
off_t  nbytes,
uint32  wait_event_info 
)

Definition at line 1948 of file fd.c.

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

Referenced by mdwriteback().

1949 {
1950  int returnCode;
1951 
1952  Assert(FileIsValid(file));
1953 
1954  DO_DB(elog(LOG, "FileWriteback: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
1955  file, VfdCache[file].fileName,
1956  (int64) offset, (int64) nbytes));
1957 
1958  if (nbytes <= 0)
1959  return;
1960 
1961  returnCode = FileAccess(file);
1962  if (returnCode < 0)
1963  return;
1964 
1965  pgstat_report_wait_start(wait_event_info);
1966  pg_flush_data(VfdCache[file].fd, offset, nbytes);
1968 }
#define DO_DB(A)
Definition: fd.c:169
static Vfd * VfdCache
Definition: fd.c:205
#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:1386
void pg_flush_data(int fd, off_t offset, off_t nbytes)
Definition: fd.c:453
#define FileIsValid(file)
Definition: fd.c:175
static int FileAccess(File file)
Definition: fd.c:1351
#define Assert(condition)
Definition: c.h:738
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1362
#define INT64_FORMAT
Definition: c.h:409
#define elog(elevel,...)
Definition: elog.h:214

◆ FreeDesc()

static int FreeDesc ( AllocateDesc desc)
static

Definition at line 2480 of file fd.c.

References AllocateDescDir, AllocateDescFile, AllocateDescPipe, AllocateDescRawFD, close, closedir(), AllocateDesc::desc, AllocateDesc::dir, elog, ERROR, AllocateDesc::fd, AllocateDesc::file, AllocateDesc::kind, and numAllocatedDescs.

Referenced by AtEOSubXact_Files(), CleanupTempFiles(), ClosePipeStream(), CloseTransientFile(), FreeDir(), and FreeFile().

2481 {
2482  int result;
2483 
2484  /* Close the underlying object */
2485  switch (desc->kind)
2486  {
2487  case AllocateDescFile:
2488  result = fclose(desc->desc.file);
2489  break;
2490  case AllocateDescPipe:
2491  result = pclose(desc->desc.file);
2492  break;
2493  case AllocateDescDir:
2494  result = closedir(desc->desc.dir);
2495  break;
2496  case AllocateDescRawFD:
2497  result = close(desc->desc.fd);
2498  break;
2499  default:
2500  elog(ERROR, "AllocateDesc kind not recognized");
2501  result = 0; /* keep compiler quiet */
2502  break;
2503  }
2504 
2505  /* Compact storage in the allocatedDescs array */
2508 
2509  return result;
2510 }
static AllocateDesc * allocatedDescs
Definition: fd.c:253
DIR * dir
Definition: fd.c:246
int closedir(DIR *)
Definition: dirent.c:113
AllocateDescKind kind
Definition: fd.c:241
#define ERROR
Definition: elog.h:43
FILE * file
Definition: fd.c:245
int fd
Definition: fd.c:247
union AllocateDesc::@25 desc
#define elog(elevel,...)
Definition: elog.h:214
#define close(a)
Definition: win32.h:12
static int numAllocatedDescs
Definition: fd.c:251

◆ FreeDir()

int FreeDir ( DIR dir)

Definition at line 2699 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(), do_pg_start_backup(), dsm_cleanup_for_mmap(), extension_file_exists(), get_ext_ver_list(), getInstallationPaths(), movedb(), ParseTzFile(), perform_base_backup(), pg_available_extension_versions(), pg_available_extensions(), pg_logdir_ls_internal(), pg_ls_dir(), pg_ls_dir_files(), pg_tablespace_databases(), pg_tzenumerate_end(), pg_tzenumerate_next(), pgarch_readyXlog(), pgstat_reset_remove_files(), RelationCacheInitFileRemove(), RelationCacheInitFileRemoveInDir(), RemoveNonParentXlogFiles(), RemoveOldXlogFiles(), RemovePgTempFiles(), RemovePgTempFilesInDir(), RemovePgTempRelationFiles(), RemovePgTempRelationFilesInDbspace(), RemoveTempXlogFiles(), ReorderBufferCleanupSerializedTXNs(), ResetUnloggedRelations(), ResetUnloggedRelationsInDbspaceDir(), ResetUnloggedRelationsInTablespaceDir(), restoreTwoPhaseData(), scan_directory_ci(), sendDir(), SlruScanDirectory(), StartupReorderBuffer(), StartupReplicationSlots(), UpdateLogicalMappings(), and walkdir().

2700 {
2701  int i;
2702 
2703  /* Nothing to do if AllocateDir failed */
2704  if (dir == NULL)
2705  return 0;
2706 
2707  DO_DB(elog(LOG, "FreeDir: Allocated %d", numAllocatedDescs));
2708 
2709  /* Remove dir from list of allocated dirs, if it's present */
2710  for (i = numAllocatedDescs; --i >= 0;)
2711  {
2712  AllocateDesc *desc = &allocatedDescs[i];
2713 
2714  if (desc->kind == AllocateDescDir && desc->desc.dir == dir)
2715  return FreeDesc(desc);
2716  }
2717 
2718  /* Only get here if someone passes us a dir not in allocatedDescs */
2719  elog(WARNING, "dir passed to FreeDir was not obtained from AllocateDir");
2720 
2721  return closedir(dir);
2722 }
static AllocateDesc * allocatedDescs
Definition: fd.c:253
DIR * dir
Definition: fd.c:246
#define DO_DB(A)
Definition: fd.c:169
int closedir(DIR *)
Definition: dirent.c:113
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:241
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2480
#define WARNING
Definition: elog.h:40
union AllocateDesc::@25 desc
#define elog(elevel,...)
Definition: elog.h:214
int i
static int numAllocatedDescs
Definition: fd.c:251

◆ FreeFile()

int FreeFile ( FILE *  file)

Definition at line 2519 of file fd.c.

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

Referenced by _ShowOption(), AlterSystemSetConfigFile(), apw_dump_now(), apw_load_buffers(), BackendRun(), checkControlFile(), do_pg_start_backup(), do_pg_stop_backup(), EndCopy(), entry_reset(), existsTimeLineHistory(), ExportSnapshot(), fill_hba_view(), gc_qtexts(), ImportSnapshot(), load_dh_file(), 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_internal(), pg_promote(), PGSharedMemoryAttach(), 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(), PostmasterMarkPIDForWorkerNotify(), read_backup_label(), read_binary_file(), read_tablespace_map(), read_whole_file(), readTimeLineHistory(), sendFile(), tokenize_inc_file(), tsearch_readline_end(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

2520 {
2521  int i;
2522 
2523  DO_DB(elog(LOG, "FreeFile: Allocated %d", numAllocatedDescs));
2524 
2525  /* Remove file from list of allocated files, if it's present */
2526  for (i = numAllocatedDescs; --i >= 0;)
2527  {
2528  AllocateDesc *desc = &allocatedDescs[i];
2529 
2530  if (desc->kind == AllocateDescFile && desc->desc.file == file)
2531  return FreeDesc(desc);
2532  }
2533 
2534  /* Only get here if someone passes us a file not in allocatedDescs */
2535  elog(WARNING, "file passed to FreeFile was not obtained from AllocateFile");
2536 
2537  return fclose(file);
2538 }
static AllocateDesc * allocatedDescs
Definition: fd.c:253
#define DO_DB(A)
Definition: fd.c:169
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:241
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2480
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:245
union AllocateDesc::@25 desc
#define elog(elevel,...)
Definition: elog.h:214
int i
static int numAllocatedDescs
Definition: fd.c:251

◆ FreeVfd()

static void FreeVfd ( File  file)
static

Definition at line 1331 of file fd.c.

References DO_DB, elog, vfd::fdstate, vfd::fileName, free, LOG, and vfd::nextFree.

Referenced by FileClose(), and PathNameOpenFilePerm().

1332 {
1333  Vfd *vfdP = &VfdCache[file];
1334 
1335  DO_DB(elog(LOG, "FreeVfd: %d (%s)",
1336  file, vfdP->fileName ? vfdP->fileName : ""));
1337 
1338  if (vfdP->fileName != NULL)
1339  {
1340  free(vfdP->fileName);
1341  vfdP->fileName = NULL;
1342  }
1343  vfdP->fdstate = 0x0;
1344 
1345  vfdP->nextFree = VfdCache[0].nextFree;
1346  VfdCache[0].nextFree = file;
1347 }
File nextFree
Definition: fd.c:190
#define DO_DB(A)
Definition: fd.c:169
static Vfd * VfdCache
Definition: fd.c:205
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:194
unsigned short fdstate
Definition: fd.c:188
Definition: fd.c:185
#define free(a)
Definition: header.h:65
#define elog(elevel,...)
Definition: elog.h:214

◆ fsync_fname()

void fsync_fname ( const char *  fname,
bool  isdir 
)

◆ fsync_fname_ext()

int fsync_fname_ext ( const char *  fname,
bool  isdir,
bool  ignore_perm,
int  elevel 
)

Definition at line 3458 of file fd.c.

References CloseTransientFile(), ereport, errcode_for_file_access(), errmsg(), vfd::fd, OpenTransientFile(), PG_BINARY, and pg_fsync().

Referenced by datadir_fsync_fname(), durable_rename(), durable_rename_excl(), fsync_fname(), fsync_parent_path(), and pg_file_sync().

3459 {
3460  int fd;
3461  int flags;
3462  int returncode;
3463 
3464  /*
3465  * Some OSs require directories to be opened read-only whereas other
3466  * systems don't allow us to fsync files opened read-only; so we need both
3467  * cases here. Using O_RDWR will cause us to fail to fsync files that are
3468  * not writable by our userid, but we assume that's OK.
3469  */
3470  flags = PG_BINARY;
3471  if (!isdir)
3472  flags |= O_RDWR;
3473  else
3474  flags |= O_RDONLY;
3475 
3476  fd = OpenTransientFile(fname, flags);
3477 
3478  /*
3479  * Some OSs don't allow us to open directories at all (Windows returns
3480  * EACCES), just ignore the error in that case. If desired also silently
3481  * ignoring errors about unreadable files. Log others.
3482  */
3483  if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES))
3484  return 0;
3485  else if (fd < 0 && ignore_perm && errno == EACCES)
3486  return 0;
3487  else if (fd < 0)
3488  {
3489  ereport(elevel,
3491  errmsg("could not open file \"%s\": %m", fname)));
3492  return -1;
3493  }
3494 
3495  returncode = pg_fsync(fd);
3496 
3497  /*
3498  * Some OSes don't allow us to fsync directories at all, so we can ignore
3499  * those errors. Anything else needs to be logged.
3500  */
3501  if (returncode != 0 && !(isdir && (errno == EBADF || errno == EINVAL)))
3502  {
3503  int save_errno;
3504 
3505  /* close file upon error, might not be in transaction context */
3506  save_errno = errno;
3507  (void) CloseTransientFile(fd);
3508  errno = save_errno;
3509 
3510  ereport(elevel,
3512  errmsg("could not fsync file \"%s\": %m", fname)));
3513  return -1;
3514  }
3515 
3516  if (CloseTransientFile(fd) != 0)
3517  {
3518  ereport(elevel,
3520  errmsg("could not close file \"%s\": %m", fname)));
3521  return -1;
3522  }
3523 
3524  return 0;
3525 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1234
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2370
int errcode_for_file_access(void)
Definition: elog.c:633
int CloseTransientFile(int fd)
Definition: fd.c:2547
static int elevel
Definition: vacuumlazy.c:323
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824
int pg_fsync(int fd)
Definition: fd.c:343

◆ fsync_parent_path()

static int fsync_parent_path ( const char *  fname,
int  elevel 
)
static

Definition at line 3534 of file fd.c.

References fsync_fname_ext(), get_parent_directory(), MAXPGPATH, and strlcpy().

Referenced by dir_close(), dir_open_for_write(), durable_rename(), durable_rename_excl(), durable_unlink(), and tar_finish().

3535 {
3536  char parentpath[MAXPGPATH];
3537 
3538  strlcpy(parentpath, fname, MAXPGPATH);
3539  get_parent_directory(parentpath);
3540 
3541  /*
3542  * get_parent_directory() returns an empty string if the input argument is
3543  * just a file name (see comments in path.c), so handle that as being the
3544  * current directory.
3545  */
3546  if (strlen(parentpath) == 0)
3547  strlcpy(parentpath, ".", MAXPGPATH);
3548 
3549  if (fsync_fname_ext(parentpath, true, false, elevel) != 0)
3550  return -1;
3551 
3552  return 0;
3553 }
#define MAXPGPATH
void get_parent_directory(char *path)
Definition: path.c:854
static int elevel
Definition: vacuumlazy.c:323
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3458

◆ GetNextTempTableSpace()

Oid GetNextTempTableSpace ( void  )

Definition at line 2842 of file fd.c.

References InvalidOid, nextTempTableSpace, numTempTableSpaces, and tempTableSpaces.

Referenced by GetDefaultTablespace(), and OpenTemporaryFile().

2843 {
2844  if (numTempTableSpaces > 0)
2845  {
2846  /* Advance nextTempTableSpace counter with wraparound */
2848  nextTempTableSpace = 0;
2850  }
2851  return InvalidOid;
2852 }
static int numTempTableSpaces
Definition: fd.c:271
static int nextTempTableSpace
Definition: fd.c:272
#define InvalidOid
Definition: postgres_ext.h:36
static Oid * tempTableSpaces
Definition: fd.c:270

◆ GetTempTablespaces()

int GetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 2824 of file fd.c.

References Assert, i, numTempTableSpaces, tempTableSpaces, and TempTablespacesAreSet().

Referenced by SharedFileSetInit().

2825 {
2826  int i;
2827 
2829  for (i = 0; i < numTempTableSpaces && i < numSpaces; ++i)
2830  tableSpaces[i] = tempTableSpaces[i];
2831 
2832  return i;
2833 }
static int numTempTableSpaces
Definition: fd.c:271
bool TempTablespacesAreSet(void)
Definition: fd.c:2812
#define Assert(condition)
Definition: c.h:738
static Oid * tempTableSpaces
Definition: fd.c:270
int i

◆ InitFileAccess()

void InitFileAccess ( void  )

Definition at line 823 of file fd.c.

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

Referenced by BaseInit().

824 {
825  Assert(SizeVfdCache == 0); /* call me only once */
826 
827  /* initialize cache header entry */
828  VfdCache = (Vfd *) malloc(sizeof(Vfd));
829  if (VfdCache == NULL)
830  ereport(FATAL,
831  (errcode(ERRCODE_OUT_OF_MEMORY),
832  errmsg("out of memory")));
833 
834  MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));
836 
837  SizeVfdCache = 1;
838 
839  /* register proc-exit hook to ensure temp files are dropped at exit */
841 }
static void AtProcExit_Files(int code, Datum arg)
Definition: fd.c:2910
static Size SizeVfdCache
Definition: fd.c:206
void on_proc_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:305
static Vfd * VfdCache
Definition: fd.c:205
int errcode(int sqlerrcode)
Definition: elog.c:610
#define MemSet(start, val, len)
Definition: c.h:971
#define malloc(a)
Definition: header.h:50
#define FATAL
Definition: elog.h:52
Definition: fd.c:185
int fd
Definition: fd.c:187
#define VFD_CLOSED
Definition: fd.c:173
#define ereport(elevel,...)
Definition: elog.h:144
#define Assert(condition)
Definition: c.h:738
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ Insert()

static void Insert ( File  file)
static

Definition at line 1172 of file fd.c.

References Assert, DO_DB, elog, vfd::fileName, LOG, vfd::lruLessRecently, and vfd::lruMoreRecently.

Referenced by AdvanceXLInsertBuffer(), CreateCheckPoint(), FileAccess(), GetXLogInsertRecPtr(), InitXLOGAccess(), LruInsert(), PathNameOpenFilePerm(), ReserveXLogInsertLocation(), ReserveXLogSwitch(), StartupXLOG(), UpdateFullPageWrites(), WaitXLogInsertionsToFinish(), and XLogInsertRecord().

1173 {
1174  Vfd *vfdP;
1175 
1176  Assert(file != 0);
1177 
1178  DO_DB(elog(LOG, "Insert %d (%s)",
1179  file, VfdCache[file].fileName));
1180  DO_DB(_dump_lru());
1181 
1182  vfdP = &VfdCache[file];
1183 
1184  vfdP->lruMoreRecently = 0;
1186  VfdCache[0].lruLessRecently = file;
1188 
1189  DO_DB(_dump_lru());
1190 }
File lruLessRecently
Definition: fd.c:192
#define DO_DB(A)
Definition: fd.c:169
static Vfd * VfdCache
Definition: fd.c:205
#define LOG
Definition: elog.h:26
Definition: fd.c:185
#define Assert(condition)
Definition: c.h:738
File lruMoreRecently
Definition: fd.c:191
#define elog(elevel,...)
Definition: elog.h:214

◆ looks_like_temp_rel_name()

bool looks_like_temp_rel_name ( const char *  name)

Definition at line 3179 of file fd.c.

References forkname_chars().

Referenced by RemovePgTempRelationFilesInDbspace(), and sendDir().

3180 {
3181  int pos;
3182  int savepos;
3183 
3184  /* Must start with "t". */
3185  if (name[0] != 't')
3186  return false;
3187 
3188  /* Followed by a non-empty string of digits and then an underscore. */
3189  for (pos = 1; isdigit((unsigned char) name[pos]); ++pos)
3190  ;
3191  if (pos == 1 || name[pos] != '_')
3192  return false;
3193 
3194  /* Followed by another nonempty string of digits. */
3195  for (savepos = ++pos; isdigit((unsigned char) name[pos]); ++pos)
3196  ;
3197  if (savepos == pos)
3198  return false;
3199 
3200  /* We might have _forkname or .segment or both. */
3201  if (name[pos] == '_')
3202  {
3203  int forkchar = forkname_chars(&name[pos + 1], NULL);
3204 
3205  if (forkchar <= 0)
3206  return false;
3207  pos += forkchar + 1;
3208  }
3209  if (name[pos] == '.')
3210  {
3211  int segchar;
3212 
3213  for (segchar = 1; isdigit((unsigned char) name[pos + segchar]); ++segchar)
3214  ;
3215  if (segchar <= 1)
3216  return false;
3217  pos += segchar;
3218  }
3219 
3220  /* Now we should be at the end. */
3221  if (name[pos] != '\0')
3222  return false;
3223  return true;
3224 }
int forkname_chars(const char *str, ForkNumber *fork)
Definition: relpath.c:81
const char * name
Definition: encode.c:521

◆ LruDelete()

static void LruDelete ( File  file)
static

Definition at line 1146 of file fd.c.

References Assert, close, data_sync_elevel(), Delete(), DO_DB, elog, vfd::fd, FD_TEMP_FILE_LIMIT, vfd::fdstate, vfd::fileName, LOG, nfile, and VFD_CLOSED.

Referenced by closeAllVfds(), RegisterTemporaryFile(), and ReleaseLruFile().

1147 {
1148  Vfd *vfdP;
1149 
1150  Assert(file != 0);
1151 
1152  DO_DB(elog(LOG, "LruDelete %d (%s)",
1153  file, VfdCache[file].fileName));
1154 
1155  vfdP = &VfdCache[file];
1156 
1157  /*
1158  * Close the file. We aren't expecting this to fail; if it does, better
1159  * to leak the FD than to mess up our internal state.
1160  */
1161  if (close(vfdP->fd) != 0)
1163  "could not close file \"%s\": %m", vfdP->fileName);
1164  vfdP->fd = VFD_CLOSED;
1165  --nfile;
1166 
1167  /* delete the vfd record from the LRU ring */
1168  Delete(file);
1169 }
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:183
#define DO_DB(A)
Definition: fd.c:169
static Vfd * VfdCache
Definition: fd.c:205
static void Delete(File file)
Definition: fd.c:1127
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:194
static int nfile
Definition: fd.c:211
unsigned short fdstate
Definition: fd.c:188
Definition: fd.c:185
int fd
Definition: fd.c:187
int data_sync_elevel(int elevel)
Definition: fd.c:3597
#define VFD_CLOSED
Definition: fd.c:173
#define Assert(condition)
Definition: c.h:738
#define elog(elevel,...)
Definition: elog.h:214
#define close(a)
Definition: win32.h:12

◆ LruInsert()

static int LruInsert ( File  file)
static

Definition at line 1194 of file fd.c.

References Assert, BasicOpenFilePerm(), DO_DB, elog, vfd::fd, vfd::fileFlags, FileIsNotOpen, vfd::fileMode, vfd::fileName, Insert(), LOG, nfile, and ReleaseLruFiles().

Referenced by FileAccess().

1195 {
1196  Vfd *vfdP;
1197 
1198  Assert(file != 0);
1199 
1200  DO_DB(elog(LOG, "LruInsert %d (%s)",
1201  file, VfdCache[file].fileName));
1202 
1203  vfdP = &VfdCache[file];
1204 
1205  if (FileIsNotOpen(file))
1206  {
1207  /* Close excess kernel FDs. */
1208  ReleaseLruFiles();
1209 
1210  /*
1211  * The open could still fail for lack of file descriptors, eg due to
1212  * overall system file table being full. So, be prepared to release
1213  * another FD if necessary...
1214  */
1215  vfdP->fd = BasicOpenFilePerm(vfdP->fileName, vfdP->fileFlags,
1216  vfdP->fileMode);
1217  if (vfdP->fd < 0)
1218  {
1219  DO_DB(elog(LOG, "re-open failed: %m"));
1220  return -1;
1221  }
1222  else
1223  {
1224  ++nfile;
1225  }
1226  }
1227 
1228  /*
1229  * put it at the head of the Lru ring
1230  */
1231 
1232  Insert(file);
1233 
1234  return 0;
1235 }
#define DO_DB(A)
Definition: fd.c:169
static Vfd * VfdCache
Definition: fd.c:205
#define LOG
Definition: elog.h:26
mode_t fileMode
Definition: fd.c:197
char * fileName
Definition: fd.c:194
static int nfile
Definition: fd.c:211
Definition: fd.c:185
int fd
Definition: fd.c:187
static void Insert(File file)
Definition: fd.c:1172
static void ReleaseLruFiles(void)
Definition: fd.c:1263
#define FileIsNotOpen(file)
Definition: fd.c:178
#define Assert(condition)
Definition: c.h:738
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1005
#define elog(elevel,...)
Definition: elog.h:214
int fileFlags
Definition: fd.c:196

◆ MakePGDirectory()

int MakePGDirectory ( const char *  directoryName)

◆ OpenPipeStream()

FILE* OpenPipeStream ( const char *  command,
const char *  mode 
)

Definition at line 2423 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, numAllocatedDescs, pqsignal(), ReleaseLruFile(), ReleaseLruFiles(), reserveAllocatedDesc(), SIG_DFL, SIG_IGN, SIGPIPE, and generate_unaccent_rules::stdout.

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

2424 {
2425  FILE *file;
2426  int save_errno;
2427 
2428  DO_DB(elog(LOG, "OpenPipeStream: Allocated %d (%s)",
2429  numAllocatedDescs, command));
2430 
2431  /* Can we allocate another non-virtual FD? */
2432  if (!reserveAllocatedDesc())
2433  ereport(ERROR,
2434  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2435  errmsg("exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"",
2436  maxAllocatedDescs, command)));
2437 
2438  /* Close excess kernel FDs. */
2439  ReleaseLruFiles();
2440 
2441 TryAgain:
2442  fflush(stdout);
2443  fflush(stderr);
2445  errno = 0;
2446  file = popen(command, mode);
2447  save_errno = errno;
2449  errno = save_errno;
2450  if (file != NULL)
2451  {
2453 
2454  desc->kind = AllocateDescPipe;
2455  desc->desc.file = file;
2458  return desc->desc.file;
2459  }
2460 
2461  if (errno == EMFILE || errno == ENFILE)
2462  {
2463  ereport(LOG,
2464  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2465  errmsg("out of file descriptors: %m; release and retry")));
2466  if (ReleaseLruFile())
2467  goto TryAgain;
2468  errno = save_errno;
2469  }
2470 
2471  return NULL;
2472 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
static AllocateDesc * allocatedDescs
Definition: fd.c:253
#define DO_DB(A)
Definition: fd.c:169
int errcode(int sqlerrcode)
Definition: elog.c:610
static bool reserveAllocatedDesc(void)
Definition: fd.c:2245
#define SIGPIPE
Definition: win32_port.h:158
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:241
static bool ReleaseLruFile(void)
Definition: fd.c:1241
#define ERROR
Definition: elog.h:43
#define SIG_IGN
Definition: win32_port.h:150
static void ReleaseLruFiles(void)
Definition: fd.c:1263
FILE * file
Definition: fd.c:245
#define ereport(elevel,...)
Definition: elog.h:144
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:170
#define SIG_DFL
Definition: win32_port.h:148
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:707
SubTransactionId create_subid
Definition: fd.c:242
union AllocateDesc::@25 desc
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
static int maxAllocatedDescs
Definition: fd.c:252
static int numAllocatedDescs
Definition: fd.c:251

◆ OpenTemporaryFile()

File OpenTemporaryFile ( bool  interXact)

Definition at line 1575 of file fd.c.

References CurrentResourceOwner, FD_DELETE_AT_CLOSE, FD_TEMP_FILE_LIMIT, vfd::fdstate, GetNextTempTableSpace(), MyDatabaseTableSpace, numTempTableSpaces, OidIsValid, OpenTemporaryFileInTablespace(), RegisterTemporaryFile(), and ResourceOwnerEnlargeFiles().

Referenced by BufFileCreateTemp(), and extendBufFile().

1576 {
1577  File file = 0;
1578 
1579  /*
1580  * Make sure the current resource owner has space for this File before we
1581  * open it, if we'll be registering it below.
1582  */
1583  if (!interXact)
1585 
1586  /*
1587  * If some temp tablespace(s) have been given to us, try to use the next
1588  * one. If a given tablespace can't be found, we silently fall back to
1589  * the database's default tablespace.
1590  *
1591  * BUT: if the temp file is slated to outlive the current transaction,
1592  * force it into the database's default tablespace, so that it will not
1593  * pose a threat to possible tablespace drop attempts.
1594  */
1595  if (numTempTableSpaces > 0 && !interXact)
1596  {
1597  Oid tblspcOid = GetNextTempTableSpace();
1598 
1599  if (OidIsValid(tblspcOid))
1600  file = OpenTemporaryFileInTablespace(tblspcOid, false);
1601  }
1602 
1603  /*
1604  * If not, or if tablespace is bad, create in database's default
1605  * tablespace. MyDatabaseTableSpace should normally be set before we get
1606  * here, but just in case it isn't, fall back to pg_default tablespace.
1607  */
1608  if (file <= 0)
1611  DEFAULTTABLESPACE_OID,
1612  true);
1613 
1614  /* Mark it for deletion at close and temporary file size limit */
1616 
1617  /* Register it with the current resource owner */
1618  if (!interXact)
1619  RegisterTemporaryFile(file);
1620 
1621  return file;
1622 }
static File OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError)
Definition: fd.c:1653
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:183
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
#define FD_DELETE_AT_CLOSE
Definition: fd.c:181
static Vfd * VfdCache
Definition: fd.c:205
static int numTempTableSpaces
Definition: fd.c:271
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
Oid MyDatabaseTableSpace
Definition: globals.c:87
Oid GetNextTempTableSpace(void)
Definition: fd.c:2842
unsigned short fdstate
Definition: fd.c:188
static void RegisterTemporaryFile(File file)
Definition: fd.c:1406
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1257
int File
Definition: fd.h:49

◆ OpenTemporaryFileInTablespace()

static File OpenTemporaryFileInTablespace ( Oid  tblspcOid,
bool  rejectError 
)
static

Definition at line 1653 of file fd.c.

References elog, ERROR, MakePGDirectory(), MAXPGPATH, MyProcPid, PathNameOpenFile(), PG_BINARY, PG_TEMP_FILE_PREFIX, snprintf, tempFileCounter, and TempTablespacePath().

Referenced by OpenTemporaryFile().

1654 {
1655  char tempdirpath[MAXPGPATH];
1656  char tempfilepath[MAXPGPATH];
1657  File file;
1658 
1659  TempTablespacePath(tempdirpath, tblspcOid);
1660 
1661  /*
1662  * Generate a tempfile name that should be unique within the current
1663  * database instance.
1664  */
1665  snprintf(tempfilepath, sizeof(tempfilepath), "%s/%s%d.%ld",
1666  tempdirpath, PG_TEMP_FILE_PREFIX, MyProcPid, tempFileCounter++);
1667 
1668  /*
1669  * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1670  * temp file that can be reused.
1671  */
1672  file = PathNameOpenFile(tempfilepath,
1673  O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1674  if (file <= 0)
1675  {
1676  /*
1677  * We might need to create the tablespace's tempfile directory, if no
1678  * one has yet done so.
1679  *
1680  * Don't check for an error from MakePGDirectory; it could fail if
1681  * someone else just did the same thing. If it doesn't work then
1682  * we'll bomb out on the second create attempt, instead.
1683  */
1684  (void) MakePGDirectory(tempdirpath);
1685 
1686  file = PathNameOpenFile(tempfilepath,
1687  O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1688  if (file <= 0 && rejectError)
1689  elog(ERROR, "could not create temporary file \"%s\": %m",
1690  tempfilepath);
1691  }
1692 
1693  return file;
1694 }
int MyProcPid
Definition: globals.c:40
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1434
void TempTablespacePath(char *path, Oid tablespace)
Definition: fd.c:1628
#define PG_BINARY
Definition: c.h:1234
#define ERROR
Definition: elog.h:43
#define PG_TEMP_FILE_PREFIX
Definition: pg_checksums.c:59
#define MAXPGPATH
int MakePGDirectory(const char *directoryName)
Definition: fd.c:3574
static long tempFileCounter
Definition: fd.c:264
#define elog(elevel,...)
Definition: elog.h:214
#define snprintf
Definition: port.h:193
int File
Definition: fd.h:49

◆ OpenTransientFile()

◆ OpenTransientFilePerm()

int OpenTransientFilePerm ( const char *  fileName,
int  fileFlags,
mode_t  fileMode 
)

Definition at line 2379 of file fd.c.

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

Referenced by be_lo_export(), and OpenTransientFile().

2380 {
2381  int fd;
2382 
2383  DO_DB(elog(LOG, "OpenTransientFile: Allocated %d (%s)",
2384  numAllocatedDescs, fileName));
2385 
2386  /* Can we allocate another non-virtual FD? */
2387  if (!reserveAllocatedDesc())
2388  ereport(ERROR,
2389  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2390  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2391  maxAllocatedDescs, fileName)));
2392 
2393  /* Close excess kernel FDs. */
2394  ReleaseLruFiles();
2395 
2396  fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
2397 
2398  if (fd >= 0)
2399  {
2401 
2402  desc->kind = AllocateDescRawFD;
2403  desc->desc.fd = fd;
2406 
2407  return fd;
2408  }
2409 
2410  return -1; /* failure */
2411 }
static AllocateDesc * allocatedDescs
Definition: fd.c:253
#define DO_DB(A)
Definition: fd.c:169
int errcode(int sqlerrcode)
Definition: elog.c:610
static bool reserveAllocatedDesc(void)
Definition: fd.c:2245
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:241
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define ERROR
Definition: elog.h:43
static void ReleaseLruFiles(void)
Definition: fd.c:1263
#define ereport(elevel,...)
Definition: elog.h:144
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:707
SubTransactionId create_subid
Definition: fd.c:242
int fd
Definition: fd.c:247
union AllocateDesc::@25 desc
int errmsg(const char *fmt,...)
Definition: elog.c:824
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1005
#define elog(elevel,...)
Definition: elog.h:214
static int maxAllocatedDescs
Definition: fd.c:252
static int numAllocatedDescs
Definition: fd.c:251

◆ PathNameCreateTemporaryDir()

void PathNameCreateTemporaryDir ( const char *  basedir,
const char *  directory 
)

Definition at line 1511 of file fd.c.

References ereport, errcode_for_file_access(), errmsg(), ERROR, and MakePGDirectory().

Referenced by SharedFileSetCreate().

1512 {
1513  if (MakePGDirectory(directory) < 0)
1514  {
1515  if (errno == EEXIST)
1516  return;
1517 
1518  /*
1519  * Failed. Try to create basedir first in case it's missing. Tolerate
1520  * EEXIST to close a race against another process following the same
1521  * algorithm.
1522  */
1523  if (MakePGDirectory(basedir) < 0 && errno != EEXIST)
1524  ereport(ERROR,
1526  errmsg("cannot create temporary directory \"%s\": %m",
1527  basedir)));
1528 
1529  /* Try again. */
1530  if (MakePGDirectory(directory) < 0 && errno != EEXIST)
1531  ereport(ERROR,
1533  errmsg("cannot create temporary subdirectory \"%s\": %m",
1534  directory)));
1535  }
1536 }
static char * basedir
#define ERROR
Definition: elog.h:43
int errcode_for_file_access(void)
Definition: elog.c:633
#define ereport(elevel,...)
Definition: elog.h:144
int MakePGDirectory(const char *directoryName)
Definition: fd.c:3574
static const char * directory
Definition: zic.c:622
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ PathNameCreateTemporaryFile()

File PathNameCreateTemporaryFile ( const char *  path,
bool  error_on_failure 
)

Definition at line 1710 of file fd.c.

References CurrentResourceOwner, ereport, errcode_for_file_access(), errmsg(), ERROR, FD_TEMP_FILE_LIMIT, vfd::fdstate, PathNameOpenFile(), PG_BINARY, RegisterTemporaryFile(), and ResourceOwnerEnlargeFiles().

Referenced by SharedFileSetCreate().

1711 {
1712  File file;
1713 
1715 
1716  /*
1717  * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1718  * temp file that can be reused.
1719  */
1720  file = PathNameOpenFile(path, O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1721  if (file <= 0)
1722  {
1723  if (error_on_failure)
1724  ereport(ERROR,
1726  errmsg("could not create temporary file \"%s\": %m",
1727  path)));
1728  else
1729  return file;
1730  }
1731 
1732  /* Mark it for temp_file_limit accounting. */
1734 
1735  /* Register it for automatic close. */
1736  RegisterTemporaryFile(file);
1737 
1738  return file;
1739 }
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1434
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:183
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
static Vfd * VfdCache
Definition: fd.c:205
#define PG_BINARY
Definition: c.h:1234
#define ERROR
Definition: elog.h:43
int errcode_for_file_access(void)
Definition: elog.c:633
unsigned short fdstate
Definition: fd.c:188
#define ereport(elevel,...)
Definition: elog.h:144
static void RegisterTemporaryFile(File file)
Definition: fd.c:1406
int errmsg(const char *fmt,...)
Definition: elog.c:824
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1257
int File
Definition: fd.h:49

◆ PathNameDeleteTemporaryDir()

void PathNameDeleteTemporaryDir ( const char *  dirname)

Definition at line 1542 of file fd.c.

References LOG, stat, unlink_if_exists_fname(), and walkdir().

Referenced by SharedFileSetDeleteAll().

1543 {
1544  struct stat statbuf;
1545 
1546  /* Silently ignore missing directory. */
1547  if (stat(dirname, &statbuf) != 0 && errno == ENOENT)
1548  return;
1549 
1550  /*
1551  * Currently, walkdir doesn't offer a way for our passed in function to
1552  * maintain state. Perhaps it should, so that we could tell the caller
1553  * whether this operation succeeded or failed. Since this operation is
1554  * used in a cleanup path, we wouldn't actually behave differently: we'll
1555  * just log failures.
1556  */
1557  walkdir(dirname, unlink_if_exists_fname, false, LOG);
1558 }
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
Definition: fd.c:3323
#define LOG
Definition: elog.h:26
static void unlink_if_exists_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3433
#define stat(a, b)
Definition: win32_port.h:255

◆ PathNameDeleteTemporaryFile()

bool PathNameDeleteTemporaryFile ( const char *  path,
bool  error_on_failure 
)

Definition at line 1778 of file fd.c.

References ereport, errcode_for_file_access(), errmsg(), ERROR, LOG, ReportTemporaryFileUsage(), and stat.

Referenced by SharedFileSetDelete(), and unlink_if_exists_fname().

1779 {
1780  struct stat filestats;
1781  int stat_errno;
1782 
1783  /* Get the final size for pgstat reporting. */
1784  if (stat(path, &filestats) != 0)
1785  stat_errno = errno;
1786  else
1787  stat_errno = 0;
1788 
1789  /*
1790  * Unlike FileClose's automatic file deletion code, we tolerate
1791  * non-existence to support BufFileDeleteShared which doesn't know how
1792  * many segments it has to delete until it runs out.
1793  */
1794  if (stat_errno == ENOENT)
1795  return false;
1796 
1797  if (unlink(path) < 0)
1798  {
1799  if (errno != ENOENT)
1800  ereport(error_on_failure ? ERROR : LOG,
1802  errmsg("could not unlink temporary file \"%s\": %m",
1803  path)));
1804  return false;
1805  }
1806 
1807  if (stat_errno == 0)
1808  ReportTemporaryFileUsage(path, filestats.st_size);
1809  else
1810  {
1811  errno = stat_errno;
1812  ereport(LOG,
1814  errmsg("could not stat file \"%s\": %m", path)));
1815  }
1816 
1817  return true;
1818 }
#define LOG
Definition: elog.h:26
#define ERROR
Definition: elog.h:43
int errcode_for_file_access(void)
Definition: elog.c:633
static void ReportTemporaryFileUsage(const char *path, off_t size)
Definition: fd.c:1387
#define stat(a, b)
Definition: win32_port.h:255
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ PathNameOpenFile()

File PathNameOpenFile ( const char *  fileName,
int  fileFlags 
)

Definition at line 1434 of file fd.c.

References PathNameOpenFilePerm(), and pg_file_create_mode.

Referenced by _mdfd_openseg(), logical_rewrite_log_mapping(), mdcreate(), mdopenfork(), mdsyncfiletag(), OpenTemporaryFileInTablespace(), PathNameCreateTemporaryFile(), PathNameOpenTemporaryFile(), and ReorderBufferRestoreChanges().

1435 {
1436  return PathNameOpenFilePerm(fileName, fileFlags, pg_file_create_mode);
1437 }
File PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1447
int pg_file_create_mode
Definition: file_perm.c:19

◆ PathNameOpenFilePerm()

File PathNameOpenFilePerm ( const char *  fileName,
int  fileFlags,
mode_t  fileMode 
)

Definition at line 1447 of file fd.c.

References AllocateVfd(), BasicOpenFilePerm(), DO_DB, elog, ereport, errcode(), errmsg(), ERROR, vfd::fd, vfd::fdstate, vfd::fileFlags, vfd::fileMode, vfd::fileName, vfd::fileSize, free, FreeVfd(), Insert(), LOG, nfile, ReleaseLruFiles(), and vfd::resowner.

Referenced by PathNameOpenFile().

1448 {
1449  char *fnamecopy;
1450  File file;
1451  Vfd *vfdP;
1452 
1453  DO_DB(elog(LOG, "PathNameOpenFilePerm: %s %x %o",
1454  fileName, fileFlags, fileMode));
1455 
1456  /*
1457  * We need a malloc'd copy of the file name; fail cleanly if no room.
1458  */
1459  fnamecopy = strdup(fileName);
1460  if (fnamecopy == NULL)
1461  ereport(ERROR,
1462  (errcode(ERRCODE_OUT_OF_MEMORY),
1463  errmsg("out of memory")));
1464 
1465  file = AllocateVfd();
1466  vfdP = &VfdCache[file];
1467 
1468  /* Close excess kernel FDs. */
1469  ReleaseLruFiles();
1470 
1471  vfdP->fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
1472 
1473  if (vfdP->fd < 0)
1474  {
1475  int save_errno = errno;
1476 
1477  FreeVfd(file);
1478  free(fnamecopy);
1479  errno = save_errno;
1480  return -1;
1481  }
1482  ++nfile;
1483  DO_DB(elog(LOG, "PathNameOpenFile: success %d",
1484  vfdP->fd));
1485 
1486  Insert(file);
1487 
1488  vfdP->fileName = fnamecopy;
1489  /* Saved flags are adjusted to be OK for re-opening file */
1490  vfdP->fileFlags = fileFlags & ~(O_CREAT | O_TRUNC | O_EXCL);
1491  vfdP->fileMode = fileMode;
1492  vfdP->fileSize = 0;
1493  vfdP->fdstate = 0x0;
1494  vfdP->resowner = NULL;
1495 
1496  return file;
1497 }
#define DO_DB(A)
Definition: fd.c:169
static Vfd * VfdCache
Definition: fd.c:205
int errcode(int sqlerrcode)
Definition: elog.c:610
#define LOG
Definition: elog.h:26
mode_t fileMode
Definition: fd.c:197
#define ERROR
Definition: elog.h:43
char * fileName
Definition: fd.c:194
static int nfile
Definition: fd.c:211
static File AllocateVfd(void)
Definition: fd.c:1273
unsigned short fdstate
Definition: fd.c:188
Definition: fd.c:185
off_t fileSize
Definition: fd.c:193
int fd
Definition: fd.c:187
static void Insert(File file)
Definition: fd.c:1172
ResourceOwner resowner
Definition: fd.c:189
static void ReleaseLruFiles(void)
Definition: fd.c:1263
#define ereport(elevel,...)
Definition: elog.h:144
#define free(a)
Definition: header.h:65
int errmsg(const char *fmt,...)
Definition: elog.c:824
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1005
#define elog(elevel,...)
Definition: elog.h:214
static void FreeVfd(File file)
Definition: fd.c:1331
int fileFlags
Definition: fd.c:196
int File
Definition: fd.h:49

◆ PathNameOpenTemporaryFile()

File PathNameOpenTemporaryFile ( const char *  path)

Definition at line 1748 of file fd.c.

References CurrentResourceOwner, ereport, errcode_for_file_access(), errmsg(), ERROR, PathNameOpenFile(), PG_BINARY, RegisterTemporaryFile(), and ResourceOwnerEnlargeFiles().

Referenced by SharedFileSetOpen().

1749 {
1750  File file;
1751 
1753 
1754  /* We open the file read-only. */
1755  file = PathNameOpenFile(path, O_RDONLY | PG_BINARY);
1756 
1757  /* If no such file, then we don't raise an error. */
1758  if (file <= 0 && errno != ENOENT)
1759  ereport(ERROR,
1761  errmsg("could not open temporary file \"%s\": %m",
1762  path)));
1763 
1764  if (file > 0)
1765  {
1766  /* Register it for automatic close. */
1767  RegisterTemporaryFile(file);
1768  }
1769 
1770  return file;
1771 }
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1434
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
#define PG_BINARY
Definition: c.h:1234
#define ERROR
Definition: elog.h:43
int errcode_for_file_access(void)
Definition: elog.c:633
#define ereport(elevel,...)
Definition: elog.h:144
static void RegisterTemporaryFile(File file)
Definition: fd.c:1406
int errmsg(const char *fmt,...)
Definition: elog.c:824
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1257
int File
Definition: fd.h:49

◆ pg_fdatasync()

int pg_fdatasync ( int  fd)

Definition at line 433 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync().

434 {
435  if (enableFsync)
436  {
437 #ifdef HAVE_FDATASYNC
438  return fdatasync(fd);
439 #else
440  return fsync(fd);
441 #endif
442  }
443  else
444  return 0;
445 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define fsync(fd)
Definition: win32_port.h:62
bool enableFsync
Definition: globals.c:119

◆ pg_flush_data()

void pg_flush_data ( int  fd,
off_t  offset,
off_t  nbytes 
)

Definition at line 453 of file fd.c.

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

Referenced by copy_file(), FileWriteback(), and walkdir().

454 {
455  /*
456  * Right now file flushing is primarily used to avoid making later
457  * fsync()/fdatasync() calls have less impact. Thus don't trigger flushes
458  * if fsyncs are disabled - that's a decision we might want to make
459  * configurable at some point.
460  */
461  if (!enableFsync)
462  return;
463 
464  /*
465  * We compile all alternatives that are supported on the current platform,
466  * to find portability problems more easily.
467  */
468 #if defined(HAVE_SYNC_FILE_RANGE)
469  {
470  int rc;
471  static bool not_implemented_by_kernel = false;
472 
473  if (not_implemented_by_kernel)
474  return;
475 
476  /*
477  * sync_file_range(SYNC_FILE_RANGE_WRITE), currently linux specific,
478  * tells the OS that writeback for the specified blocks should be
479  * started, but that we don't want to wait for completion. Note that
480  * this call might block if too much dirty data exists in the range.
481  * This is the preferable method on OSs supporting it, as it works
482  * reliably when available (contrast to msync()) and doesn't flush out
483  * clean data (like FADV_DONTNEED).
484  */
485  rc = sync_file_range(fd, offset, nbytes,
486  SYNC_FILE_RANGE_WRITE);
487  if (rc != 0)
488  {
489  int elevel;
490 
491  /*
492  * For systems that don't have an implementation of
493  * sync_file_range() such as Windows WSL, generate only one
494  * warning and then suppress all further attempts by this process.
495  */
496  if (errno == ENOSYS)
497  {
498  elevel = WARNING;
499  not_implemented_by_kernel = true;
500  }
501  else
502  elevel = data_sync_elevel(WARNING);
503 
504  ereport(elevel,
506  errmsg("could not flush dirty data: %m")));
507  }
508 
509  return;
510  }
511 #endif
512 #if !defined(WIN32) && defined(MS_ASYNC)
513  {
514  void *p;
515  static int pagesize = 0;
516 
517  /*
518  * On several OSs msync(MS_ASYNC) on a mmap'ed file triggers
519  * writeback. On linux it only does so if MS_SYNC is specified, but
520  * then it does the writeback synchronously. Luckily all common linux
521  * systems have sync_file_range(). This is preferable over
522  * FADV_DONTNEED because it doesn't flush out clean data.
523  *
524  * We map the file (mmap()), tell the kernel to sync back the contents
525  * (msync()), and then remove the mapping again (munmap()).
526  */
527 
528  /* mmap() needs actual length if we want to map whole file */
529  if (offset == 0 && nbytes == 0)
530  {
531  nbytes = lseek(fd, 0, SEEK_END);
532  if (nbytes < 0)
533  {
536  errmsg("could not determine dirty data size: %m")));
537  return;
538  }
539  }
540 
541  /*
542  * Some platforms reject partial-page mmap() attempts. To deal with
543  * that, just truncate the request to a page boundary. If any extra
544  * bytes don't get flushed, well, it's only a hint anyway.
545  */
546 
547  /* fetch pagesize only once */
548  if (pagesize == 0)
549  pagesize = sysconf(_SC_PAGESIZE);
550 
551  /* align length to pagesize, dropping any fractional page */
552  if (pagesize > 0)
553  nbytes = (nbytes / pagesize) * pagesize;
554 
555  /* fractional-page request is a no-op */
556  if (nbytes <= 0)
557  return;
558 
559  /*
560  * mmap could well fail, particularly on 32-bit platforms where there
561  * may simply not be enough address space. If so, silently fall
562  * through to the next implementation.
563  */
564  if (nbytes <= (off_t) SSIZE_MAX)
565  p = mmap(NULL, nbytes, PROT_READ, MAP_SHARED, fd, offset);
566  else
567  p = MAP_FAILED;
568 
569  if (p != MAP_FAILED)
570  {
571  int rc;
572 
573  rc = msync(p, (size_t) nbytes, MS_ASYNC);
574  if (rc != 0)
575  {
578  errmsg("could not flush dirty data: %m")));
579  /* NB: need to fall through to munmap()! */
580  }
581 
582  rc = munmap(p, (size_t) nbytes);
583  if (rc != 0)
584  {
585  /* FATAL error because mapping would remain */
586  ereport(FATAL,
588  errmsg("could not munmap() while flushing data: %m")));
589  }
590 
591  return;
592  }
593  }
594 #endif
595 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
596  {
597  int rc;
598 
599  /*
600  * Signal the kernel that the passed in range should not be cached
601  * anymore. This has the, desired, side effect of writing out dirty
602  * data, and the, undesired, side effect of likely discarding useful
603  * clean cached blocks. For the latter reason this is the least
604  * preferable method.
605  */
606 
607  rc = posix_fadvise(fd, offset, nbytes, POSIX_FADV_DONTNEED);
608 
609  if (rc != 0)
610  {
611  /* don't error out, this is just a performance optimization */
614  errmsg("could not flush dirty data: %m")));
615  }
616 
617  return;
618  }
619 #endif
620 }
#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:633
#define WARNING
Definition: elog.h:40
static int elevel
Definition: vacuumlazy.c:323
int data_sync_elevel(int elevel)
Definition: fd.c:3597
#define ereport(elevel,...)
Definition: elog.h:144
bool enableFsync
Definition: globals.c:119
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ pg_fsync()

int pg_fsync ( int  fd)

Definition at line 343 of file fd.c.

References Assert, pg_fsync_no_writethrough(), pg_fsync_writethrough(), S_ISDIR, stat, 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(), readRecoverySignalFile(), RecreateTwoPhaseFile(), RestoreSlotFromDisk(), SaveSlotToPath(), SimpleLruFlush(), SlruPhysicalWritePage(), SnapBuildSerialize(), update_controlfile(), write_auto_conf_file(), write_relmap_file(), WriteControlFile(), writeTimeLineHistory(), writeTimeLineHistoryFile(), XLogFileCopy(), and XLogFileInit().

344 {
345 #if !defined(WIN32) && defined(USE_ASSERT_CHECKING)
346  struct stat st;
347 
348  /*
349  * Some operating system implementations of fsync() have requirements
350  * about the file access modes that were used when their file descriptor
351  * argument was opened, and these requirements differ depending on whether
352  * the file descriptor is for a directory.
353  *
354  * For any file descriptor that may eventually be handed to fsync(), we
355  * should have opened it with access modes that are compatible with
356  * fsync() on all supported systems, otherwise the code may not be
357  * portable, even if it runs ok on the current system.
358  *
359  * We assert here that a descriptor for a file was opened with write
360  * permissions (either O_RDWR or O_WRONLY) and for a directory without
361  * write permissions (O_RDONLY).
362  *
363  * Ignore any fstat errors and let the follow-up fsync() do its work.
364  * Doing this sanity check here counts for the case where fsync() is
365  * disabled.
366  */
367  if (fstat(fd, &st) == 0)
368  {
369  int desc_flags = fcntl(fd, F_GETFL);
370 
371  /*
372  * O_RDONLY is historically 0, so just make sure that for directories
373  * no write flags are used.
374  */
375  if (S_ISDIR(st.st_mode))
376  Assert((desc_flags & (O_RDWR | O_WRONLY)) == 0);
377  else
378  Assert((desc_flags & (O_RDWR | O_WRONLY)) != 0);
379  }
380  errno = 0;
381 #endif
382 
383  /* #if is to skip the sync_method test if there's no need for it */
384 #if defined(HAVE_FSYNC_WRITETHROUGH) && !defined(FSYNC_WRITETHROUGH_IS_FSYNC)
386  return pg_fsync_writethrough(fd);
387  else
388 #endif
390 }
#define SYNC_METHOD_FSYNC_WRITETHROUGH
Definition: xlog.h:28
int pg_fsync_writethrough(int fd)
Definition: fd.c:410
int pg_fsync_no_writethrough(int fd)
Definition: fd.c:398
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define stat(a, b)
Definition: win32_port.h:255
#define Assert(condition)
Definition: c.h:738
int sync_method
Definition: xlog.c:105
#define S_ISDIR(m)
Definition: win32_port.h:296

◆ pg_fsync_no_writethrough()

int pg_fsync_no_writethrough ( int  fd)

Definition at line 398 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync(), and pg_fsync().

399 {
400  if (enableFsync)
401  return fsync(fd);
402  else
403  return 0;
404 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define fsync(fd)
Definition: win32_port.h:62
bool enableFsync
Definition: globals.c:119

◆ pg_fsync_writethrough()

int pg_fsync_writethrough ( int  fd)

Definition at line 410 of file fd.c.

References enableFsync.

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

411 {
412  if (enableFsync)
413  {
414 #ifdef WIN32
415  return _commit(fd);
416 #elif defined(F_FULLFSYNC)
417  return (fcntl(fd, F_FULLFSYNC, 0) == -1) ? -1 : 0;
418 #else
419  errno = ENOSYS;
420  return -1;
421 #endif
422  }
423  else
424  return 0;
425 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
bool enableFsync
Definition: globals.c:119

◆ ReadDir()

◆ ReadDirExtended()

struct dirent* ReadDirExtended ( DIR dir,
const char *  dirname,
int  elevel 
)

Definition at line 2662 of file fd.c.

References ereport, errcode_for_file_access(), errmsg(), and readdir().

Referenced by DeleteAllExportedSnapshotFiles(), ReadDir(), RelationCacheInitFileRemove(), RelationCacheInitFileRemoveInDir(), RemovePgTempFiles(), RemovePgTempFilesInDir(), RemovePgTempRelationFiles(), RemovePgTempRelationFilesInDbspace(), ReorderBufferCleanupSerializedTXNs(), scan_directory_ci(), and walkdir().

2663 {
2664  struct dirent *dent;
2665 
2666  /* Give a generic message for AllocateDir failure, if caller didn't */
2667  if (dir == NULL)
2668  {
2669  ereport(elevel,
2671  errmsg("could not open directory \"%s\": %m",
2672  dirname)));
2673  return NULL;
2674  }
2675 
2676  errno = 0;
2677  if ((dent = readdir(dir)) != NULL)
2678  return dent;
2679 
2680  if (errno)
2681  ereport(elevel,
2683  errmsg("could not read directory \"%s\": %m",
2684  dirname)));
2685  return NULL;
2686 }
Definition: dirent.h:9
int errcode_for_file_access(void)
Definition: elog.c:633
static int elevel
Definition: vacuumlazy.c:323
#define ereport(elevel,...)
Definition: elog.h:144
struct dirent * readdir(DIR *)
Definition: dirent.c:77
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ RegisterTemporaryFile()

static void RegisterTemporaryFile ( File  file)
static

Definition at line 1406 of file fd.c.

References Assert, CurrentResourceOwner, FD_CLOSE_AT_EOXACT, vfd::fdstate, FileIsNotOpen, FileIsValid, have_xact_temporary_files, LruDelete(), ResourceOwnerRememberFile(), and vfd::resowner.

Referenced by OpenTemporaryFile(), PathNameCreateTemporaryFile(), and PathNameOpenTemporaryFile().

1407 {
1410 
1411  /* Backup mechanism for closing at end of xact. */
1414 }
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
static Vfd * VfdCache
Definition: fd.c:205
static bool have_xact_temporary_files
Definition: fd.c:217
void ResourceOwnerRememberFile(ResourceOwner owner, File file)
Definition: resowner.c:1268
unsigned short fdstate
Definition: fd.c:188
ResourceOwner resowner
Definition: fd.c:189
#define FD_CLOSE_AT_EOXACT
Definition: fd.c:182

◆ ReleaseExternalFD()

◆ ReleaseLruFile()

static bool ReleaseLruFile ( void  )
static

Definition at line 1241 of file fd.c.

References Assert, DO_DB, elog, LOG, LruDelete(), vfd::lruMoreRecently, and nfile.

Referenced by AllocateDir(), AllocateFile(), BasicOpenFilePerm(), OpenPipeStream(), and ReleaseLruFiles().

1242 {
1243  DO_DB(elog(LOG, "ReleaseLruFile. Opened %d", nfile));
1244 
1245  if (nfile > 0)
1246  {
1247  /*
1248  * There are opened files and so there should be at least one used vfd
1249  * in the ring.
1250  */
1251  Assert(VfdCache[0].lruMoreRecently != 0);
1252  LruDelete(VfdCache[0].lruMoreRecently);
1253  return true; /* freed a file */
1254  }
1255  return false; /* no files available to free */
1256 }
#define DO_DB(A)
Definition: fd.c:169
static Vfd * VfdCache
Definition: fd.c:205
#define LOG
Definition: elog.h:26
static void LruDelete(File file)
Definition: fd.c:1146
static int nfile
Definition: fd.c:211
#define Assert(condition)
Definition: c.h:738
#define elog(elevel,...)
Definition: elog.h:214

◆ ReleaseLruFiles()

static void ReleaseLruFiles ( void  )
static

Definition at line 1263 of file fd.c.

References max_safe_fds, nfile, numAllocatedDescs, numExternalFDs, and ReleaseLruFile().

Referenced by AllocateDir(), AllocateFile(), LruInsert(), OpenPipeStream(), OpenTransientFilePerm(), PathNameOpenFilePerm(), and ReserveExternalFD().

1264 {
1266  {
1267  if (!ReleaseLruFile())
1268  break;
1269  }
1270 }
static int numExternalFDs
Definition: fd.c:258
int max_safe_fds
Definition: fd.c:154
static bool ReleaseLruFile(void)
Definition: fd.c:1241
static int nfile
Definition: fd.c:211
static int numAllocatedDescs
Definition: fd.c:251

◆ RemovePgTempFiles()

void RemovePgTempFiles ( void  )

Definition at line 2998 of file fd.c.

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

Referenced by PostmasterMain().

2999 {
3000  char temp_path[MAXPGPATH + 10 + sizeof(TABLESPACE_VERSION_DIRECTORY) + sizeof(PG_TEMP_FILES_DIR)];
3001  DIR *spc_dir;
3002  struct dirent *spc_de;
3003 
3004  /*
3005  * First process temp files in pg_default ($PGDATA/base)
3006  */
3007  snprintf(temp_path, sizeof(temp_path), "base/%s", PG_TEMP_FILES_DIR);
3008  RemovePgTempFilesInDir(temp_path, true, false);
3009  RemovePgTempRelationFiles("base");
3010 
3011  /*
3012  * Cycle through temp directories for all non-default tablespaces.
3013  */
3014  spc_dir = AllocateDir("pg_tblspc");
3015 
3016  while ((spc_de = ReadDirExtended(spc_dir, "pg_tblspc", LOG)) != NULL)
3017  {
3018  if (strcmp(spc_de->d_name, ".") == 0 ||
3019  strcmp(spc_de->d_name, "..") == 0)
3020  continue;
3021 
3022  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s/%s",
3024  RemovePgTempFilesInDir(temp_path, true, false);
3025 
3026  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s",
3028  RemovePgTempRelationFiles(temp_path);
3029  }
3030 
3031  FreeDir(spc_dir);
3032 
3033  /*
3034  * In EXEC_BACKEND case there is a pgsql_tmp directory at the top level of
3035  * DataDir as well. However, that is *not* cleaned here because doing so
3036  * would create a race condition. It's done separately, earlier in
3037  * postmaster startup.
3038  */
3039 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2662
#define PG_TEMP_FILES_DIR
Definition: pg_checksums.c:58
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
static void RemovePgTempRelationFiles(const char *tsdirname)
Definition: fd.c:3123
Definition: dirent.c:25
#define MAXPGPATH
#define TABLESPACE_VERSION_DIRECTORY
Definition: relpath.h:26
void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok, bool unlink_all)
Definition: fd.c:3057
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2581
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:193
int FreeDir(DIR *dir)
Definition: fd.c:2699

◆ RemovePgTempFilesInDir()

void RemovePgTempFilesInDir ( const char *  tmpdirname,
bool  missing_ok,
bool  unlink_all 
)

Definition at line 3057 of file fd.c.

References AllocateDir(), dirent::d_name, ereport, errcode_for_file_access(), errmsg(), FreeDir(), LOG, lstat, MAXPGPATH, PG_TEMP_FILE_PREFIX, ReadDirExtended(), RemovePgTempFilesInDir(), S_ISDIR, snprintf, and stat.

Referenced by PostmasterMain(), RemovePgTempFiles(), and RemovePgTempFilesInDir().

3058 {
3059  DIR *temp_dir;
3060  struct dirent *temp_de;
3061  char rm_path[MAXPGPATH * 2];
3062 
3063  temp_dir = AllocateDir(tmpdirname);
3064 
3065  if (temp_dir == NULL && errno == ENOENT && missing_ok)
3066  return;
3067 
3068  while ((temp_de = ReadDirExtended(temp_dir, tmpdirname, LOG)) != NULL)
3069  {
3070  if (strcmp(temp_de->d_name, ".") == 0 ||
3071  strcmp(temp_de->d_name, "..") == 0)
3072  continue;
3073 
3074  snprintf(rm_path, sizeof(rm_path), "%s/%s",
3075  tmpdirname, temp_de->d_name);
3076 
3077  if (unlink_all ||
3078  strncmp(temp_de->d_name,
3080  strlen(PG_TEMP_FILE_PREFIX)) == 0)
3081  {
3082  struct stat statbuf;
3083 
3084  if (lstat(rm_path, &statbuf) < 0)
3085  {
3086  ereport(LOG,
3088  errmsg("could not stat file \"%s\": %m", rm_path)));
3089  continue;
3090  }
3091 
3092  if (S_ISDIR(statbuf.st_mode))
3093  {
3094  /* recursively remove contents, then directory itself */
3095  RemovePgTempFilesInDir(rm_path, false, true);
3096 
3097  if (rmdir(rm_path) < 0)
3098  ereport(LOG,
3100  errmsg("could not remove directory \"%s\": %m",
3101  rm_path)));
3102  }
3103  else
3104  {
3105  if (unlink(rm_path) < 0)
3106  ereport(LOG,
3108  errmsg("could not remove file \"%s\": %m",
3109  rm_path)));
3110  }
3111  }
3112  else
3113  ereport(LOG,
3114  (errmsg("unexpected file found in temporary-files directory: \"%s\"",
3115  rm_path)));
3116  }
3117 
3118  FreeDir(temp_dir);
3119 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2662
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
Definition: dirent.c:25
#define PG_TEMP_FILE_PREFIX
Definition: pg_checksums.c:59
#define MAXPGPATH
void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok, bool unlink_all)
Definition: fd.c:3057
int errcode_for_file_access(void)
Definition: elog.c:633
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2581
#define stat(a, b)
Definition: win32_port.h:255
#define ereport(elevel,...)
Definition: elog.h:144
#define S_ISDIR(m)
Definition: win32_port.h:296
#define lstat(path, sb)
Definition: win32_port.h:244
int errmsg(const char *fmt,...)
Definition: elog.c:824
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:193
int FreeDir(DIR *dir)
Definition: fd.c:2699

◆ RemovePgTempRelationFiles()

static void RemovePgTempRelationFiles ( const char *  tsdirname)
static

Definition at line 3123 of file fd.c.

References AllocateDir(), dirent::d_name, FreeDir(), LOG, MAXPGPATH, ReadDirExtended(), RemovePgTempRelationFilesInDbspace(), and snprintf.

Referenced by RemovePgTempFiles().

3124 {
3125  DIR *ts_dir;
3126  struct dirent *de;
3127  char dbspace_path[MAXPGPATH * 2];
3128 
3129  ts_dir = AllocateDir(tsdirname);
3130 
3131  while ((de = ReadDirExtended(ts_dir, tsdirname, LOG)) != NULL)
3132  {
3133  /*
3134  * We're only interested in the per-database directories, which have
3135  * numeric names. Note that this code will also (properly) ignore "."
3136  * and "..".
3137  */
3138  if (strspn(de->d_name, "0123456789") != strlen(de->d_name))
3139  continue;
3140 
3141  snprintf(dbspace_path, sizeof(dbspace_path), "%s/%s",
3142  tsdirname, de->d_name);
3143  RemovePgTempRelationFilesInDbspace(dbspace_path);
3144  }
3145 
3146  FreeDir(ts_dir);
3147 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2662
static void RemovePgTempRelationFilesInDbspace(const char *dbspacedirname)
Definition: fd.c:3151
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2581
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:193
int FreeDir(DIR *dir)
Definition: fd.c:2699

◆ RemovePgTempRelationFilesInDbspace()

static void RemovePgTempRelationFilesInDbspace ( const char *  dbspacedirname)
static

Definition at line 3151 of file fd.c.

References AllocateDir(), dirent::d_name, ereport, errcode_for_file_access(), errmsg(), FreeDir(), LOG, looks_like_temp_rel_name(), MAXPGPATH, ReadDirExtended(), and snprintf.

Referenced by RemovePgTempRelationFiles().

3152 {
3153  DIR *dbspace_dir;
3154  struct dirent *de;
3155  char rm_path[MAXPGPATH * 2];
3156 
3157  dbspace_dir = AllocateDir(dbspacedirname);
3158 
3159  while ((de = ReadDirExtended(dbspace_dir, dbspacedirname, LOG)) != NULL)
3160  {
3161  if (!looks_like_temp_rel_name(de->d_name))
3162  continue;
3163 
3164  snprintf(rm_path, sizeof(rm_path), "%s/%s",
3165  dbspacedirname, de->d_name);
3166 
3167  if (unlink(rm_path) < 0)
3168  ereport(LOG,
3170  errmsg("could not remove file \"%s\": %m",
3171  rm_path)));
3172  }
3173 
3174  FreeDir(dbspace_dir);
3175 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2662
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
int errcode_for_file_access(void)
Definition: elog.c:633
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2581
#define ereport(elevel,...)
Definition: elog.h:144
bool looks_like_temp_rel_name(const char *name)
Definition: fd.c:3179
int errmsg(const char *fmt,...)
Definition: elog.c:824
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:193
int FreeDir(DIR *dir)
Definition: fd.c:2699

◆ ReportTemporaryFileUsage()

static void ReportTemporaryFileUsage ( const char *  path,
off_t  size 
)
static

Definition at line 1387 of file fd.c.

References ereport, errmsg(), LOG, log_temp_files, and pgstat_report_tempfile().

Referenced by FileClose(), and PathNameDeleteTemporaryFile().

1388 {
1389  pgstat_report_tempfile(size);
1390 
1391  if (log_temp_files >= 0)
1392  {
1393  if ((size / 1024) >= log_temp_files)
1394  ereport(LOG,
1395  (errmsg("temporary file: path \"%s\", size %lu",
1396  path, (unsigned long) size)));
1397  }
1398 }
int log_temp_files
Definition: guc.c:549
void pgstat_report_tempfile(size_t filesize)
Definition: pgstat.c:1613
#define LOG
Definition: elog.h:26
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ reserveAllocatedDesc()

static bool reserveAllocatedDesc ( void  )
static

Definition at line 2245 of file fd.c.

References ereport, errcode(), errmsg(), ERROR, FD_MINFREE, malloc, max_safe_fds, maxAllocatedDescs, numAllocatedDescs, and realloc.

Referenced by AllocateDir(), AllocateFile(), OpenPipeStream(), and OpenTransientFilePerm().

2246 {
2247  AllocateDesc *newDescs;
2248  int newMax;
2249 
2250  /* Quick out if array already has a free slot. */
2252  return true;
2253 
2254  /*
2255  * If the array hasn't yet been created in the current process, initialize
2256  * it with FD_MINFREE / 3 elements. In many scenarios this is as many as
2257  * we will ever need, anyway. We don't want to look at max_safe_fds
2258  * immediately because set_max_safe_fds() may not have run yet.
2259  */
2260  if (allocatedDescs == NULL)
2261  {
2262  newMax = FD_MINFREE / 3;
2263  newDescs = (AllocateDesc *) malloc(newMax * sizeof(AllocateDesc));
2264  /* Out of memory already? Treat as fatal error. */
2265  if (newDescs == NULL)
2266  ereport(ERROR,
2267  (errcode(ERRCODE_OUT_OF_MEMORY),
2268  errmsg("out of memory")));
2269  allocatedDescs = newDescs;
2270  maxAllocatedDescs = newMax;
2271  return true;
2272  }
2273 
2274  /*
2275  * Consider enlarging the array beyond the initial allocation used above.
2276  * By the time this happens, max_safe_fds should be known accurately.
2277  *
2278  * We mustn't let allocated descriptors hog all the available FDs, and in
2279  * practice we'd better leave a reasonable number of FDs for VFD use. So
2280  * set the maximum to max_safe_fds / 3. (This should certainly be at
2281  * least as large as the initial size, FD_MINFREE / 3, so we aren't
2282  * tightening the restriction here.) Recall that "external" FDs are
2283  * allowed to consume another third of max_safe_fds.
2284  */
2285  newMax = max_safe_fds / 3;
2286  if (newMax > maxAllocatedDescs)
2287  {
2288  newDescs = (AllocateDesc *) realloc(allocatedDescs,
2289  newMax * sizeof(AllocateDesc));
2290  /* Treat out-of-memory as a non-fatal error. */
2291  if (newDescs == NULL)
2292  return false;
2293  allocatedDescs = newDescs;
2294  maxAllocatedDescs = newMax;
2295  return true;
2296  }
2297 
2298  /* Can't enlarge allocatedDescs[] any more. */
2299  return false;
2300 }
static AllocateDesc * allocatedDescs
Definition: fd.c:253
int max_safe_fds
Definition: fd.c:154
int errcode(int sqlerrcode)
Definition: elog.c:610
#define malloc(a)
Definition: header.h:50
#define ERROR
Definition: elog.h:43
#define ereport(elevel,...)
Definition: elog.h:144
#define FD_MINFREE
Definition: fd.c:133
#define realloc(a, b)
Definition: header.h:60
int errmsg(const char *fmt,...)
Definition: elog.c:824
static int maxAllocatedDescs
Definition: fd.c:252
static int numAllocatedDescs
Definition: fd.c:251

◆ ReserveExternalFD()

void ReserveExternalFD ( void  )

Definition at line 1080 of file fd.c.

References numExternalFDs, and ReleaseLruFiles().

Referenced by AcquireExternalFD(), BackendInitialize(), dsm_impl_op(), InitializeLatchSupport(), InitPostmasterDeathWatchHandle(), pgstat_init(), PostmasterMarkPIDForWorkerNotify(), and XLogWrite().

1081 {
1082  /*
1083  * Release VFDs if needed to stay safe. Because we do this before
1084  * incrementing numExternalFDs, the final state will be as desired, i.e.,
1085  * nfile + numAllocatedDescs + numExternalFDs <= max_safe_fds.
1086  */
1087  ReleaseLruFiles();
1088 
1089  numExternalFDs++;
1090 }
static int numExternalFDs
Definition: fd.c:258
static void ReleaseLruFiles(void)
Definition: fd.c:1263

◆ set_max_safe_fds()

void set_max_safe_fds ( void  )

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

941 {
942  int usable_fds;
943  int already_open;
944 
945  /*----------
946  * We want to set max_safe_fds to
947  * MIN(usable_fds, max_files_per_process - already_open)
948  * less the slop factor for files that are opened without consulting
949  * fd.c. This ensures that we won't exceed either max_files_per_process
950  * or the experimentally-determined EMFILE limit.
951  *----------
952  */
954  &usable_fds, &already_open);
955 
956  max_safe_fds = Min(usable_fds, max_files_per_process - already_open);
957 
958  /*
959  * Take off the FDs reserved for system() etc.
960  */
962 
963  /*
964  * Make sure we still have enough to get by.
965  */
966  if (max_safe_fds < FD_MINFREE)
967  ereport(FATAL,
968  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
969  errmsg("insufficient file descriptors available to start server process"),
970  errdetail("System allows %d, we need at least %d.",
973 
974  elog(DEBUG2, "max_safe_fds = %d, usable_fds = %d, already_open = %d",
975  max_safe_fds, usable_fds, already_open);
976 }
static void count_usable_fds(int max_to_probe, int *usable_fds, int *already_open)
Definition: fd.c:856
#define NUM_RESERVED_FDS
Definition: fd.c:124
int max_safe_fds
Definition: fd.c:154
#define Min(x, y)
Definition: c.h:920
int errcode(int sqlerrcode)
Definition: elog.c:610
#define FATAL
Definition: elog.h:52
#define DEBUG2
Definition: elog.h:24
int errdetail(const char *fmt,...)
Definition: elog.c:957
int max_files_per_process
Definition: fd.c:141
#define ereport(elevel,...)
Definition: elog.h:144
#define FD_MINFREE
Definition: fd.c:133
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214

◆ SetTempTablespaces()

void SetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 2784 of file fd.c.

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

Referenced by assign_temp_tablespaces(), and PrepareTempTablespaces().

2785 {
2786  Assert(numSpaces >= 0);
2787  tempTableSpaces = tableSpaces;
2788  numTempTableSpaces = numSpaces;
2789 
2790  /*
2791  * Select a random starting point in the list. This is to minimize
2792  * conflicts between backends that are most likely sharing the same list
2793  * of temp tablespaces. Note that if we create multiple temp files in the
2794  * same transaction, we'll advance circularly through the list --- this
2795  * ensures that large temporary sort files are nicely spread across all
2796  * available tablespaces.
2797  */
2798  if (numSpaces > 1)
2799  nextTempTableSpace = random() % numSpaces;
2800  else
2801  nextTempTableSpace = 0;
2802 }
long random(void)
Definition: random.c:22
static int numTempTableSpaces
Definition: fd.c:271
static int nextTempTableSpace
Definition: fd.c:272
#define Assert(condition)
Definition: c.h:738
static Oid * tempTableSpaces
Definition: fd.c:270

◆ SyncDataDirectory()

void SyncDataDirectory ( void  )

Definition at line 3249 of file fd.c.

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

Referenced by StartupXLOG().

3250 {
3251  bool xlog_is_symlink;
3252 
3253  /* We can skip this whole thing if fsync is disabled. */
3254  if (!enableFsync)
3255  return;
3256 
3257  /*
3258  * If pg_wal is a symlink, we'll need to recurse into it separately,
3259  * because the first walkdir below will ignore it.
3260  */
3261  xlog_is_symlink = false;
3262 
3263 #ifndef WIN32
3264  {
3265  struct stat st;
3266 
3267  if (lstat("pg_wal", &st) < 0)
3268  ereport(LOG,
3270  errmsg("could not stat file \"%s\": %m",
3271  "pg_wal")));
3272  else if (S_ISLNK(st.st_mode))
3273  xlog_is_symlink = true;
3274  }
3275 #else
3276  if (pgwin32_is_junction("pg_wal"))
3277  xlog_is_symlink = true;
3278 #endif
3279 
3280  /*
3281  * If possible, hint to the kernel that we're soon going to fsync the data
3282  * directory and its contents. Errors in this step are even less
3283  * interesting than normal, so log them only at DEBUG1.
3284  */
3285 #ifdef PG_FLUSH_DATA_WORKS
3286  walkdir(".", pre_sync_fname, false, DEBUG1);
3287  if (xlog_is_symlink)
3288  walkdir("pg_wal", pre_sync_fname, false, DEBUG1);
3289  walkdir("pg_tblspc", pre_sync_fname, true, DEBUG1);
3290 #endif
3291 
3292  /*
3293  * Now we do the fsync()s in the same order.
3294  *
3295  * The main call ignores symlinks, so in addition to specially processing
3296  * pg_wal if it's a symlink, pg_tblspc has to be visited separately with
3297  * process_symlinks = true. Note that if there are any plain directories
3298  * in pg_tblspc, they'll get fsync'd twice. That's not an expected case
3299  * so we don't worry about optimizing it.
3300  */
3301  walkdir(".", datadir_fsync_fname, false, LOG);
3302  if (xlog_is_symlink)
3303  walkdir("pg_wal", datadir_fsync_fname, false, LOG);
3304  walkdir("pg_tblspc", datadir_fsync_fname, true, LOG);
3305 }
#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:3323
#define LOG
Definition: elog.h:26
int errcode_for_file_access(void)
Definition: elog.c:633
static void datadir_fsync_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3423
#define stat(a, b)
Definition: win32_port.h:255
#define ereport(elevel,...)
Definition: elog.h:144
#define lstat(path, sb)
Definition: win32_port.h:244
bool enableFsync
Definition: globals.c:119
int errmsg(const char *fmt,...)
Definition: elog.c:824
bool pgwin32_is_junction(const char *path)

◆ TempTablespacePath()

void TempTablespacePath ( char *  path,
Oid  tablespace 
)

Definition at line 1628 of file fd.c.

References InvalidOid, MAXPGPATH, PG_TEMP_FILES_DIR, snprintf, and TABLESPACE_VERSION_DIRECTORY.

Referenced by OpenTemporaryFileInTablespace(), pg_ls_tmpdir(), SharedFileSetCreate(), and SharedFileSetPath().

1629 {
1630  /*
1631  * Identify the tempfile directory for this tablespace.
1632  *
1633  * If someone tries to specify pg_global, use pg_default instead.
1634  */
1635  if (tablespace == InvalidOid ||
1636  tablespace == DEFAULTTABLESPACE_OID ||
1637  tablespace == GLOBALTABLESPACE_OID)
1638  snprintf(path, MAXPGPATH, "base/%s", PG_TEMP_FILES_DIR);
1639  else
1640  {
1641  /* All other tablespaces are accessed via symlinks */
1642  snprintf(path, MAXPGPATH, "pg_tblspc/%u/%s/%s",
1645  }
1646 }
#define PG_TEMP_FILES_DIR
Definition: pg_checksums.c:58
#define MAXPGPATH
#define TABLESPACE_VERSION_DIRECTORY
Definition: relpath.h:26
char * tablespace
Definition: pgbench.c:188
#define InvalidOid
Definition: postgres_ext.h:36
#define snprintf
Definition: port.h:193

◆ TempTablespacesAreSet()

bool TempTablespacesAreSet ( void  )

Definition at line 2812 of file fd.c.

References numTempTableSpaces.

Referenced by GetTempTablespaces(), and PrepareTempTablespaces().

2813 {
2814  return (numTempTableSpaces >= 0);
2815 }
static int numTempTableSpaces
Definition: fd.c:271

◆ unlink_if_exists_fname()

static void unlink_if_exists_fname ( const char *  fname,
bool  isdir,
int  elevel 
)
static

Definition at line 3433 of file fd.c.

References ereport, errcode_for_file_access(), errmsg(), and PathNameDeleteTemporaryFile().

Referenced by PathNameDeleteTemporaryDir().

3434 {
3435  if (isdir)
3436  {
3437  if (rmdir(fname) != 0 && errno != ENOENT)
3438  ereport(elevel,
3440  errmsg("could not remove directory \"%s\": %m", fname)));
3441  }
3442  else
3443  {
3444  /* Use PathNameDeleteTemporaryFile to report filesize */
3445  PathNameDeleteTemporaryFile(fname, false);
3446  }
3447 }
bool PathNameDeleteTemporaryFile(const char *path, bool error_on_failure)
Definition: fd.c:1778
int errcode_for_file_access(void)
Definition: elog.c:633
static int elevel
Definition: vacuumlazy.c:323
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ walkdir()

static void walkdir ( const char *  path,
void(*)(const char *fname, bool isdir, int elevel action,
bool  process_symlinks,
int  elevel 
)
static

Definition at line 3323 of file fd.c.

References generate_unaccent_rules::action, AllocateDir(), CHECK_FOR_INTERRUPTS, CloseTransientFile(), dirent::d_name, elevel, ereport, errcode_for_file_access(), errmsg(), vfd::fd, FreeDir(), lstat, MAXPGPATH, OpenTransientFile(), PG_BINARY, pg_flush_data(), ReadDirExtended(), S_ISDIR, S_ISREG, snprintf, stat, and subpath().

Referenced by PathNameDeleteTemporaryDir(), and SyncDataDirectory().

3327 {
3328  DIR *dir;
3329  struct dirent *de;
3330 
3331  dir = AllocateDir(path);
3332 
3333  while ((de = ReadDirExtended(dir, path, elevel)) != NULL)
3334  {
3335  char subpath[MAXPGPATH * 2];
3336  struct stat fst;
3337  int sret;
3338 
3340 
3341  if (strcmp(de->d_name, ".") == 0 ||
3342  strcmp(de->d_name, "..") == 0)
3343  continue;
3344 
3345  snprintf(subpath, sizeof(subpath), "%s/%s", path, de->d_name);
3346 
3347  if (process_symlinks)
3348  sret = stat(subpath, &fst);
3349  else
3350  sret = lstat(subpath, &fst);
3351 
3352  if (sret < 0)
3353  {
3354  ereport(elevel,
3356  errmsg("could not stat file \"%s\": %m", subpath)));
3357  continue;
3358  }
3359 
3360  if (S_ISREG(fst.st_mode))
3361  (*action) (subpath, false, elevel);
3362  else if (S_ISDIR(fst.st_mode))
3363  walkdir(subpath, action, false, elevel);
3364  }
3365 
3366  FreeDir(dir); /* we ignore any error here */
3367 
3368  /*
3369  * It's important to fsync the destination directory itself as individual
3370  * file fsyncs don't guarantee that the directory entry for the file is
3371  * synced. However, skip this if AllocateDir failed; the action function
3372  * might not be robust against that.
3373  */
3374  if (dir)
3375  (*action) (path, true, elevel);
3376 }
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
Definition: fd.c:3323
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2662
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
int errcode_for_file_access(void)
Definition: elog.c:633
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2581
#define S_ISREG(m)
Definition: win32_port.h:299
#define stat(a, b)
Definition: win32_port.h:255
static int elevel
Definition: vacuumlazy.c:323
#define ereport(elevel,...)
Definition: elog.h:144
#define S_ISDIR(m)
Definition: win32_port.h:296
#define lstat(path, sb)
Definition: win32_port.h:244
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:193
int FreeDir(DIR *dir)
Definition: fd.c:2699
Datum subpath(PG_FUNCTION_ARGS)
Definition: ltree_op.c:241

Variable Documentation

◆ allocatedDescs

AllocateDesc* allocatedDescs = NULL
static

Definition at line 253 of file fd.c.

◆ data_sync_retry

bool data_sync_retry = false

Definition at line 157 of file fd.c.

Referenced by data_sync_elevel().

◆ have_xact_temporary_files

bool have_xact_temporary_files = false
static

Definition at line 217 of file fd.c.

Referenced by CleanupTempFiles(), and RegisterTemporaryFile().

◆ max_files_per_process

int max_files_per_process = 1000

Definition at line 141 of file fd.c.

Referenced by set_max_safe_fds().

◆ max_safe_fds

◆ maxAllocatedDescs

int maxAllocatedDescs = 0
static

◆ nextTempTableSpace

int nextTempTableSpace = 0
static

Definition at line 272 of file fd.c.

Referenced by GetNextTempTableSpace(), and SetTempTablespaces().

◆ nfile

int nfile = 0
static

◆ numAllocatedDescs

◆ numExternalFDs

int numExternalFDs = 0
static

Definition at line 258 of file fd.c.

Referenced by AcquireExternalFD(), ReleaseExternalFD(), ReleaseLruFiles(), and ReserveExternalFD().

◆ numTempTableSpaces

int numTempTableSpaces = -1
static

◆ SizeVfdCache

Size SizeVfdCache = 0
static

Definition at line 206 of file fd.c.

Referenced by AllocateVfd(), CleanupTempFiles(), closeAllVfds(), and InitFileAccess().

◆ tempFileCounter

long tempFileCounter = 0
static

Definition at line 264 of file fd.c.

Referenced by OpenTemporaryFileInTablespace().

◆ temporary_files_size

uint64 temporary_files_size = 0
static

Definition at line 225 of file fd.c.

Referenced by FileClose(), FileTruncate(), and FileWrite().

◆ tempTableSpaces

Oid* tempTableSpaces = NULL
static

◆ VfdCache

Vfd* VfdCache
static

Definition at line 205 of file fd.c.