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 1047 of file fd.c.

References max_safe_fds, numExternalFDs, and ReserveExternalFD().

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

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

◆ AllocateDir()

DIR* AllocateDir ( const char *  dirname)

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

2584 {
2585  DIR *dir;
2586 
2587  DO_DB(elog(LOG, "AllocateDir: Allocated %d (%s)",
2588  numAllocatedDescs, dirname));
2589 
2590  /* Can we allocate another non-virtual FD? */
2591  if (!reserveAllocatedDesc())
2592  ereport(ERROR,
2593  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2594  errmsg("exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"",
2595  maxAllocatedDescs, dirname)));
2596 
2597  /* Close excess kernel FDs. */
2598  ReleaseLruFiles();
2599 
2600 TryAgain:
2601  if ((dir = opendir(dirname)) != NULL)
2602  {
2604 
2605  desc->kind = AllocateDescDir;
2606  desc->desc.dir = dir;
2609  return desc->desc.dir;
2610  }
2611 
2612  if (errno == EMFILE || errno == ENFILE)
2613  {
2614  int save_errno = errno;
2615 
2616  ereport(LOG,
2617  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2618  errmsg("out of file descriptors: %m; release and retry")));
2619  errno = 0;
2620  if (ReleaseLruFile())
2621  goto TryAgain;
2622  errno = save_errno;
2623  }
2624 
2625  return NULL;
2626 }
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:2247
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:241
static bool ReleaseLruFile(void)
Definition: fd.c:1243
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:1265
#define ereport(elevel,...)
Definition: elog.h:144
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:708
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 2322 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(), 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(), tokenize_inc_file(), tsearch_readline_begin(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

2323 {
2324  FILE *file;
2325 
2326  DO_DB(elog(LOG, "AllocateFile: Allocated %d (%s)",
2328 
2329  /* Can we allocate another non-virtual FD? */
2330  if (!reserveAllocatedDesc())
2331  ereport(ERROR,
2332  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2333  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2334  maxAllocatedDescs, name)));
2335 
2336  /* Close excess kernel FDs. */
2337  ReleaseLruFiles();
2338 
2339 TryAgain:
2340  if ((file = fopen(name, mode)) != NULL)
2341  {
2343 
2344  desc->kind = AllocateDescFile;
2345  desc->desc.file = file;
2348  return desc->desc.file;
2349  }
2350 
2351  if (errno == EMFILE || errno == ENFILE)
2352  {
2353  int save_errno = errno;
2354 
2355  ereport(LOG,
2356  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2357  errmsg("out of file descriptors: %m; release and retry")));
2358  errno = 0;
2359  if (ReleaseLruFile())
2360  goto TryAgain;
2361  errno = save_errno;
2362  }
2363 
2364  return NULL;
2365 }
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:2247
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:241
static bool ReleaseLruFile(void)
Definition: fd.c:1243
#define ERROR
Definition: elog.h:43
static void ReleaseLruFiles(void)
Definition: fd.c:1265
FILE * file
Definition: fd.c:245
#define ereport(elevel,...)
Definition: elog.h:144
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:708
SubTransactionId create_subid
Definition: fd.c:242
const char * name
Definition: encode.c:561
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 1275 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().

1276 {
1277  Index i;
1278  File file;
1279 
1280  DO_DB(elog(LOG, "AllocateVfd. Size %zu", SizeVfdCache));
1281 
1282  Assert(SizeVfdCache > 0); /* InitFileAccess not called? */
1283 
1284  if (VfdCache[0].nextFree == 0)
1285  {
1286  /*
1287  * The free list is empty so it is time to increase the size of the
1288  * array. We choose to double it each time this happens. However,
1289  * there's not much point in starting *real* small.
1290  */
1291  Size newCacheSize = SizeVfdCache * 2;
1292  Vfd *newVfdCache;
1293 
1294  if (newCacheSize < 32)
1295  newCacheSize = 32;
1296 
1297  /*
1298  * Be careful not to clobber VfdCache ptr if realloc fails.
1299  */
1300  newVfdCache = (Vfd *) realloc(VfdCache, sizeof(Vfd) * newCacheSize);
1301  if (newVfdCache == NULL)
1302  ereport(ERROR,
1303  (errcode(ERRCODE_OUT_OF_MEMORY),
1304  errmsg("out of memory")));
1305  VfdCache = newVfdCache;
1306 
1307  /*
1308  * Initialize the new entries and link them into the free list.
1309  */
1310  for (i = SizeVfdCache; i < newCacheSize; i++)
1311  {
1312  MemSet((char *) &(VfdCache[i]), 0, sizeof(Vfd));
1313  VfdCache[i].nextFree = i + 1;
1314  VfdCache[i].fd = VFD_CLOSED;
1315  }
1316  VfdCache[newCacheSize - 1].nextFree = 0;
1318 
1319  /*
1320  * Record the new size
1321  */
1322  SizeVfdCache = newCacheSize;
1323  }
1324 
1325  file = VfdCache[0].nextFree;
1326 
1327  VfdCache[0].nextFree = VfdCache[file].nextFree;
1328 
1329  return file;
1330 }
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 2871 of file fd.c.

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

2873 {
2874  Index i;
2875 
2876  for (i = 0; i < numAllocatedDescs; i++)
2877  {
2878  if (allocatedDescs[i].create_subid == mySubid)
2879  {
2880  if (isCommit)
2881  allocatedDescs[i].create_subid = parentSubid;
2882  else
2883  {
2884  /* have to recheck the item after FreeDesc (ugly) */
2885  FreeDesc(&allocatedDescs[i--]);
2886  }
2887  }
2888  }
2889 }
static AllocateDesc * allocatedDescs
Definition: fd.c:253
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2482
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 2904 of file fd.c.

References CleanupTempFiles(), numTempTableSpaces, and tempTableSpaces.

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

2905 {
2906  CleanupTempFiles(isCommit, false);
2907  tempTableSpaces = NULL;
2908  numTempTableSpaces = -1;
2909 }
static int numTempTableSpaces
Definition: fd.c:273
static Oid * tempTableSpaces
Definition: fd.c:272
static void CleanupTempFiles(bool isCommit, bool isProcExit)
Definition: fd.c:2936

◆ AtProcExit_Files()

static void AtProcExit_Files ( int  code,
Datum  arg 
)
static

Definition at line 2918 of file fd.c.

References CleanupTempFiles().

Referenced by InitFileAccess().

2919 {
2920  CleanupTempFiles(false, true);
2921 }
static void CleanupTempFiles(bool isCommit, bool isProcExit)
Definition: fd.c:2936

◆ BasicOpenFile()

int BasicOpenFile ( const char *  fileName,
int  fileFlags 
)

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

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

◆ BasicOpenFilePerm()

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

Definition at line 1007 of file fd.c.

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

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

1008 {
1009  int fd;
1010 
1011 tryAgain:
1012  fd = open(fileName, fileFlags, fileMode);
1013 
1014  if (fd >= 0)
1015  return fd; /* success! */
1016 
1017  if (errno == EMFILE || errno == ENFILE)
1018  {
1019  int save_errno = errno;
1020 
1021  ereport(LOG,
1022  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
1023  errmsg("out of file descriptors: %m; release and retry")));
1024  errno = 0;
1025  if (ReleaseLruFile())
1026  goto tryAgain;
1027  errno = save_errno;
1028  }
1029 
1030  return -1; /* failure */
1031 }
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:1243
#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 2936 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().

2937 {
2938  Index i;
2939 
2940  /*
2941  * Careful here: at proc_exit we need extra cleanup, not just
2942  * xact_temporary files.
2943  */
2944  if (isProcExit || have_xact_temporary_files)
2945  {
2946  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2947  for (i = 1; i < SizeVfdCache; i++)
2948  {
2949  unsigned short fdstate = VfdCache[i].fdstate;
2950 
2951  if (((fdstate & FD_DELETE_AT_CLOSE) || (fdstate & FD_CLOSE_AT_EOXACT)) &&
2952  VfdCache[i].fileName != NULL)
2953  {
2954  /*
2955  * If we're in the process of exiting a backend process, close
2956  * all temporary files. Otherwise, only close temporary files
2957  * local to the current transaction. They should be closed by
2958  * the ResourceOwner mechanism already, so this is just a
2959  * debugging cross-check.
2960  */
2961  if (isProcExit)
2962  FileClose(i);
2963  else if (fdstate & FD_CLOSE_AT_EOXACT)
2964  {
2965  elog(WARNING,
2966  "temporary file %s not closed at end-of-transaction",
2967  VfdCache[i].fileName);
2968  FileClose(i);
2969  }
2970  }
2971  }
2972 
2973  have_xact_temporary_files = false;
2974  }
2975 
2976  /* Complain if any allocated files remain open at commit. */
2977  if (isCommit && numAllocatedDescs > 0)
2978  elog(WARNING, "%d temporary files and directories not closed at end-of-transaction",
2980 
2981  /* Clean up "allocated" stdio files, dirs and fds. */
2982  while (numAllocatedDescs > 0)
2983  FreeDesc(&allocatedDescs[0]);
2984 }
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:2482
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:1826
#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 2760 of file fd.c.

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

Referenced by standard_ProcessUtility().

2761 {
2762  Index i;
2763 
2764  if (SizeVfdCache > 0)
2765  {
2766  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2767  for (i = 1; i < SizeVfdCache; i++)
2768  {
2769  if (!FileIsNotOpen(i))
2770  LruDelete(i);
2771  }
2772  }
2773 }
static Size SizeVfdCache
Definition: fd.c:206
static void LruDelete(File file)
Definition: fd.c:1148
#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 2731 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().

2732 {
2733  int i;
2734 
2735  DO_DB(elog(LOG, "ClosePipeStream: Allocated %d", numAllocatedDescs));
2736 
2737  /* Remove file from list of allocated files, if it's present */
2738  for (i = numAllocatedDescs; --i >= 0;)
2739  {
2740  AllocateDesc *desc = &allocatedDescs[i];
2741 
2742  if (desc->kind == AllocateDescPipe && desc->desc.file == file)
2743  return FreeDesc(desc);
2744  }
2745 
2746  /* Only get here if someone passes us a file not in allocatedDescs */
2747  elog(WARNING, "file passed to ClosePipeStream was not obtained from OpenPipeStream");
2748 
2749  return pclose(file);
2750 }
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:2482
#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 2549 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(), perform_base_backup(), qtext_load_file(), qtext_store(), ReadTwoPhaseFile(), RecreateTwoPhaseFile(), ReorderBufferSerializeChange(), ReorderBufferSerializeTXN(), RestoreSlotFromDisk(), SaveSlotToPath(), sendFile(), SendTimeLineHistory(), SimpleLruDoesPhysicalPageExist(), SimpleLruFlush(), SlruInternalWritePage(), SlruPhysicalReadPage(), SlruPhysicalWritePage(), SnapBuildRestore(), SnapBuildSerialize(), StartupReplicationOrigin(), walkdir(), write_relmap_file(), writeTimeLineHistory(), writeTimeLineHistoryFile(), and XLogFileCopy().

2550 {
2551  int i;
2552 
2553  DO_DB(elog(LOG, "CloseTransientFile: Allocated %d", numAllocatedDescs));
2554 
2555  /* Remove fd from list of allocated files, if it's present */
2556  for (i = numAllocatedDescs; --i >= 0;)
2557  {
2558  AllocateDesc *desc = &allocatedDescs[i];
2559 
2560  if (desc->kind == AllocateDescRawFD && desc->desc.fd == fd)
2561  return FreeDesc(desc);
2562  }
2563 
2564  /* Only get here if someone passes us a file not in allocatedDescs */
2565  elog(WARNING, "fd passed to CloseTransientFile was not obtained from OpenTransientFile");
2566 
2567  return close(fd);
2568 }
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:2482
#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 858 of file fd.c.

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

Referenced by set_max_safe_fds().

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

References fsync_fname_ext().

Referenced by SyncDataDirectory().

3432 {
3433  /*
3434  * We want to silently ignoring errors about unreadable files. Pass that
3435  * desire on to fsync_fname_ext().
3436  */
3437  fsync_fname_ext(fname, isdir, true, elevel);
3438 }
static int elevel
Definition: vacuumlazy.c:330
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3466

◆ Delete()

static void Delete ( File  file)
static

Definition at line 1129 of file fd.c.

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

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

1130 {
1131  Vfd *vfdP;
1132 
1133  Assert(file != 0);
1134 
1135  DO_DB(elog(LOG, "Delete %d (%s)",
1136  file, VfdCache[file].fileName));
1137  DO_DB(_dump_lru());
1138 
1139  vfdP = &VfdCache[file];
1140 
1143 
1144  DO_DB(_dump_lru());
1145 }
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 658 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().

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

◆ durable_rename_excl()

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

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

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

◆ durable_unlink()

int durable_unlink ( const char *  fname,
int  elevel 
)

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

749 {
750  if (unlink(fname) < 0)
751  {
752  ereport(elevel,
754  errmsg("could not remove file \"%s\": %m",
755  fname)));
756  return -1;
757  }
758 
759  /*
760  * To guarantee that the removal of the file is persistent, fsync its
761  * parent directory.
762  */
763  if (fsync_parent_path(fname, elevel) != 0)
764  return -1;
765 
766  return 0;
767 }
int errcode_for_file_access(void)
Definition: elog.c:633
static int elevel
Definition: vacuumlazy.c:330
#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:3542

◆ FileAccess()

static int FileAccess ( File  file)
static

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

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

◆ FileClose()

void FileClose ( File  file)

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

1827 {
1828  Vfd *vfdP;
1829 
1830  Assert(FileIsValid(file));
1831 
1832  DO_DB(elog(LOG, "FileClose: %d (%s)",
1833  file, VfdCache[file].fileName));
1834 
1835  vfdP = &VfdCache[file];
1836 
1837  if (!FileIsNotOpen(file))
1838  {
1839  /* close the file */
1840  if (close(vfdP->fd) != 0)
1841  {
1842  /*
1843  * We may need to panic on failure to close non-temporary files;
1844  * see LruDelete.
1845  */
1847  "could not close file \"%s\": %m", vfdP->fileName);
1848  }
1849 
1850  --nfile;
1851  vfdP->fd = VFD_CLOSED;
1852 
1853  /* remove the file from the lru ring */
1854  Delete(file);
1855  }
1856 
1857  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
1858  {
1859  /* Subtract its size from current usage (do first in case of error) */
1860  temporary_files_size -= vfdP->fileSize;
1861  vfdP->fileSize = 0;
1862  }
1863 
1864  /*
1865  * Delete the file if it was temporary, and make a log entry if wanted
1866  */
1867  if (vfdP->fdstate & FD_DELETE_AT_CLOSE)
1868  {
1869  struct stat filestats;
1870  int stat_errno;
1871 
1872  /*
1873  * If we get an error, as could happen within the ereport/elog calls,
1874  * we'll come right back here during transaction abort. Reset the
1875  * flag to ensure that we can't get into an infinite loop. This code
1876  * is arranged to ensure that the worst-case consequence is failing to
1877  * emit log message(s), not failing to attempt the unlink.
1878  */
1879  vfdP->fdstate &= ~FD_DELETE_AT_CLOSE;
1880 
1881 
1882  /* first try the stat() */
1883  if (stat(vfdP->fileName, &filestats))
1884  stat_errno = errno;
1885  else
1886  stat_errno = 0;
1887 
1888  /* in any case do the unlink */
1889  if (unlink(vfdP->fileName))
1890  elog(LOG, "could not unlink file \"%s\": %m", vfdP->fileName);
1891 
1892  /* and last report the stat results */
1893  if (stat_errno == 0)
1894  ReportTemporaryFileUsage(vfdP->fileName, filestats.st_size);
1895  else
1896  {
1897  errno = stat_errno;
1898  elog(LOG, "could not stat file \"%s\": %m", vfdP->fileName);
1899  }
1900  }
1901 
1902  /* Unregister it from the resource owner */
1903  if (vfdP->resowner)
1904  ResourceOwnerForgetFile(vfdP->resowner, file);
1905 
1906  /*
1907  * Return the Vfd slot to the free list
1908  */
1909  FreeVfd(file);
1910 }
#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:1129
#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:1389
#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:3605
#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:1333
#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 2216 of file fd.c.

References Assert, vfd::fd, and FileIsValid.

2217 {
2218  Assert(FileIsValid(file));
2219  return VfdCache[file].fd;
2220 }
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 2226 of file fd.c.

References Assert, vfd::fileFlags, and FileIsValid.

2227 {
2228  Assert(FileIsValid(file));
2229  return VfdCache[file].fileFlags;
2230 }
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 2236 of file fd.c.

References Assert, FileIsValid, and vfd::fileMode.

2237 {
2238  Assert(FileIsValid(file));
2239  return VfdCache[file].fileMode;
2240 }
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 2200 of file fd.c.

References Assert, FileIsValid, and vfd::fileName.

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

2201 {
2202  Assert(FileIsValid(file));
2203 
2204  return VfdCache[file].fileName;
2205 }
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 1922 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().

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

1975 {
1976  int returnCode;
1977  Vfd *vfdP;
1978 
1979  Assert(FileIsValid(file));
1980 
1981  DO_DB(elog(LOG, "FileRead: %d (%s) " INT64_FORMAT " %d %p",
1982  file, VfdCache[file].fileName,
1983  (int64) offset,
1984  amount, buffer));
1985 
1986  returnCode = FileAccess(file);
1987  if (returnCode < 0)
1988  return returnCode;
1989 
1990  vfdP = &VfdCache[file];
1991 
1992 retry:
1993  pgstat_report_wait_start(wait_event_info);
1994  returnCode = pg_pread(vfdP->fd, buffer, amount, offset);
1996 
1997  if (returnCode < 0)
1998  {
1999  /*
2000  * Windows may run out of kernel buffers and return "Insufficient
2001  * system resources" error. Wait a bit and retry to solve it.
2002  *
2003  * It is rumored that EINTR is also possible on some Unix filesystems,
2004  * in which case immediate retry is indicated.
2005  */
2006 #ifdef WIN32
2007  DWORD error = GetLastError();
2008 
2009  switch (error)
2010  {
2011  case ERROR_NO_SYSTEM_RESOURCES:
2012  pg_usleep(1000L);
2013  errno = EINTR;
2014  break;
2015  default:
2016  _dosmaperr(error);
2017  break;
2018  }
2019 #endif
2020  /* OK to retry if interrupted */
2021  if (errno == EINTR)
2022  goto retry;
2023  }
2024 
2025  return returnCode;
2026 }
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:1381
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:1353
#define Assert(condition)
Definition: c.h:738
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1357
#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 2148 of file fd.c.

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

Referenced by _mdnblocks(), and BufFileSize().

2149 {
2150  Assert(FileIsValid(file));
2151 
2152  DO_DB(elog(LOG, "FileSize %d (%s)",
2153  file, VfdCache[file].fileName));
2154 
2155  if (FileIsNotOpen(file))
2156  {
2157  if (FileAccess(file) < 0)
2158  return (off_t) -1;
2159  }
2160 
2161  return lseek(VfdCache[file].fd, 0, SEEK_END);
2162 }
#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:1353
#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 2127 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().

2128 {
2129  int returnCode;
2130 
2131  Assert(FileIsValid(file));
2132 
2133  DO_DB(elog(LOG, "FileSync: %d (%s)",
2134  file, VfdCache[file].fileName));
2135 
2136  returnCode = FileAccess(file);
2137  if (returnCode < 0)
2138  return returnCode;
2139 
2140  pgstat_report_wait_start(wait_event_info);
2141  returnCode = pg_fsync(VfdCache[file].fd);
2143 
2144  return returnCode;
2145 }
#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:1381
#define FileIsValid(file)
Definition: fd.c:175
static int FileAccess(File file)
Definition: fd.c:1353
#define Assert(condition)
Definition: c.h:738
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1357
#define elog(elevel,...)
Definition: elog.h:214
int pg_fsync(int fd)
Definition: fd.c:345

◆ FileTruncate()

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

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

2166 {
2167  int returnCode;
2168 
2169  Assert(FileIsValid(file));
2170 
2171  DO_DB(elog(LOG, "FileTruncate %d (%s)",
2172  file, VfdCache[file].fileName));
2173 
2174  returnCode = FileAccess(file);
2175  if (returnCode < 0)
2176  return returnCode;
2177 
2178  pgstat_report_wait_start(wait_event_info);
2179  returnCode = ftruncate(VfdCache[file].fd, offset);
2181 
2182  if (returnCode == 0 && VfdCache[file].fileSize > offset)
2183  {
2184  /* adjust our state for truncation of a temp file */
2185  Assert(VfdCache[file].fdstate & FD_TEMP_FILE_LIMIT);
2186  temporary_files_size -= VfdCache[file].fileSize - offset;
2187  VfdCache[file].fileSize = offset;
2188  }
2189 
2190  return returnCode;
2191 }
#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:1381
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:1353
#define Assert(condition)
Definition: c.h:738
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1357
#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 2029 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().

2031 {
2032  int returnCode;
2033  Vfd *vfdP;
2034 
2035  Assert(FileIsValid(file));
2036 
2037  DO_DB(elog(LOG, "FileWrite: %d (%s) " INT64_FORMAT " %d %p",
2038  file, VfdCache[file].fileName,
2039  (int64) offset,
2040  amount, buffer));
2041 
2042  returnCode = FileAccess(file);
2043  if (returnCode < 0)
2044  return returnCode;
2045 
2046  vfdP = &VfdCache[file];
2047 
2048  /*
2049  * If enforcing temp_file_limit and it's a temp file, check to see if the
2050  * write would overrun temp_file_limit, and throw error if so. Note: it's
2051  * really a modularity violation to throw error here; we should set errno
2052  * and return -1. However, there's no way to report a suitable error
2053  * message if we do that. All current callers would just throw error
2054  * immediately anyway, so this is safe at present.
2055  */
2056  if (temp_file_limit >= 0 && (vfdP->fdstate & FD_TEMP_FILE_LIMIT))
2057  {
2058  off_t past_write = offset + amount;
2059 
2060  if (past_write > vfdP->fileSize)
2061  {
2062  uint64 newTotal = temporary_files_size;
2063 
2064  newTotal += past_write - vfdP->fileSize;
2065  if (newTotal > (uint64) temp_file_limit * (uint64) 1024)
2066  ereport(ERROR,
2067  (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
2068  errmsg("temporary file size exceeds temp_file_limit (%dkB)",
2069  temp_file_limit)));
2070  }
2071  }
2072 
2073 retry:
2074  errno = 0;
2075  pgstat_report_wait_start(wait_event_info);
2076  returnCode = pg_pwrite(VfdCache[file].fd, buffer, amount, offset);
2078 
2079  /* if write didn't set errno, assume problem is no disk space */
2080  if (returnCode != amount && errno == 0)
2081  errno = ENOSPC;
2082 
2083  if (returnCode >= 0)
2084  {
2085  /*
2086  * Maintain fileSize and temporary_files_size if it's a temp file.
2087  */
2088  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
2089  {
2090  off_t past_write = offset + amount;
2091 
2092  if (past_write > vfdP->fileSize)
2093  {
2094  temporary_files_size += past_write - vfdP->fileSize;
2095  vfdP->fileSize = past_write;
2096  }
2097  }
2098  }
2099  else
2100  {
2101  /*
2102  * See comments in FileRead()
2103  */
2104 #ifdef WIN32
2105  DWORD error = GetLastError();
2106 
2107  switch (error)
2108  {
2109  case ERROR_NO_SYSTEM_RESOURCES:
2110  pg_usleep(1000L);
2111  errno = EINTR;
2112  break;
2113  default:
2114  _dosmaperr(error);
2115  break;
2116  }
2117 #endif
2118  /* OK to retry if interrupted */
2119  if (errno == EINTR)
2120  goto retry;
2121  }
2122 
2123  return returnCode;
2124 }
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:1381
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:1353
#define Assert(condition)
Definition: c.h:738
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1357
#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:547

◆ FileWriteback()

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

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

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

◆ FreeDesc()

static int FreeDesc ( AllocateDesc desc)
static

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

2483 {
2484  int result;
2485 
2486  /* Close the underlying object */
2487  switch (desc->kind)
2488  {
2489  case AllocateDescFile:
2490  result = fclose(desc->desc.file);
2491  break;
2492  case AllocateDescPipe:
2493  result = pclose(desc->desc.file);
2494  break;
2495  case AllocateDescDir:
2496  result = closedir(desc->desc.dir);
2497  break;
2498  case AllocateDescRawFD:
2499  result = close(desc->desc.fd);
2500  break;
2501  default:
2502  elog(ERROR, "AllocateDesc kind not recognized");
2503  result = 0; /* keep compiler quiet */
2504  break;
2505  }
2506 
2507  /* Compact storage in the allocatedDescs array */
2510 
2511  return result;
2512 }
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 2701 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().

2702 {
2703  int i;
2704 
2705  /* Nothing to do if AllocateDir failed */
2706  if (dir == NULL)
2707  return 0;
2708 
2709  DO_DB(elog(LOG, "FreeDir: Allocated %d", numAllocatedDescs));
2710 
2711  /* Remove dir from list of allocated dirs, if it's present */
2712  for (i = numAllocatedDescs; --i >= 0;)
2713  {
2714  AllocateDesc *desc = &allocatedDescs[i];
2715 
2716  if (desc->kind == AllocateDescDir && desc->desc.dir == dir)
2717  return FreeDesc(desc);
2718  }
2719 
2720  /* Only get here if someone passes us a dir not in allocatedDescs */
2721  elog(WARNING, "dir passed to FreeDir was not obtained from AllocateDir");
2722 
2723  return closedir(dir);
2724 }
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:2482
#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 2521 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(), 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(), tokenize_inc_file(), tsearch_readline_end(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

2522 {
2523  int i;
2524 
2525  DO_DB(elog(LOG, "FreeFile: Allocated %d", numAllocatedDescs));
2526 
2527  /* Remove file from list of allocated files, if it's present */
2528  for (i = numAllocatedDescs; --i >= 0;)
2529  {
2530  AllocateDesc *desc = &allocatedDescs[i];
2531 
2532  if (desc->kind == AllocateDescFile && desc->desc.file == file)
2533  return FreeDesc(desc);
2534  }
2535 
2536  /* Only get here if someone passes us a file not in allocatedDescs */
2537  elog(WARNING, "file passed to FreeFile was not obtained from AllocateFile");
2538 
2539  return fclose(file);
2540 }
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:2482
#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 1333 of file fd.c.

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

Referenced by FileClose(), and PathNameOpenFilePerm().

1334 {
1335  Vfd *vfdP = &VfdCache[file];
1336 
1337  DO_DB(elog(LOG, "FreeVfd: %d (%s)",
1338  file, vfdP->fileName ? vfdP->fileName : ""));
1339 
1340  if (vfdP->fileName != NULL)
1341  {
1342  free(vfdP->fileName);
1343  vfdP->fileName = NULL;
1344  }
1345  vfdP->fdstate = 0x0;
1346 
1347  vfdP->nextFree = VfdCache[0].nextFree;
1348  VfdCache[0].nextFree = file;
1349 }
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 3466 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().

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

◆ fsync_parent_path()

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

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

3543 {
3544  char parentpath[MAXPGPATH];
3545 
3546  strlcpy(parentpath, fname, MAXPGPATH);
3547  get_parent_directory(parentpath);
3548 
3549  /*
3550  * get_parent_directory() returns an empty string if the input argument is
3551  * just a file name (see comments in path.c), so handle that as being the
3552  * current directory.
3553  */
3554  if (strlen(parentpath) == 0)
3555  strlcpy(parentpath, ".", MAXPGPATH);
3556 
3557  if (fsync_fname_ext(parentpath, true, false, elevel) != 0)
3558  return -1;
3559 
3560  return 0;
3561 }
#define MAXPGPATH
void get_parent_directory(char *path)
Definition: path.c:854
static int elevel
Definition: vacuumlazy.c:330
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:3466

◆ GetNextTempTableSpace()

Oid GetNextTempTableSpace ( void  )

Definition at line 2850 of file fd.c.

References InvalidOid, nextTempTableSpace, numTempTableSpaces, and tempTableSpaces.

Referenced by GetDefaultTablespace(), and OpenTemporaryFile().

2851 {
2852  if (numTempTableSpaces > 0)
2853  {
2854  /* Advance nextTempTableSpace counter with wraparound */
2856  nextTempTableSpace = 0;
2858  }
2859  return InvalidOid;
2860 }
static int numTempTableSpaces
Definition: fd.c:273
static int nextTempTableSpace
Definition: fd.c:274
#define InvalidOid
Definition: postgres_ext.h:36
static Oid * tempTableSpaces
Definition: fd.c:272

◆ GetTempTablespaces()

int GetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 2832 of file fd.c.

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

Referenced by SharedFileSetInit().

2833 {
2834  int i;
2835 
2837  for (i = 0; i < numTempTableSpaces && i < numSpaces; ++i)
2838  tableSpaces[i] = tempTableSpaces[i];
2839 
2840  return i;
2841 }
static int numTempTableSpaces
Definition: fd.c:273
bool TempTablespacesAreSet(void)
Definition: fd.c:2817
#define Assert(condition)
Definition: c.h:738
static Oid * tempTableSpaces
Definition: fd.c:272
int i

◆ InitFileAccess()

void InitFileAccess ( void  )

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

826 {
827  Assert(SizeVfdCache == 0); /* call me only once */
828 
829  /* initialize cache header entry */
830  VfdCache = (Vfd *) malloc(sizeof(Vfd));
831  if (VfdCache == NULL)
832  ereport(FATAL,
833  (errcode(ERRCODE_OUT_OF_MEMORY),
834  errmsg("out of memory")));
835 
836  MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));
838 
839  SizeVfdCache = 1;
840 
841  /* register proc-exit hook to ensure temp files are dropped at exit */
843 }
static void AtProcExit_Files(int code, Datum arg)
Definition: fd.c:2918
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 1174 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().

1175 {
1176  Vfd *vfdP;
1177 
1178  Assert(file != 0);
1179 
1180  DO_DB(elog(LOG, "Insert %d (%s)",
1181  file, VfdCache[file].fileName));
1182  DO_DB(_dump_lru());
1183 
1184  vfdP = &VfdCache[file];
1185 
1186  vfdP->lruMoreRecently = 0;
1188  VfdCache[0].lruLessRecently = file;
1190 
1191  DO_DB(_dump_lru());
1192 }
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 3187 of file fd.c.

References forkname_chars().

Referenced by RemovePgTempRelationFilesInDbspace(), and sendDir().

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

◆ LruDelete()

static void LruDelete ( File  file)
static

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

1149 {
1150  Vfd *vfdP;
1151 
1152  Assert(file != 0);
1153 
1154  DO_DB(elog(LOG, "LruDelete %d (%s)",
1155  file, VfdCache[file].fileName));
1156 
1157  vfdP = &VfdCache[file];
1158 
1159  /*
1160  * Close the file. We aren't expecting this to fail; if it does, better
1161  * to leak the FD than to mess up our internal state.
1162  */
1163  if (close(vfdP->fd) != 0)
1165  "could not close file \"%s\": %m", vfdP->fileName);
1166  vfdP->fd = VFD_CLOSED;
1167  --nfile;
1168 
1169  /* delete the vfd record from the LRU ring */
1170  Delete(file);
1171 }
#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:1129
#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:3605
#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 1196 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().

1197 {
1198  Vfd *vfdP;
1199 
1200  Assert(file != 0);
1201 
1202  DO_DB(elog(LOG, "LruInsert %d (%s)",
1203  file, VfdCache[file].fileName));
1204 
1205  vfdP = &VfdCache[file];
1206 
1207  if (FileIsNotOpen(file))
1208  {
1209  /* Close excess kernel FDs. */
1210  ReleaseLruFiles();
1211 
1212  /*
1213  * The open could still fail for lack of file descriptors, eg due to
1214  * overall system file table being full. So, be prepared to release
1215  * another FD if necessary...
1216  */
1217  vfdP->fd = BasicOpenFilePerm(vfdP->fileName, vfdP->fileFlags,
1218  vfdP->fileMode);
1219  if (vfdP->fd < 0)
1220  {
1221  DO_DB(elog(LOG, "re-open failed: %m"));
1222  return -1;
1223  }
1224  else
1225  {
1226  ++nfile;
1227  }
1228  }
1229 
1230  /*
1231  * put it at the head of the Lru ring
1232  */
1233 
1234  Insert(file);
1235 
1236  return 0;
1237 }
#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:1174
static void ReleaseLruFiles(void)
Definition: fd.c:1265
#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:1007
#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 2425 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().

2426 {
2427  FILE *file;
2428  int save_errno;
2429 
2430  DO_DB(elog(LOG, "OpenPipeStream: Allocated %d (%s)",
2431  numAllocatedDescs, command));
2432 
2433  /* Can we allocate another non-virtual FD? */
2434  if (!reserveAllocatedDesc())
2435  ereport(ERROR,
2436  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2437  errmsg("exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"",
2438  maxAllocatedDescs, command)));
2439 
2440  /* Close excess kernel FDs. */
2441  ReleaseLruFiles();
2442 
2443 TryAgain:
2444  fflush(stdout);
2445  fflush(stderr);
2447  errno = 0;
2448  file = popen(command, mode);
2449  save_errno = errno;
2451  errno = save_errno;
2452  if (file != NULL)
2453  {
2455 
2456  desc->kind = AllocateDescPipe;
2457  desc->desc.file = file;
2460  return desc->desc.file;
2461  }
2462 
2463  if (errno == EMFILE || errno == ENFILE)
2464  {
2465  ereport(LOG,
2466  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2467  errmsg("out of file descriptors: %m; release and retry")));
2468  if (ReleaseLruFile())
2469  goto TryAgain;
2470  errno = save_errno;
2471  }
2472 
2473  return NULL;
2474 }
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:2247
#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:1243
#define ERROR
Definition: elog.h:43
#define SIG_IGN
Definition: win32_port.h:150
static void ReleaseLruFiles(void)
Definition: fd.c:1265
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:708
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 1577 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().

1578 {
1579  File file = 0;
1580 
1581  /*
1582  * Make sure the current resource owner has space for this File before we
1583  * open it, if we'll be registering it below.
1584  */
1585  if (!interXact)
1587 
1588  /*
1589  * If some temp tablespace(s) have been given to us, try to use the next
1590  * one. If a given tablespace can't be found, we silently fall back to
1591  * the database's default tablespace.
1592  *
1593  * BUT: if the temp file is slated to outlive the current transaction,
1594  * force it into the database's default tablespace, so that it will not
1595  * pose a threat to possible tablespace drop attempts.
1596  */
1597  if (numTempTableSpaces > 0 && !interXact)
1598  {
1599  Oid tblspcOid = GetNextTempTableSpace();
1600 
1601  if (OidIsValid(tblspcOid))
1602  file = OpenTemporaryFileInTablespace(tblspcOid, false);
1603  }
1604 
1605  /*
1606  * If not, or if tablespace is bad, create in database's default
1607  * tablespace. MyDatabaseTableSpace should normally be set before we get
1608  * here, but just in case it isn't, fall back to pg_default tablespace.
1609  */
1610  if (file <= 0)
1613  DEFAULTTABLESPACE_OID,
1614  true);
1615 
1616  /* Mark it for deletion at close and temporary file size limit */
1618 
1619  /* Register it with the current resource owner */
1620  if (!interXact)
1621  RegisterTemporaryFile(file);
1622 
1623  return file;
1624 }
static File OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError)
Definition: fd.c:1655
#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:273
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:2850
unsigned short fdstate
Definition: fd.c:188
static void RegisterTemporaryFile(File file)
Definition: fd.c:1408
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 1655 of file fd.c.

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

Referenced by OpenTemporaryFile().

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

2382 {
2383  int fd;
2384 
2385  DO_DB(elog(LOG, "OpenTransientFile: Allocated %d (%s)",
2386  numAllocatedDescs, fileName));
2387 
2388  /* Can we allocate another non-virtual FD? */
2389  if (!reserveAllocatedDesc())
2390  ereport(ERROR,
2391  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2392  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2393  maxAllocatedDescs, fileName)));
2394 
2395  /* Close excess kernel FDs. */
2396  ReleaseLruFiles();
2397 
2398  fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
2399 
2400  if (fd >= 0)
2401  {
2403 
2404  desc->kind = AllocateDescRawFD;
2405  desc->desc.fd = fd;
2408 
2409  return fd;
2410  }
2411 
2412  return -1; /* failure */
2413 }
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:2247
#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:1265
#define ereport(elevel,...)
Definition: elog.h:144
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:708
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:1007
#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 1513 of file fd.c.

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

Referenced by SharedFileSetCreate().

1514 {
1515  if (MakePGDirectory(directory) < 0)
1516  {
1517  if (errno == EEXIST)
1518  return;
1519 
1520  /*
1521  * Failed. Try to create basedir first in case it's missing. Tolerate
1522  * EEXIST to close a race against another process following the same
1523  * algorithm.
1524  */
1525  if (MakePGDirectory(basedir) < 0 && errno != EEXIST)
1526  ereport(ERROR,
1528  errmsg("cannot create temporary directory \"%s\": %m",
1529  basedir)));
1530 
1531  /* Try again. */
1532  if (MakePGDirectory(directory) < 0 && errno != EEXIST)
1533  ereport(ERROR,
1535  errmsg("cannot create temporary subdirectory \"%s\": %m",
1536  directory)));
1537  }
1538 }
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:3582
static const char * directory
Definition: zic.c:634
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ PathNameCreateTemporaryFile()

File PathNameCreateTemporaryFile ( const char *  path,
bool  error_on_failure 
)

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

1713 {
1714  File file;
1715 
1717 
1718  /*
1719  * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1720  * temp file that can be reused.
1721  */
1722  file = PathNameOpenFile(path, O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1723  if (file <= 0)
1724  {
1725  if (error_on_failure)
1726  ereport(ERROR,
1728  errmsg("could not create temporary file \"%s\": %m",
1729  path)));
1730  else
1731  return file;
1732  }
1733 
1734  /* Mark it for temp_file_limit accounting. */
1736 
1737  /* Register it for automatic close. */
1738  RegisterTemporaryFile(file);
1739 
1740  return file;
1741 }
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1436
#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:1233
#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:1408
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 1544 of file fd.c.

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

Referenced by SharedFileSetDeleteAll().

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

◆ PathNameDeleteTemporaryFile()

bool PathNameDeleteTemporaryFile ( const char *  path,
bool  error_on_failure 
)

Definition at line 1780 of file fd.c.

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

Referenced by SharedFileSetDelete(), and unlink_if_exists_fname().

1781 {
1782  struct stat filestats;
1783  int stat_errno;
1784 
1785  /* Get the final size for pgstat reporting. */
1786  if (stat(path, &filestats) != 0)
1787  stat_errno = errno;
1788  else
1789  stat_errno = 0;
1790 
1791  /*
1792  * Unlike FileClose's automatic file deletion code, we tolerate
1793  * non-existence to support BufFileDeleteShared which doesn't know how
1794  * many segments it has to delete until it runs out.
1795  */
1796  if (stat_errno == ENOENT)
1797  return false;
1798 
1799  if (unlink(path) < 0)
1800  {
1801  if (errno != ENOENT)
1802  ereport(error_on_failure ? ERROR : LOG,
1804  errmsg("could not unlink temporary file \"%s\": %m",
1805  path)));
1806  return false;
1807  }
1808 
1809  if (stat_errno == 0)
1810  ReportTemporaryFileUsage(path, filestats.st_size);
1811  else
1812  {
1813  errno = stat_errno;
1814  ereport(LOG,
1816  errmsg("could not stat file \"%s\": %m", path)));
1817  }
1818 
1819  return true;
1820 }
#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:1389
#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 1436 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().

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

◆ PathNameOpenFilePerm()

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

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

1450 {
1451  char *fnamecopy;
1452  File file;
1453  Vfd *vfdP;
1454 
1455  DO_DB(elog(LOG, "PathNameOpenFilePerm: %s %x %o",
1456  fileName, fileFlags, fileMode));
1457 
1458  /*
1459  * We need a malloc'd copy of the file name; fail cleanly if no room.
1460  */
1461  fnamecopy = strdup(fileName);
1462  if (fnamecopy == NULL)
1463  ereport(ERROR,
1464  (errcode(ERRCODE_OUT_OF_MEMORY),
1465  errmsg("out of memory")));
1466 
1467  file = AllocateVfd();
1468  vfdP = &VfdCache[file];
1469 
1470  /* Close excess kernel FDs. */
1471  ReleaseLruFiles();
1472 
1473  vfdP->fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
1474 
1475  if (vfdP->fd < 0)
1476  {
1477  int save_errno = errno;
1478 
1479  FreeVfd(file);
1480  free(fnamecopy);
1481  errno = save_errno;
1482  return -1;
1483  }
1484  ++nfile;
1485  DO_DB(elog(LOG, "PathNameOpenFile: success %d",
1486  vfdP->fd));
1487 
1488  Insert(file);
1489 
1490  vfdP->fileName = fnamecopy;
1491  /* Saved flags are adjusted to be OK for re-opening file */
1492  vfdP->fileFlags = fileFlags & ~(O_CREAT | O_TRUNC | O_EXCL);
1493  vfdP->fileMode = fileMode;
1494  vfdP->fileSize = 0;
1495  vfdP->fdstate = 0x0;
1496  vfdP->resowner = NULL;
1497 
1498  return file;
1499 }
#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:1275
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:1174
ResourceOwner resowner
Definition: fd.c:189
static void ReleaseLruFiles(void)
Definition: fd.c:1265
#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:1007
#define elog(elevel,...)
Definition: elog.h:214
static void FreeVfd(File file)
Definition: fd.c:1333
int fileFlags
Definition: fd.c:196
int File
Definition: fd.h:49

◆ PathNameOpenTemporaryFile()

File PathNameOpenTemporaryFile ( const char *  path)

Definition at line 1750 of file fd.c.

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

Referenced by SharedFileSetOpen().

1751 {
1752  File file;
1753 
1755 
1756  /* We open the file read-only. */
1757  file = PathNameOpenFile(path, O_RDONLY | PG_BINARY);
1758 
1759  /* If no such file, then we don't raise an error. */
1760  if (file <= 0 && errno != ENOENT)
1761  ereport(ERROR,
1763  errmsg("could not open temporary file \"%s\": %m",
1764  path)));
1765 
1766  if (file > 0)
1767  {
1768  /* Register it for automatic close. */
1769  RegisterTemporaryFile(file);
1770  }
1771 
1772  return file;
1773 }
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1436
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
#define PG_BINARY
Definition: c.h:1233
#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:1408
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 435 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync().

436 {
437  if (enableFsync)
438  {
439 #ifdef HAVE_FDATASYNC
440  return fdatasync(fd);
441 #else
442  return fsync(fd);
443 #endif
444  }
445  else
446  return 0;
447 }
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 455 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().

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

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

References enableFsync, and fsync.

Referenced by issue_xlog_fsync(), and pg_fsync().

401 {
402  if (enableFsync)
403  return fsync(fd);
404  else
405  return 0;
406 }
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 412 of file fd.c.

References enableFsync.

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

413 {
414  if (enableFsync)
415  {
416 #ifdef WIN32
417  return _commit(fd);
418 #elif defined(F_FULLFSYNC)
419  return (fcntl(fd, F_FULLFSYNC, 0) == -1) ? -1 : 0;
420 #else
421  errno = ENOSYS;
422  return -1;
423 #endif
424  }
425  else
426  return 0;
427 }
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 2664 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().

2665 {
2666  struct dirent *dent;
2667 
2668  /* Give a generic message for AllocateDir failure, if caller didn't */
2669  if (dir == NULL)
2670  {
2671  ereport(elevel,
2673  errmsg("could not open directory \"%s\": %m",
2674  dirname)));
2675  return NULL;
2676  }
2677 
2678  errno = 0;
2679  if ((dent = readdir(dir)) != NULL)
2680  return dent;
2681 
2682  if (errno)
2683  ereport(elevel,
2685  errmsg("could not read directory \"%s\": %m",
2686  dirname)));
2687  return NULL;
2688 }
Definition: dirent.h:9
int errcode_for_file_access(void)
Definition: elog.c:633
static int elevel
Definition: vacuumlazy.c:330
#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 1408 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().

1409 {
1412 
1413  /* Backup mechanism for closing at end of xact. */
1416 }
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 1243 of file fd.c.

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

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

1244 {
1245  DO_DB(elog(LOG, "ReleaseLruFile. Opened %d", nfile));
1246 
1247  if (nfile > 0)
1248  {
1249  /*
1250  * There are opened files and so there should be at least one used vfd
1251  * in the ring.
1252  */
1253  Assert(VfdCache[0].lruMoreRecently != 0);
1254  LruDelete(VfdCache[0].lruMoreRecently);
1255  return true; /* freed a file */
1256  }
1257  return false; /* no files available to free */
1258 }
#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:1148
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 1265 of file fd.c.

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

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

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

◆ RemovePgTempFiles()

void RemovePgTempFiles ( void  )

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

3007 {
3008  char temp_path[MAXPGPATH + 10 + sizeof(TABLESPACE_VERSION_DIRECTORY) + sizeof(PG_TEMP_FILES_DIR)];
3009  DIR *spc_dir;
3010  struct dirent *spc_de;
3011 
3012  /*
3013  * First process temp files in pg_default ($PGDATA/base)
3014  */
3015  snprintf(temp_path, sizeof(temp_path), "base/%s", PG_TEMP_FILES_DIR);
3016  RemovePgTempFilesInDir(temp_path, true, false);
3017  RemovePgTempRelationFiles("base");
3018 
3019  /*
3020  * Cycle through temp directories for all non-default tablespaces.
3021  */
3022  spc_dir = AllocateDir("pg_tblspc");
3023 
3024  while ((spc_de = ReadDirExtended(spc_dir, "pg_tblspc", LOG)) != NULL)
3025  {
3026  if (strcmp(spc_de->d_name, ".") == 0 ||
3027  strcmp(spc_de->d_name, "..") == 0)
3028  continue;
3029 
3030  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s/%s",
3032  RemovePgTempFilesInDir(temp_path, true, false);
3033 
3034  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s",
3036  RemovePgTempRelationFiles(temp_path);
3037  }
3038 
3039  FreeDir(spc_dir);
3040 
3041  /*
3042  * In EXEC_BACKEND case there is a pgsql_tmp directory at the top level of
3043  * DataDir as well. However, that is *not* cleaned here because doing so
3044  * would create a race condition. It's done separately, earlier in
3045  * postmaster startup.
3046  */
3047 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2664
#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:3131
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:3065
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2583
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:193
int FreeDir(DIR *dir)
Definition: fd.c:2701

◆ RemovePgTempFilesInDir()

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

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

3066 {
3067  DIR *temp_dir;
3068  struct dirent *temp_de;
3069  char rm_path[MAXPGPATH * 2];
3070 
3071  temp_dir = AllocateDir(tmpdirname);
3072 
3073  if (temp_dir == NULL && errno == ENOENT && missing_ok)
3074  return;
3075 
3076  while ((temp_de = ReadDirExtended(temp_dir, tmpdirname, LOG)) != NULL)
3077  {
3078  if (strcmp(temp_de->d_name, ".") == 0 ||
3079  strcmp(temp_de->d_name, "..") == 0)
3080  continue;
3081 
3082  snprintf(rm_path, sizeof(rm_path), "%s/%s",
3083  tmpdirname, temp_de->d_name);
3084 
3085  if (unlink_all ||
3086  strncmp(temp_de->d_name,
3088  strlen(PG_TEMP_FILE_PREFIX)) == 0)
3089  {
3090  struct stat statbuf;
3091 
3092  if (lstat(rm_path, &statbuf) < 0)
3093  {
3094  ereport(LOG,
3096  errmsg("could not stat file \"%s\": %m", rm_path)));
3097  continue;
3098  }
3099 
3100  if (S_ISDIR(statbuf.st_mode))
3101  {
3102  /* recursively remove contents, then directory itself */
3103  RemovePgTempFilesInDir(rm_path, false, true);
3104 
3105  if (rmdir(rm_path) < 0)
3106  ereport(LOG,
3108  errmsg("could not remove directory \"%s\": %m",
3109  rm_path)));
3110  }
3111  else
3112  {
3113  if (unlink(rm_path) < 0)
3114  ereport(LOG,
3116  errmsg("could not remove file \"%s\": %m",
3117  rm_path)));
3118  }
3119  }
3120  else
3121  ereport(LOG,
3122  (errmsg("unexpected file found in temporary-files directory: \"%s\"",
3123  rm_path)));
3124  }
3125 
3126  FreeDir(temp_dir);
3127 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2664
#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:3065
int errcode_for_file_access(void)
Definition: elog.c:633
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2583
#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:2701

◆ RemovePgTempRelationFiles()

static void RemovePgTempRelationFiles ( const char *  tsdirname)
static

Definition at line 3131 of file fd.c.

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

Referenced by RemovePgTempFiles().

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

◆ RemovePgTempRelationFilesInDbspace()

static void RemovePgTempRelationFilesInDbspace ( const char *  dbspacedirname)
static

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

3160 {
3161  DIR *dbspace_dir;
3162  struct dirent *de;
3163  char rm_path[MAXPGPATH * 2];
3164 
3165  dbspace_dir = AllocateDir(dbspacedirname);
3166 
3167  while ((de = ReadDirExtended(dbspace_dir, dbspacedirname, LOG)) != NULL)
3168  {
3169  if (!looks_like_temp_rel_name(de->d_name))
3170  continue;
3171 
3172  snprintf(rm_path, sizeof(rm_path), "%s/%s",
3173  dbspacedirname, de->d_name);
3174 
3175  if (unlink(rm_path) < 0)
3176  ereport(LOG,
3178  errmsg("could not remove file \"%s\": %m",
3179  rm_path)));
3180  }
3181 
3182  FreeDir(dbspace_dir);
3183 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2664
#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:2583
#define ereport(elevel,...)
Definition: elog.h:144
bool looks_like_temp_rel_name(const char *name)
Definition: fd.c:3187
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:2701

◆ ReportTemporaryFileUsage()

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

Definition at line 1389 of file fd.c.

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

Referenced by FileClose(), and PathNameDeleteTemporaryFile().

1390 {
1391  pgstat_report_tempfile(size);
1392 
1393  if (log_temp_files >= 0)
1394  {
1395  if ((size / 1024) >= log_temp_files)
1396  ereport(LOG,
1397  (errmsg("temporary file: path \"%s\", size %lu",
1398  path, (unsigned long) size)));
1399  }
1400 }
int log_temp_files
Definition: guc.c:540
void pgstat_report_tempfile(size_t filesize)
Definition: pgstat.c:1619
#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 2247 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().

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

References numExternalFDs, and ReleaseLruFiles().

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

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

◆ set_max_safe_fds()

void set_max_safe_fds ( void  )

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

943 {
944  int usable_fds;
945  int already_open;
946 
947  /*----------
948  * We want to set max_safe_fds to
949  * MIN(usable_fds, max_files_per_process - already_open)
950  * less the slop factor for files that are opened without consulting
951  * fd.c. This ensures that we won't exceed either max_files_per_process
952  * or the experimentally-determined EMFILE limit.
953  *----------
954  */
956  &usable_fds, &already_open);
957 
958  max_safe_fds = Min(usable_fds, max_files_per_process - already_open);
959 
960  /*
961  * Take off the FDs reserved for system() etc.
962  */
964 
965  /*
966  * Make sure we still have enough to get by.
967  */
968  if (max_safe_fds < FD_MINFREE)
969  ereport(FATAL,
970  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
971  errmsg("insufficient file descriptors available to start server process"),
972  errdetail("System allows %d, we need at least %d.",
975 
976  elog(DEBUG2, "max_safe_fds = %d, usable_fds = %d, already_open = %d",
977  max_safe_fds, usable_fds, already_open);
978 }
static void count_usable_fds(int max_to_probe, int *usable_fds, int *already_open)
Definition: fd.c:858
#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 2789 of file fd.c.

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

Referenced by assign_temp_tablespaces(), and PrepareTempTablespaces().

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

◆ SyncDataDirectory()

void SyncDataDirectory ( void  )

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

3258 {
3259  bool xlog_is_symlink;
3260 
3261  /* We can skip this whole thing if fsync is disabled. */
3262  if (!enableFsync)
3263  return;
3264 
3265  /*
3266  * If pg_wal is a symlink, we'll need to recurse into it separately,
3267  * because the first walkdir below will ignore it.
3268  */
3269  xlog_is_symlink = false;
3270 
3271 #ifndef WIN32
3272  {
3273  struct stat st;
3274 
3275  if (lstat("pg_wal", &st) < 0)
3276  ereport(LOG,
3278  errmsg("could not stat file \"%s\": %m",
3279  "pg_wal")));
3280  else if (S_ISLNK(st.st_mode))
3281  xlog_is_symlink = true;
3282  }
3283 #else
3284  if (pgwin32_is_junction("pg_wal"))
3285  xlog_is_symlink = true;
3286 #endif
3287 
3288  /*
3289  * If possible, hint to the kernel that we're soon going to fsync the data
3290  * directory and its contents. Errors in this step are even less
3291  * interesting than normal, so log them only at DEBUG1.
3292  */
3293 #ifdef PG_FLUSH_DATA_WORKS
3294  walkdir(".", pre_sync_fname, false, DEBUG1);
3295  if (xlog_is_symlink)
3296  walkdir("pg_wal", pre_sync_fname, false, DEBUG1);
3297  walkdir("pg_tblspc", pre_sync_fname, true, DEBUG1);
3298 #endif
3299 
3300  /*
3301  * Now we do the fsync()s in the same order.
3302  *
3303  * The main call ignores symlinks, so in addition to specially processing
3304  * pg_wal if it's a symlink, pg_tblspc has to be visited separately with
3305  * process_symlinks = true. Note that if there are any plain directories
3306  * in pg_tblspc, they'll get fsync'd twice. That's not an expected case
3307  * so we don't worry about optimizing it.
3308  */
3309  walkdir(".", datadir_fsync_fname, false, LOG);
3310  if (xlog_is_symlink)
3311  walkdir("pg_wal", datadir_fsync_fname, false, LOG);
3312  walkdir("pg_tblspc", datadir_fsync_fname, true, LOG);
3313 }
#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:3331
#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:3431
#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 1630 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().

1631 {
1632  /*
1633  * Identify the tempfile directory for this tablespace.
1634  *
1635  * If someone tries to specify pg_global, use pg_default instead.
1636  */
1637  if (tablespace == InvalidOid ||
1638  tablespace == DEFAULTTABLESPACE_OID ||
1639  tablespace == GLOBALTABLESPACE_OID)
1640  snprintf(path, MAXPGPATH, "base/%s", PG_TEMP_FILES_DIR);
1641  else
1642  {
1643  /* All other tablespaces are accessed via symlinks */
1644  snprintf(path, MAXPGPATH, "pg_tblspc/%u/%s/%s",
1647  }
1648 }
#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 2817 of file fd.c.

References numTempTableSpaces.

Referenced by GetTempTablespaces(), and PrepareTempTablespaces().

2818 {
2819  return (numTempTableSpaces >= 0);
2820 }
static int numTempTableSpaces
Definition: fd.c:273

◆ unlink_if_exists_fname()

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

Definition at line 3441 of file fd.c.

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

Referenced by PathNameDeleteTemporaryDir().

3442 {
3443  if (isdir)
3444  {
3445  if (rmdir(fname) != 0 && errno != ENOENT)
3446  ereport(elevel,
3448  errmsg("could not remove directory \"%s\": %m", fname)));
3449  }
3450  else
3451  {
3452  /* Use PathNameDeleteTemporaryFile to report filesize */
3453  PathNameDeleteTemporaryFile(fname, false);
3454  }
3455 }
bool PathNameDeleteTemporaryFile(const char *path, bool error_on_failure)
Definition: fd.c:1780
int errcode_for_file_access(void)
Definition: elog.c:633
static int elevel
Definition: vacuumlazy.c:330
#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 3331 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().

3335 {
3336  DIR *dir;
3337  struct dirent *de;
3338 
3339  dir = AllocateDir(path);
3340 
3341  while ((de = ReadDirExtended(dir, path, elevel)) != NULL)
3342  {
3343  char subpath[MAXPGPATH * 2];
3344  struct stat fst;
3345  int sret;
3346 
3348 
3349  if (strcmp(de->d_name, ".") == 0 ||
3350  strcmp(de->d_name, "..") == 0)
3351  continue;
3352 
3353  snprintf(subpath, sizeof(subpath), "%s/%s", path, de->d_name);
3354 
3355  if (process_symlinks)
3356  sret = stat(subpath, &fst);
3357  else
3358  sret = lstat(subpath, &fst);
3359 
3360  if (sret < 0)
3361  {
3362  ereport(elevel,
3364  errmsg("could not stat file \"%s\": %m", subpath)));
3365  continue;
3366  }
3367 
3368  if (S_ISREG(fst.st_mode))
3369  (*action) (subpath, false, elevel);
3370  else if (S_ISDIR(fst.st_mode))
3371  walkdir(subpath, action, false, elevel);
3372  }
3373 
3374  FreeDir(dir); /* we ignore any error here */
3375 
3376  /*
3377  * It's important to fsync the destination directory itself as individual
3378  * file fsyncs don't guarantee that the directory entry for the file is
3379  * synced. However, skip this if AllocateDir failed; the action function
3380  * might not be robust against that.
3381  */
3382  if (dir)
3383  (*action) (path, true, elevel);
3384 }
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
Definition: fd.c:3331
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2664
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:2583
#define S_ISREG(m)
Definition: win32_port.h:299
#define stat(a, b)
Definition: win32_port.h:255
static int elevel
Definition: vacuumlazy.c:330
#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:2701
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 274 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.