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 "common/file_utils.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, int mode)
 
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 183 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 182 of file fd.c.

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

◆ FD_MINFREE

#define FD_MINFREE   48

Definition at line 134 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 125 of file fd.c.

Referenced by set_max_safe_fds().

◆ VFD_CLOSED

#define VFD_CLOSED   (-1)

Definition at line 174 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 232 of file fd.c.

Function Documentation

◆ AcquireExternalFD()

bool AcquireExternalFD ( void  )

Definition at line 1048 of file fd.c.

References max_safe_fds, numExternalFDs, and ReserveExternalFD().

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

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

◆ 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:254
DIR * dir
Definition: fd.c:247
#define DO_DB(A)
Definition: fd.c:170
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:242
static bool ReleaseLruFile(void)
Definition: fd.c:1244
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:1266
#define ereport(elevel,...)
Definition: elog.h:144
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:723
SubTransactionId create_subid
Definition: fd.c:243
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:253
static int numAllocatedDescs
Definition: fd.c:252

◆ 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:254
#define DO_DB(A)
Definition: fd.c:170
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:242
static bool ReleaseLruFile(void)
Definition: fd.c:1244
#define ERROR
Definition: elog.h:43
static void ReleaseLruFiles(void)
Definition: fd.c:1266
FILE * file
Definition: fd.c:246
#define ereport(elevel,...)
Definition: elog.h:144
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:723
SubTransactionId create_subid
Definition: fd.c:243
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:253
static int numAllocatedDescs
Definition: fd.c:252

◆ AllocateVfd()

static File AllocateVfd ( void  )
static

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

1277 {
1278  Index i;
1279  File file;
1280 
1281  DO_DB(elog(LOG, "AllocateVfd. Size %zu", SizeVfdCache));
1282 
1283  Assert(SizeVfdCache > 0); /* InitFileAccess not called? */
1284 
1285  if (VfdCache[0].nextFree == 0)
1286  {
1287  /*
1288  * The free list is empty so it is time to increase the size of the
1289  * array. We choose to double it each time this happens. However,
1290  * there's not much point in starting *real* small.
1291  */
1292  Size newCacheSize = SizeVfdCache * 2;
1293  Vfd *newVfdCache;
1294 
1295  if (newCacheSize < 32)
1296  newCacheSize = 32;
1297 
1298  /*
1299  * Be careful not to clobber VfdCache ptr if realloc fails.
1300  */
1301  newVfdCache = (Vfd *) realloc(VfdCache, sizeof(Vfd) * newCacheSize);
1302  if (newVfdCache == NULL)
1303  ereport(ERROR,
1304  (errcode(ERRCODE_OUT_OF_MEMORY),
1305  errmsg("out of memory")));
1306  VfdCache = newVfdCache;
1307 
1308  /*
1309  * Initialize the new entries and link them into the free list.
1310  */
1311  for (i = SizeVfdCache; i < newCacheSize; i++)
1312  {
1313  MemSet((char *) &(VfdCache[i]), 0, sizeof(Vfd));
1314  VfdCache[i].nextFree = i + 1;
1315  VfdCache[i].fd = VFD_CLOSED;
1316  }
1317  VfdCache[newCacheSize - 1].nextFree = 0;
1319 
1320  /*
1321  * Record the new size
1322  */
1323  SizeVfdCache = newCacheSize;
1324  }
1325 
1326  file = VfdCache[0].nextFree;
1327 
1328  VfdCache[0].nextFree = VfdCache[file].nextFree;
1329 
1330  return file;
1331 }
File nextFree
Definition: fd.c:191
static Size SizeVfdCache
Definition: fd.c:207
#define DO_DB(A)
Definition: fd.c:170
static Vfd * VfdCache
Definition: fd.c:206
int errcode(int sqlerrcode)
Definition: elog.c:610
#define MemSet(start, val, len)
Definition: c.h:949
#define LOG
Definition: elog.h:26
#define ERROR
Definition: elog.h:43
Definition: fd.c:186
int fd
Definition: fd.c:188
unsigned int Index
Definition: c.h:482
#define VFD_CLOSED
Definition: fd.c:174
#define ereport(elevel,...)
Definition: elog.h:144
#define Assert(condition)
Definition: c.h:745
size_t Size
Definition: c.h:473
#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:254
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2482
unsigned int Index
Definition: c.h:482
SubTransactionId create_subid
Definition: fd.c:243
int i
static int numAllocatedDescs
Definition: fd.c:252

◆ 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:274
static Oid * tempTableSpaces
Definition: fd.c:273
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 986 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().

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

◆ BasicOpenFilePerm()

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

Definition at line 1008 of file fd.c.

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

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

1009 {
1010  int fd;
1011 
1012 tryAgain:
1013  fd = open(fileName, fileFlags, fileMode);
1014 
1015  if (fd >= 0)
1016  return fd; /* success! */
1017 
1018  if (errno == EMFILE || errno == ENFILE)
1019  {
1020  int save_errno = errno;
1021 
1022  ereport(LOG,
1023  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
1024  errmsg("out of file descriptors: %m; release and retry")));
1025  errno = 0;
1026  if (ReleaseLruFile())
1027  goto tryAgain;
1028  errno = save_errno;
1029  }
1030 
1031  return -1; /* failure */
1032 }
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:1244
#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:254
static Size SizeVfdCache
Definition: fd.c:207
#define FD_DELETE_AT_CLOSE
Definition: fd.c:182
static Vfd * VfdCache
Definition: fd.c:206
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2482
static bool have_xact_temporary_files
Definition: fd.c:218
unsigned short fdstate
Definition: fd.c:189
#define WARNING
Definition: elog.h:40
#define FileIsNotOpen(file)
Definition: fd.c:179
unsigned int Index
Definition: c.h:482
void FileClose(File file)
Definition: fd.c:1826
#define Assert(condition)
Definition: c.h:745
#define elog(elevel,...)
Definition: elog.h:214
int i
#define FD_CLOSE_AT_EOXACT
Definition: fd.c:183
static int numAllocatedDescs
Definition: fd.c:252

◆ 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:207
static void LruDelete(File file)
Definition: fd.c:1149
#define FileIsNotOpen(file)
Definition: fd.c:179
unsigned int Index
Definition: c.h:482
#define Assert(condition)
Definition: c.h:745
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:254
#define DO_DB(A)
Definition: fd.c:170
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:242
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2482
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:246
union AllocateDesc::@25 desc
#define elog(elevel,...)
Definition: elog.h:214
int i
static int numAllocatedDescs
Definition: fd.c:252

◆ 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(), SimpleLruWriteAll(), SlruInternalWritePage(), SlruPhysicalReadPage(), SlruPhysicalWritePage(), SlruSyncFileTag(), 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:254
#define DO_DB(A)
Definition: fd.c:170
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:242
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:248
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:252

◆ count_usable_fds()

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

Definition at line 859 of file fd.c.

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

Referenced by set_max_safe_fds().

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

References fsync_fname_ext().

Referenced by SyncDataDirectory().

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

◆ Delete()

static void Delete ( File  file)
static

Definition at line 1130 of file fd.c.

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

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

1131 {
1132  Vfd *vfdP;
1133 
1134  Assert(file != 0);
1135 
1136  DO_DB(elog(LOG, "Delete %d (%s)",
1137  file, VfdCache[file].fileName));
1138  DO_DB(_dump_lru());
1139 
1140  vfdP = &VfdCache[file];
1141 
1144 
1145  DO_DB(_dump_lru());
1146 }
File lruLessRecently
Definition: fd.c:193
#define DO_DB(A)
Definition: fd.c:170
static Vfd * VfdCache
Definition: fd.c:206
#define LOG
Definition: elog.h:26
Definition: fd.c:186
#define Assert(condition)
Definition: c.h:745
File lruMoreRecently
Definition: fd.c:192
#define elog(elevel,...)
Definition: elog.h:214

◆ durable_rename()

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

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

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

◆ durable_rename_excl()

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

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

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

◆ durable_unlink()

int durable_unlink ( const char *  fname,
int  elevel 
)

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

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

◆ FileAccess()

static int FileAccess ( File  file)
static

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

1355 {
1356  int returnValue;
1357 
1358  DO_DB(elog(LOG, "FileAccess %d (%s)",
1359  file, VfdCache[file].fileName));
1360 
1361  /*
1362  * Is the file open? If not, open it and put it at the head of the LRU
1363  * ring (possibly closing the least recently used file to get an FD).
1364  */
1365 
1366  if (FileIsNotOpen(file))
1367  {
1368  returnValue = LruInsert(file);
1369  if (returnValue != 0)
1370  return returnValue;
1371  }
1372  else if (VfdCache[0].lruLessRecently != file)
1373  {
1374  /*
1375  * We now know that the file is open and that it is not the last one
1376  * accessed, so we need to move it to the head of the Lru ring.
1377  */
1378 
1379  Delete(file);
1380  Insert(file);
1381  }
1382 
1383  return 0;
1384 }
#define DO_DB(A)
Definition: fd.c:170
static Vfd * VfdCache
Definition: fd.c:206
static void Delete(File file)
Definition: fd.c:1130
#define LOG
Definition: elog.h:26
static int LruInsert(File file)
Definition: fd.c:1197
static void Insert(File file)
Definition: fd.c:1175
#define FileIsNotOpen(file)
Definition: fd.c:179
#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(), BufFileTruncateShared(), 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:184
#define DO_DB(A)
Definition: fd.c:170
#define FD_DELETE_AT_CLOSE
Definition: fd.c:182
static Vfd * VfdCache
Definition: fd.c:206
static void Delete(File file)
Definition: fd.c:1130
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:195
static int nfile
Definition: fd.c:212
unsigned short fdstate
Definition: fd.c:189
Definition: fd.c:186
off_t fileSize
Definition: fd.c:194
int fd
Definition: fd.c:188
ResourceOwner resowner
Definition: fd.c:190
static void ReportTemporaryFileUsage(const char *path, off_t size)
Definition: fd.c:1390
#define stat(a, b)
Definition: win32_port.h:255
#define FileIsNotOpen(file)
Definition: fd.c:179
int data_sync_elevel(int elevel)
Definition: fd.c:3603
#define FileIsValid(file)
Definition: fd.c:176
#define VFD_CLOSED
Definition: fd.c:174
static uint64 temporary_files_size
Definition: fd.c:226
#define Assert(condition)
Definition: c.h:745
#define elog(elevel,...)
Definition: elog.h:214
static void FreeVfd(File file)
Definition: fd.c:1334
#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:206
int fd
Definition: fd.c:188
#define FileIsValid(file)
Definition: fd.c:176
#define Assert(condition)
Definition: c.h:745

◆ 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:206
#define FileIsValid(file)
Definition: fd.c:176
#define Assert(condition)
Definition: c.h:745
int fileFlags
Definition: fd.c:197

◆ 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:206
mode_t fileMode
Definition: fd.c:198
#define FileIsValid(file)
Definition: fd.c:176
#define Assert(condition)
Definition: c.h:745

◆ FilePathName()

char* FilePathName ( File  file)

Definition at line 2200 of file fd.c.

References Assert, FileIsValid, and vfd::fileName.

Referenced by _mdnblocks(), BufFileDumpBuffer(), BufFileLoadBuffer(), BufFileSeek(), BufFileSize(), BufFileTruncateShared(), 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:206
char * fileName
Definition: fd.c:195
#define FileIsValid(file)
Definition: fd.c:176
#define Assert(condition)
Definition: c.h:745

◆ 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:170
static Vfd * VfdCache
Definition: fd.c:206
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1386
#define FileIsValid(file)
Definition: fd.c:176
static int FileAccess(File file)
Definition: fd.c:1354
#define Assert(condition)
Definition: c.h:745
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1362
#define INT64_FORMAT
Definition: c.h:416
#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:170
void _dosmaperr(unsigned long)
Definition: win32error.c:171
static Vfd * VfdCache
Definition: fd.c:206
#define LOG
Definition: elog.h:26
ssize_t pg_pread(int fd, void *buf, size_t nbyte, off_t offset)
Definition: pread.c:27
void pg_usleep(long microsec)
Definition: signal.c:53
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1386
Definition: fd.c:186
int fd
Definition: fd.c:188
#define FileIsValid(file)
Definition: fd.c:176
static int FileAccess(File file)
Definition: fd.c:1354
#define Assert(condition)
Definition: c.h:745
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1362
#define INT64_FORMAT
Definition: c.h:416
#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(), BufFileSeek(), 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:170
static Vfd * VfdCache
Definition: fd.c:206
#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:179
#define FileIsValid(file)
Definition: fd.c:176
static int FileAccess(File file)
Definition: fd.c:1354
#define Assert(condition)
Definition: c.h:745
#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:170
static Vfd * VfdCache
Definition: fd.c:206
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1386
#define FileIsValid(file)
Definition: fd.c:176
static int FileAccess(File file)
Definition: fd.c:1354
#define Assert(condition)
Definition: c.h:745
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1362
#define elog(elevel,...)
Definition: elog.h:214
int pg_fsync(int fd)
Definition: fd.c:346

◆ 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 BufFileTruncateShared(), and 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:184
#define DO_DB(A)
Definition: fd.c:170
static Vfd * VfdCache
Definition: fd.c:206
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1386
off_t fileSize
Definition: fd.c:194
#define FileIsValid(file)
Definition: fd.c:176
static uint64 temporary_files_size
Definition: fd.c:226
static int FileAccess(File file)
Definition: fd.c:1354
#define Assert(condition)
Definition: c.h:745
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1362
#define elog(elevel,...)
Definition: elog.h:214
#define ftruncate(a, b)
Definition: win32_port.h:59

◆ FileWrite()

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

Definition at line 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:184
#define DO_DB(A)
Definition: fd.c:170
void _dosmaperr(unsigned long)
Definition: win32error.c:171
static Vfd * VfdCache
Definition: fd.c:206
int errcode(int sqlerrcode)
Definition: elog.c:610
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ssize_t pg_pwrite(int fd, const void *buf, size_t nbyte, off_t offset)
Definition: pwrite.c:27
void pg_usleep(long microsec)
Definition: signal.c:53
#define ERROR
Definition: elog.h:43
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1386
unsigned short fdstate
Definition: fd.c:189
Definition: fd.c:186
off_t fileSize
Definition: fd.c:194
#define FileIsValid(file)
Definition: fd.c:176
static uint64 temporary_files_size
Definition: fd.c:226
#define ereport(elevel,...)
Definition: elog.h:144
static int FileAccess(File file)
Definition: fd.c:1354
#define Assert(condition)
Definition: c.h:745
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1362
#define INT64_FORMAT
Definition: c.h:416
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:551

◆ 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:170
static Vfd * VfdCache
Definition: fd.c:206
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1386
void pg_flush_data(int fd, off_t offset, off_t nbytes)
Definition: fd.c:456
#define FileIsValid(file)
Definition: fd.c:176
static int FileAccess(File file)
Definition: fd.c:1354
#define Assert(condition)
Definition: c.h:745
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1362
#define INT64_FORMAT
Definition: c.h:416
#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:254
DIR * dir
Definition: fd.c:247
int closedir(DIR *)
Definition: dirent.c:123
AllocateDescKind kind
Definition: fd.c:242
#define ERROR
Definition: elog.h:43
FILE * file
Definition: fd.c:246
int fd
Definition: fd.c:248
union AllocateDesc::@25 desc
#define elog(elevel,...)
Definition: elog.h:214
#define close(a)
Definition: win32.h:12
static int numAllocatedDescs
Definition: fd.c:252

◆ 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:254
DIR * dir
Definition: fd.c:247
#define DO_DB(A)
Definition: fd.c:170
int closedir(DIR *)
Definition: dirent.c:123
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:242
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:252

◆ 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:254
#define DO_DB(A)
Definition: fd.c:170
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:242
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2482
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:246
union AllocateDesc::@25 desc
#define elog(elevel,...)
Definition: elog.h:214
int i
static int numAllocatedDescs
Definition: fd.c:252

◆ FreeVfd()

static void FreeVfd ( File  file)
static

Definition at line 1334 of file fd.c.

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

Referenced by FileClose(), and PathNameOpenFilePerm().

1335 {
1336  Vfd *vfdP = &VfdCache[file];
1337 
1338  DO_DB(elog(LOG, "FreeVfd: %d (%s)",
1339  file, vfdP->fileName ? vfdP->fileName : ""));
1340 
1341  if (vfdP->fileName != NULL)
1342  {
1343  free(vfdP->fileName);
1344  vfdP->fileName = NULL;
1345  }
1346  vfdP->fdstate = 0x0;
1347 
1348  vfdP->nextFree = VfdCache[0].nextFree;
1349  VfdCache[0].nextFree = file;
1350 }
File nextFree
Definition: fd.c:191
#define DO_DB(A)
Definition: fd.c:170
static Vfd * VfdCache
Definition: fd.c:206
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:195
unsigned short fdstate
Definition: fd.c:189
Definition: fd.c:186
#define free(a)
Definition: header.h:65
#define elog(elevel,...)
Definition: elog.h:214

◆ fsync_fname()

void fsync_fname ( const char *  fname,
bool  isdir 
)

Definition at line 633 of file fd.c.

References data_sync_elevel(), ERROR, and fsync_fname_ext().

Referenced by _CloseArchive(), CheckPointTwoPhase(), copydir(), CreateSlotOnDisk(), dir_close(), dir_finish(), dir_open_for_write(), main(), ReplicationSlotDropPtr(), ResetUnloggedRelationsInDbspaceDir(), RestoreSlotFromDisk(), SaveSlotToPath(), SimpleLruWriteAll(), SnapBuildRestore(), SnapBuildSerialize(), StartupReplicationSlots(), and tar_finish().

634 {
635  fsync_fname_ext(fname, isdir, false, data_sync_elevel(ERROR));
636 }
#define ERROR
Definition: elog.h:43
int data_sync_elevel(int elevel)
Definition: fd.c:3603
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3464

◆ fsync_fname_ext()

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

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

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

◆ fsync_parent_path()

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

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

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

◆ 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:274
static int nextTempTableSpace
Definition: fd.c:275
#define InvalidOid
Definition: postgres_ext.h:36
static Oid * tempTableSpaces
Definition: fd.c:273

◆ 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:274
bool TempTablespacesAreSet(void)
Definition: fd.c:2817
#define Assert(condition)
Definition: c.h:745
static Oid * tempTableSpaces
Definition: fd.c:273
int i

◆ InitFileAccess()

void InitFileAccess ( void  )

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

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

◆ Insert()

static void Insert ( File  file)
static

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

1176 {
1177  Vfd *vfdP;
1178 
1179  Assert(file != 0);
1180 
1181  DO_DB(elog(LOG, "Insert %d (%s)",
1182  file, VfdCache[file].fileName));
1183  DO_DB(_dump_lru());
1184 
1185  vfdP = &VfdCache[file];
1186 
1187  vfdP->lruMoreRecently = 0;
1189  VfdCache[0].lruLessRecently = file;
1191 
1192  DO_DB(_dump_lru());
1193 }
File lruLessRecently
Definition: fd.c:193
#define DO_DB(A)
Definition: fd.c:170
static Vfd * VfdCache
Definition: fd.c:206
#define LOG
Definition: elog.h:26
Definition: fd.c:186
#define Assert(condition)
Definition: c.h:745
File lruMoreRecently
Definition: fd.c:192
#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 1149 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().

1150 {
1151  Vfd *vfdP;
1152 
1153  Assert(file != 0);
1154 
1155  DO_DB(elog(LOG, "LruDelete %d (%s)",
1156  file, VfdCache[file].fileName));
1157 
1158  vfdP = &VfdCache[file];
1159 
1160  /*
1161  * Close the file. We aren't expecting this to fail; if it does, better
1162  * to leak the FD than to mess up our internal state.
1163  */
1164  if (close(vfdP->fd) != 0)
1166  "could not close file \"%s\": %m", vfdP->fileName);
1167  vfdP->fd = VFD_CLOSED;
1168  --nfile;
1169 
1170  /* delete the vfd record from the LRU ring */
1171  Delete(file);
1172 }
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:184
#define DO_DB(A)
Definition: fd.c:170
static Vfd * VfdCache
Definition: fd.c:206
static void Delete(File file)
Definition: fd.c:1130
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:195
static int nfile
Definition: fd.c:212
unsigned short fdstate
Definition: fd.c:189
Definition: fd.c:186
int fd
Definition: fd.c:188
int data_sync_elevel(int elevel)
Definition: fd.c:3603
#define VFD_CLOSED
Definition: fd.c:174
#define Assert(condition)
Definition: c.h:745
#define elog(elevel,...)
Definition: elog.h:214
#define close(a)
Definition: win32.h:12

◆ LruInsert()

static int LruInsert ( File  file)
static

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

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

◆ 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:254
#define DO_DB(A)
Definition: fd.c:170
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:242
static bool ReleaseLruFile(void)
Definition: fd.c:1244
#define ERROR
Definition: elog.h:43
#define SIG_IGN
Definition: win32_port.h:150
static void ReleaseLruFiles(void)
Definition: fd.c:1266
FILE * file
Definition: fd.c:246
#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:723
SubTransactionId create_subid
Definition: fd.c:243
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:253
static int numAllocatedDescs
Definition: fd.c:252

◆ OpenTemporaryFile()

File OpenTemporaryFile ( bool  interXact)

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

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

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

Referenced by OpenTemporaryFile().

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

◆ PathNameCreateTemporaryDir()

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

Definition at line 1514 of file fd.c.

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

Referenced by SharedFileSetCreate().

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

1714 {
1715  File file;
1716 
1718 
1719  /*
1720  * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1721  * temp file that can be reused.
1722  */
1723  file = PathNameOpenFile(path, O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1724  if (file <= 0)
1725  {
1726  if (error_on_failure)
1727  ereport(ERROR,
1729  errmsg("could not create temporary file \"%s\": %m",
1730  path)));
1731  else
1732  return file;
1733  }
1734 
1735  /* Mark it for temp_file_limit accounting. */
1737 
1738  /* Register it for automatic close. */
1739  RegisterTemporaryFile(file);
1740 
1741  return file;
1742 }
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1437
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:184
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
static Vfd * VfdCache
Definition: fd.c:206
#define PG_BINARY
Definition: c.h:1211
#define ERROR
Definition: elog.h:43
int errcode_for_file_access(void)
Definition: elog.c:633
unsigned short fdstate
Definition: fd.c:189
#define ereport(elevel,...)
Definition: elog.h:144
static void RegisterTemporaryFile(File file)
Definition: fd.c:1409
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 1545 of file fd.c.

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

Referenced by SharedFileSetDeleteAll().

1546 {
1547  struct stat statbuf;
1548 
1549  /* Silently ignore missing directory. */
1550  if (stat(dirname, &statbuf) != 0 && errno == ENOENT)
1551  return;
1552 
1553  /*
1554  * Currently, walkdir doesn't offer a way for our passed in function to
1555  * maintain state. Perhaps it should, so that we could tell the caller
1556  * whether this operation succeeded or failed. Since this operation is
1557  * used in a cleanup path, we wouldn't actually behave differently: we'll
1558  * just log failures.
1559  */
1560  walkdir(dirname, unlink_if_exists_fname, false, LOG);
1561 }
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:3439
#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:1390
#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 1437 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().

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

◆ PathNameOpenFilePerm()

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

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

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

◆ PathNameOpenTemporaryFile()

File PathNameOpenTemporaryFile ( const char *  path,
int  mode 
)

Definition at line 1751 of file fd.c.

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

Referenced by SharedFileSetOpen().

1752 {
1753  File file;
1754 
1756 
1757  file = PathNameOpenFile(path, mode | 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 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1437
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
#define PG_BINARY
Definition: c.h:1211
#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:1409
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 436 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync().

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

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

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

◆ pg_fsync_no_writethrough()

int pg_fsync_no_writethrough ( int  fd)

Definition at line 401 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync(), and pg_fsync().

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

References enableFsync.

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

414 {
415  if (enableFsync)
416  {
417 #ifdef WIN32
418  return _commit(fd);
419 #elif defined(F_FULLFSYNC)
420  return (fcntl(fd, F_FULLFSYNC, 0) == -1) ? -1 : 0;
421 #else
422  errno = ENOSYS;
423  return -1;
424 #endif
425  }
426  else
427  return 0;
428 }
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:333
#define ereport(elevel,...)
Definition: elog.h:144
struct dirent * readdir(DIR *)
Definition: dirent.c:78
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ RegisterTemporaryFile()

static void RegisterTemporaryFile ( File  file)
static

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

1410 {
1413 
1414  /* Backup mechanism for closing at end of xact. */
1417 }
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
static Vfd * VfdCache
Definition: fd.c:206
static bool have_xact_temporary_files
Definition: fd.c:218
void ResourceOwnerRememberFile(ResourceOwner owner, File file)
Definition: resowner.c:1268
unsigned short fdstate
Definition: fd.c:189
ResourceOwner resowner
Definition: fd.c:190
#define FD_CLOSE_AT_EOXACT
Definition: fd.c:183

◆ ReleaseExternalFD()

◆ ReleaseLruFile()

static bool ReleaseLruFile ( void  )
static

Definition at line 1244 of file fd.c.

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

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

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

◆ ReleaseLruFiles()

static void ReleaseLruFiles ( void  )
static

Definition at line 1266 of file fd.c.

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

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

1267 {
1269  {
1270  if (!ReleaseLruFile())
1271  break;
1272  }
1273 }
static int numExternalFDs
Definition: fd.c:259
int max_safe_fds
Definition: fd.c:155
static bool ReleaseLruFile(void)
Definition: fd.c:1244
static int nfile
Definition: fd.c:212
static int numAllocatedDescs
Definition: fd.c:252

◆ 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:15
#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:15
#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:15
#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:15
#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 1390 of file fd.c.

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

Referenced by FileClose(), and PathNameDeleteTemporaryFile().

1391 {
1392  pgstat_report_tempfile(size);
1393 
1394  if (log_temp_files >= 0)
1395  {
1396  if ((size / 1024) >= log_temp_files)
1397  ereport(LOG,
1398  (errmsg("temporary file: path \"%s\", size %lu",
1399  path, (unsigned long) size)));
1400  }
1401 }
int log_temp_files
Definition: guc.c:544
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:254
int max_safe_fds
Definition: fd.c:155
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:134
#define realloc(a, b)
Definition: header.h:60
int errmsg(const char *fmt,...)
Definition: elog.c:824
static int maxAllocatedDescs
Definition: fd.c:253
static int numAllocatedDescs
Definition: fd.c:252

◆ ReserveExternalFD()

void ReserveExternalFD ( void  )

Definition at line 1083 of file fd.c.

References numExternalFDs, and ReleaseLruFiles().

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

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

◆ set_max_safe_fds()

void set_max_safe_fds ( void  )

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

944 {
945  int usable_fds;
946  int already_open;
947 
948  /*----------
949  * We want to set max_safe_fds to
950  * MIN(usable_fds, max_files_per_process - already_open)
951  * less the slop factor for files that are opened without consulting
952  * fd.c. This ensures that we won't exceed either max_files_per_process
953  * or the experimentally-determined EMFILE limit.
954  *----------
955  */
957  &usable_fds, &already_open);
958 
959  max_safe_fds = Min(usable_fds, max_files_per_process - already_open);
960 
961  /*
962  * Take off the FDs reserved for system() etc.
963  */
965 
966  /*
967  * Make sure we still have enough to get by.
968  */
969  if (max_safe_fds < FD_MINFREE)
970  ereport(FATAL,
971  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
972  errmsg("insufficient file descriptors available to start server process"),
973  errdetail("System allows %d, we need at least %d.",
976 
977  elog(DEBUG2, "max_safe_fds = %d, usable_fds = %d, already_open = %d",
978  max_safe_fds, usable_fds, already_open);
979 }
static void count_usable_fds(int max_to_probe, int *usable_fds, int *already_open)
Definition: fd.c:859
#define NUM_RESERVED_FDS
Definition: fd.c:125
int max_safe_fds
Definition: fd.c:155
#define Min(x, y)
Definition: c.h:927
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:142
#define ereport(elevel,...)
Definition: elog.h:144
#define FD_MINFREE
Definition: fd.c:134
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:274
static int nextTempTableSpace
Definition: fd.c:275
#define Assert(condition)
Definition: c.h:745
static Oid * tempTableSpaces
Definition: fd.c:273

◆ 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:3429
#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 1631 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().

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

◆ unlink_if_exists_fname()

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

Definition at line 3439 of file fd.c.

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

Referenced by PathNameDeleteTemporaryDir().

3440 {
3441  if (isdir)
3442  {
3443  if (rmdir(fname) != 0 && errno != ENOENT)
3444  ereport(elevel,
3446  errmsg("could not remove directory \"%s\": %m", fname)));
3447  }
3448  else
3449  {
3450  /* Use PathNameDeleteTemporaryFile to report filesize */
3451  PathNameDeleteTemporaryFile(fname, false);
3452  }
3453 }
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:333
#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(), get_dirent_type(), MAXPGPATH, OpenTransientFile(), PG_BINARY, pg_flush_data(), PGFILETYPE_DIR, PGFILETYPE_REG, ReadDirExtended(), snprintf, 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 
3346 
3347  if (strcmp(de->d_name, ".") == 0 ||
3348  strcmp(de->d_name, "..") == 0)
3349  continue;
3350 
3351  snprintf(subpath, sizeof(subpath), "%s/%s", path, de->d_name);
3352 
3353  switch (get_dirent_type(subpath, de, process_symlinks, elevel))
3354  {
3355  case PGFILETYPE_REG:
3356  (*action) (subpath, false, elevel);
3357  break;
3358  case PGFILETYPE_DIR:
3359  walkdir(subpath, action, false, elevel);
3360  break;
3361  default:
3362 
3363  /*
3364  * Errors are already reported directly by get_dirent_type(),
3365  * and any remaining symlinks and unknown file types are
3366  * ignored.
3367  */
3368  break;
3369  }
3370  }
3371 
3372  FreeDir(dir); /* we ignore any error here */
3373 
3374  /*
3375  * It's important to fsync the destination directory itself as individual
3376  * file fsyncs don't guarantee that the directory entry for the file is
3377  * synced. However, skip this if AllocateDir failed; the action function
3378  * might not be robust against that.
3379  */
3380  if (dir)
3381  (*action) (path, true, elevel);
3382 }
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
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2583
PGFileType get_dirent_type(const char *path, const struct dirent *de, bool look_through_symlinks, int elevel)
Definition: file_utils.c:410
static int elevel
Definition: vacuumlazy.c:333
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
char d_name[MAX_PATH]
Definition: dirent.h:15
#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 254 of file fd.c.

◆ data_sync_retry

bool data_sync_retry = false

Definition at line 158 of file fd.c.

Referenced by data_sync_elevel().

◆ have_xact_temporary_files

bool have_xact_temporary_files = false
static

Definition at line 218 of file fd.c.

Referenced by CleanupTempFiles(), and RegisterTemporaryFile().

◆ max_files_per_process

int max_files_per_process = 1000

Definition at line 142 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 275 of file fd.c.

Referenced by GetNextTempTableSpace(), and SetTempTablespaces().

◆ nfile

int nfile = 0
static

◆ numAllocatedDescs

◆ numExternalFDs

int numExternalFDs = 0
static

Definition at line 259 of file fd.c.

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

◆ numTempTableSpaces

int numTempTableSpaces = -1
static

◆ SizeVfdCache

Size SizeVfdCache = 0
static

Definition at line 207 of file fd.c.

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

◆ tempFileCounter

long tempFileCounter = 0
static

Definition at line 265 of file fd.c.

Referenced by OpenTemporaryFileInTablespace().

◆ temporary_files_size

uint64 temporary_files_size = 0
static

Definition at line 226 of file fd.c.

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

◆ tempTableSpaces

Oid* tempTableSpaces = NULL
static

◆ VfdCache

Vfd* VfdCache
static

Definition at line 206 of file fd.c.