PostgreSQL Source Code  git master
fd.c File Reference
#include "postgres.h"
#include <dirent.h>
#include <sys/file.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/types.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 "port/pg_iovec.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)
 
int pg_truncate (const char *path, off_t length)
 
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)
 
ssize_t pg_pwritev_with_retry (int fd, const struct iovec *iov, int iovcnt, off_t offset)
 

Variables

int max_files_per_process = 1000
 
int max_safe_fds = FD_MINFREE
 
bool data_sync_retry = false
 
int recovery_init_sync_method = RECOVERY_INIT_SYNC_METHOD_FSYNC
 
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 189 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 188 of file fd.c.

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

◆ FD_MINFREE

#define FD_MINFREE   48

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

Referenced by set_max_safe_fds().

◆ VFD_CLOSED

#define VFD_CLOSED   (-1)

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

Function Documentation

◆ AcquireExternalFD()

bool AcquireExternalFD ( void  )

Definition at line 1139 of file fd.c.

References max_safe_fds, numExternalFDs, and ReserveExternalFD().

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

1140 {
1141  /*
1142  * We don't want more than max_safe_fds / 3 FDs to be consumed for
1143  * "external" FDs.
1144  */
1145  if (numExternalFDs < max_safe_fds / 3)
1146  {
1148  return true;
1149  }
1150  errno = EMFILE;
1151  return false;
1152 }
static int numExternalFDs
Definition: fd.c:265
int max_safe_fds
Definition: fd.c:158
void ReserveExternalFD(void)
Definition: fd.c:1174

◆ AllocateDir()

DIR* AllocateDir ( const char *  dirname)

Definition at line 2678 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(), SyncDataDirectory(), UpdateLogicalMappings(), and walkdir().

2679 {
2680  DIR *dir;
2681 
2682  DO_DB(elog(LOG, "AllocateDir: Allocated %d (%s)",
2683  numAllocatedDescs, dirname));
2684 
2685  /* Can we allocate another non-virtual FD? */
2686  if (!reserveAllocatedDesc())
2687  ereport(ERROR,
2688  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2689  errmsg("exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"",
2690  maxAllocatedDescs, dirname)));
2691 
2692  /* Close excess kernel FDs. */
2693  ReleaseLruFiles();
2694 
2695 TryAgain:
2696  if ((dir = opendir(dirname)) != NULL)
2697  {
2699 
2700  desc->kind = AllocateDescDir;
2701  desc->desc.dir = dir;
2704  return desc->desc.dir;
2705  }
2706 
2707  if (errno == EMFILE || errno == ENFILE)
2708  {
2709  int save_errno = errno;
2710 
2711  ereport(LOG,
2712  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2713  errmsg("out of file descriptors: %m; release and retry")));
2714  errno = 0;
2715  if (ReleaseLruFile())
2716  goto TryAgain;
2717  errno = save_errno;
2718  }
2719 
2720  return NULL;
2721 }
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:260
DIR * dir
Definition: fd.c:253
#define DO_DB(A)
Definition: fd.c:176
int errcode(int sqlerrcode)
Definition: elog.c:698
static bool reserveAllocatedDesc(void)
Definition: fd.c:2342
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:248
static bool ReleaseLruFile(void)
Definition: fd.c:1335
Definition: dirent.c:25
#define ERROR
Definition: elog.h:46
DIR * opendir(const char *)
Definition: dirent.c:33
static void ReleaseLruFiles(void)
Definition: fd.c:1357
#define ereport(elevel,...)
Definition: elog.h:157
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:723
SubTransactionId create_subid
Definition: fd.c:249
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
static int maxAllocatedDescs
Definition: fd.c:259
static int numAllocatedDescs
Definition: fd.c:258

◆ AllocateFile()

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

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

2418 {
2419  FILE *file;
2420 
2421  DO_DB(elog(LOG, "AllocateFile: Allocated %d (%s)",
2423 
2424  /* Can we allocate another non-virtual FD? */
2425  if (!reserveAllocatedDesc())
2426  ereport(ERROR,
2427  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2428  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2429  maxAllocatedDescs, name)));
2430 
2431  /* Close excess kernel FDs. */
2432  ReleaseLruFiles();
2433 
2434 TryAgain:
2435  if ((file = fopen(name, mode)) != NULL)
2436  {
2438 
2439  desc->kind = AllocateDescFile;
2440  desc->desc.file = file;
2443  return desc->desc.file;
2444  }
2445 
2446  if (errno == EMFILE || errno == ENFILE)
2447  {
2448  int save_errno = errno;
2449 
2450  ereport(LOG,
2451  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2452  errmsg("out of file descriptors: %m; release and retry")));
2453  errno = 0;
2454  if (ReleaseLruFile())
2455  goto TryAgain;
2456  errno = save_errno;
2457  }
2458 
2459  return NULL;
2460 }
static PgChecksumMode mode
Definition: pg_checksums.c:65
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:260
#define DO_DB(A)
Definition: fd.c:176
int errcode(int sqlerrcode)
Definition: elog.c:698
static bool reserveAllocatedDesc(void)
Definition: fd.c:2342
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:248
static bool ReleaseLruFile(void)
Definition: fd.c:1335
#define ERROR
Definition: elog.h:46
static void ReleaseLruFiles(void)
Definition: fd.c:1357
FILE * file
Definition: fd.c:252
#define ereport(elevel,...)
Definition: elog.h:157
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:723
SubTransactionId create_subid
Definition: fd.c:249
const char * name
Definition: encode.c:515
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
static int maxAllocatedDescs
Definition: fd.c:259
static int numAllocatedDescs
Definition: fd.c:258

◆ AllocateVfd()

static File AllocateVfd ( void  )
static

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

1368 {
1369  Index i;
1370  File file;
1371 
1372  DO_DB(elog(LOG, "AllocateVfd. Size %zu", SizeVfdCache));
1373 
1374  Assert(SizeVfdCache > 0); /* InitFileAccess not called? */
1375 
1376  if (VfdCache[0].nextFree == 0)
1377  {
1378  /*
1379  * The free list is empty so it is time to increase the size of the
1380  * array. We choose to double it each time this happens. However,
1381  * there's not much point in starting *real* small.
1382  */
1383  Size newCacheSize = SizeVfdCache * 2;
1384  Vfd *newVfdCache;
1385 
1386  if (newCacheSize < 32)
1387  newCacheSize = 32;
1388 
1389  /*
1390  * Be careful not to clobber VfdCache ptr if realloc fails.
1391  */
1392  newVfdCache = (Vfd *) realloc(VfdCache, sizeof(Vfd) * newCacheSize);
1393  if (newVfdCache == NULL)
1394  ereport(ERROR,
1395  (errcode(ERRCODE_OUT_OF_MEMORY),
1396  errmsg("out of memory")));
1397  VfdCache = newVfdCache;
1398 
1399  /*
1400  * Initialize the new entries and link them into the free list.
1401  */
1402  for (i = SizeVfdCache; i < newCacheSize; i++)
1403  {
1404  MemSet((char *) &(VfdCache[i]), 0, sizeof(Vfd));
1405  VfdCache[i].nextFree = i + 1;
1406  VfdCache[i].fd = VFD_CLOSED;
1407  }
1408  VfdCache[newCacheSize - 1].nextFree = 0;
1410 
1411  /*
1412  * Record the new size
1413  */
1414  SizeVfdCache = newCacheSize;
1415  }
1416 
1417  file = VfdCache[0].nextFree;
1418 
1419  VfdCache[0].nextFree = VfdCache[file].nextFree;
1420 
1421  return file;
1422 }
File nextFree
Definition: fd.c:197
static Size SizeVfdCache
Definition: fd.c:213
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
int errcode(int sqlerrcode)
Definition: elog.c:698
#define MemSet(start, val, len)
Definition: c.h:1008
#define LOG
Definition: elog.h:26
#define ERROR
Definition: elog.h:46
Definition: fd.c:192
int fd
Definition: fd.c:194
unsigned int Index
Definition: c.h:549
#define VFD_CLOSED
Definition: fd.c:180
#define ereport(elevel,...)
Definition: elog.h:157
#define Assert(condition)
Definition: c.h:804
size_t Size
Definition: c.h:540
#define realloc(a, b)
Definition: header.h:60
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
int i
int File
Definition: fd.h:54

◆ AtEOSubXact_Files()

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

Definition at line 2966 of file fd.c.

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

2968 {
2969  Index i;
2970 
2971  for (i = 0; i < numAllocatedDescs; i++)
2972  {
2973  if (allocatedDescs[i].create_subid == mySubid)
2974  {
2975  if (isCommit)
2976  allocatedDescs[i].create_subid = parentSubid;
2977  else
2978  {
2979  /* have to recheck the item after FreeDesc (ugly) */
2980  FreeDesc(&allocatedDescs[i--]);
2981  }
2982  }
2983  }
2984 }
static AllocateDesc * allocatedDescs
Definition: fd.c:260
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2577
unsigned int Index
Definition: c.h:549
SubTransactionId create_subid
Definition: fd.c:249
int i
static int numAllocatedDescs
Definition: fd.c:258

◆ AtEOXact_Files()

void AtEOXact_Files ( bool  isCommit)

Definition at line 2999 of file fd.c.

References CleanupTempFiles(), numTempTableSpaces, and tempTableSpaces.

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

3000 {
3001  CleanupTempFiles(isCommit, false);
3002  tempTableSpaces = NULL;
3003  numTempTableSpaces = -1;
3004 }
static int numTempTableSpaces
Definition: fd.c:280
static Oid * tempTableSpaces
Definition: fd.c:279
static void CleanupTempFiles(bool isCommit, bool isProcExit)
Definition: fd.c:3031

◆ AtProcExit_Files()

static void AtProcExit_Files ( int  code,
Datum  arg 
)
static

Definition at line 3013 of file fd.c.

References CleanupTempFiles().

Referenced by InitFileAccess().

3014 {
3015  CleanupTempFiles(false, true);
3016 }
static void CleanupTempFiles(bool isCommit, bool isProcExit)
Definition: fd.c:3031

◆ BasicOpenFile()

int BasicOpenFile ( const char *  fileName,
int  fileFlags 
)

Definition at line 1033 of file fd.c.

References BasicOpenFilePerm(), and pg_file_create_mode.

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

1034 {
1035  return BasicOpenFilePerm(fileName, fileFlags, pg_file_create_mode);
1036 }
int pg_file_create_mode
Definition: file_perm.c:19
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1055

◆ BasicOpenFilePerm()

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

Definition at line 1055 of file fd.c.

References close, ereport, errcode(), errmsg(), vfd::fd, LOG, O_DSYNC, PG_O_DIRECT, ReleaseLruFile(), and StaticAssertStmt.

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

1056 {
1057  int fd;
1058 
1059 tryAgain:
1060 #ifdef PG_O_DIRECT_USE_F_NOCACHE
1061 
1062  /*
1063  * The value we defined to stand in for O_DIRECT when simulating it with
1064  * F_NOCACHE had better not collide with any of the standard flags.
1065  */
1067  (O_APPEND |
1068  O_CREAT |
1069  O_EXCL |
1070  O_RDWR |
1071  O_RDONLY |
1072  O_SYNC |
1073  O_TRUNC |
1074  O_WRONLY)) == 0,
1075  "PG_O_DIRECT value collides with standard flag");
1076 #if defined(O_CLOEXEC)
1077  StaticAssertStmt((PG_O_DIRECT & O_CLOEXEC) == 0,
1078  "PG_O_DIRECT value collides with O_CLOEXEC");
1079 #endif
1080 #if defined(O_DSYNC)
1082  "PG_O_DIRECT value collides with O_DSYNC");
1083 #endif
1084 
1085  fd = open(fileName, fileFlags & ~PG_O_DIRECT, fileMode);
1086 #else
1087  fd = open(fileName, fileFlags, fileMode);
1088 #endif
1089 
1090  if (fd >= 0)
1091  {
1092 #ifdef PG_O_DIRECT_USE_F_NOCACHE
1093  if (fileFlags & PG_O_DIRECT)
1094  {
1095  if (fcntl(fd, F_NOCACHE, 1) < 0)
1096  {
1097  int save_errno = errno;
1098 
1099  close(fd);
1100  errno = save_errno;
1101  return -1;
1102  }
1103  }
1104 #endif
1105 
1106  return fd; /* success! */
1107  }
1108 
1109  if (errno == EMFILE || errno == ENFILE)
1110  {
1111  int save_errno = errno;
1112 
1113  ereport(LOG,
1114  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
1115  errmsg("out of file descriptors: %m; release and retry")));
1116  errno = 0;
1117  if (ReleaseLruFile())
1118  goto tryAgain;
1119  errno = save_errno;
1120  }
1121 
1122  return -1; /* failure */
1123 }
int errcode(int sqlerrcode)
Definition: elog.c:698
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:918
static bool ReleaseLruFile(void)
Definition: fd.c:1335
#define PG_O_DIRECT
Definition: fd.h:95
#define O_DSYNC
Definition: win32_port.h:328
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define close(a)
Definition: win32.h:12

◆ CleanupTempFiles()

static void CleanupTempFiles ( bool  isCommit,
bool  isProcExit 
)
static

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

3032 {
3033  Index i;
3034 
3035  /*
3036  * Careful here: at proc_exit we need extra cleanup, not just
3037  * xact_temporary files.
3038  */
3039  if (isProcExit || have_xact_temporary_files)
3040  {
3041  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
3042  for (i = 1; i < SizeVfdCache; i++)
3043  {
3044  unsigned short fdstate = VfdCache[i].fdstate;
3045 
3046  if (((fdstate & FD_DELETE_AT_CLOSE) || (fdstate & FD_CLOSE_AT_EOXACT)) &&
3047  VfdCache[i].fileName != NULL)
3048  {
3049  /*
3050  * If we're in the process of exiting a backend process, close
3051  * all temporary files. Otherwise, only close temporary files
3052  * local to the current transaction. They should be closed by
3053  * the ResourceOwner mechanism already, so this is just a
3054  * debugging cross-check.
3055  */
3056  if (isProcExit)
3057  FileClose(i);
3058  else if (fdstate & FD_CLOSE_AT_EOXACT)
3059  {
3060  elog(WARNING,
3061  "temporary file %s not closed at end-of-transaction",
3062  VfdCache[i].fileName);
3063  FileClose(i);
3064  }
3065  }
3066  }
3067 
3068  have_xact_temporary_files = false;
3069  }
3070 
3071  /* Complain if any allocated files remain open at commit. */
3072  if (isCommit && numAllocatedDescs > 0)
3073  elog(WARNING, "%d temporary files and directories not closed at end-of-transaction",
3075 
3076  /* Clean up "allocated" stdio files, dirs and fds. */
3077  while (numAllocatedDescs > 0)
3078  FreeDesc(&allocatedDescs[0]);
3079 }
static AllocateDesc * allocatedDescs
Definition: fd.c:260
static Size SizeVfdCache
Definition: fd.c:213
#define FD_DELETE_AT_CLOSE
Definition: fd.c:188
static Vfd * VfdCache
Definition: fd.c:212
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2577
static bool have_xact_temporary_files
Definition: fd.c:224
unsigned short fdstate
Definition: fd.c:195
#define WARNING
Definition: elog.h:40
#define FileIsNotOpen(file)
Definition: fd.c:185
unsigned int Index
Definition: c.h:549
void FileClose(File file)
Definition: fd.c:1917
#define Assert(condition)
Definition: c.h:804
#define elog(elevel,...)
Definition: elog.h:232
int i
#define FD_CLOSE_AT_EOXACT
Definition: fd.c:189
static int numAllocatedDescs
Definition: fd.c:258

◆ closeAllVfds()

void closeAllVfds ( void  )

Definition at line 2855 of file fd.c.

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

Referenced by standard_ProcessUtility().

2856 {
2857  Index i;
2858 
2859  if (SizeVfdCache > 0)
2860  {
2861  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2862  for (i = 1; i < SizeVfdCache; i++)
2863  {
2864  if (!FileIsNotOpen(i))
2865  LruDelete(i);
2866  }
2867  }
2868 }
static Size SizeVfdCache
Definition: fd.c:213
static void LruDelete(File file)
Definition: fd.c:1240
#define FileIsNotOpen(file)
Definition: fd.c:185
unsigned int Index
Definition: c.h:549
#define Assert(condition)
Definition: c.h:804
int i

◆ ClosePipeStream()

int ClosePipeStream ( FILE *  file)

Definition at line 2826 of file fd.c.

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

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

2827 {
2828  int i;
2829 
2830  DO_DB(elog(LOG, "ClosePipeStream: Allocated %d", numAllocatedDescs));
2831 
2832  /* Remove file from list of allocated files, if it's present */
2833  for (i = numAllocatedDescs; --i >= 0;)
2834  {
2835  AllocateDesc *desc = &allocatedDescs[i];
2836 
2837  if (desc->kind == AllocateDescPipe && desc->desc.file == file)
2838  return FreeDesc(desc);
2839  }
2840 
2841  /* Only get here if someone passes us a file not in allocatedDescs */
2842  elog(WARNING, "file passed to ClosePipeStream was not obtained from OpenPipeStream");
2843 
2844  return pclose(file);
2845 }
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:260
#define DO_DB(A)
Definition: fd.c:176
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:248
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2577
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:252
#define elog(elevel,...)
Definition: elog.h:232
int i
static int numAllocatedDescs
Definition: fd.c:258

◆ CloseTransientFile()

int CloseTransientFile ( int  fd)

Definition at line 2644 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(), looks_like_temp_rel_name(), perform_base_backup(), pg_truncate(), 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().

2645 {
2646  int i;
2647 
2648  DO_DB(elog(LOG, "CloseTransientFile: Allocated %d", numAllocatedDescs));
2649 
2650  /* Remove fd from list of allocated files, if it's present */
2651  for (i = numAllocatedDescs; --i >= 0;)
2652  {
2653  AllocateDesc *desc = &allocatedDescs[i];
2654 
2655  if (desc->kind == AllocateDescRawFD && desc->desc.fd == fd)
2656  return FreeDesc(desc);
2657  }
2658 
2659  /* Only get here if someone passes us a file not in allocatedDescs */
2660  elog(WARNING, "fd passed to CloseTransientFile was not obtained from OpenTransientFile");
2661 
2662  return close(fd);
2663 }
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:260
#define DO_DB(A)
Definition: fd.c:176
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:248
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2577
#define WARNING
Definition: elog.h:40
int fd
Definition: fd.c:254
#define elog(elevel,...)
Definition: elog.h:232
int i
#define close(a)
Definition: win32.h:12
static int numAllocatedDescs
Definition: fd.c:258

◆ count_usable_fds()

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

Definition at line 906 of file fd.c.

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

Referenced by set_max_safe_fds().

907 {
908  int *fd;
909  int size;
910  int used = 0;
911  int highestfd = 0;
912  int j;
913 
914 #ifdef HAVE_GETRLIMIT
915  struct rlimit rlim;
916  int getrlimit_status;
917 #endif
918 
919  size = 1024;
920  fd = (int *) palloc(size * sizeof(int));
921 
922 #ifdef HAVE_GETRLIMIT
923 #ifdef RLIMIT_NOFILE /* most platforms use RLIMIT_NOFILE */
924  getrlimit_status = getrlimit(RLIMIT_NOFILE, &rlim);
925 #else /* but BSD doesn't ... */
926  getrlimit_status = getrlimit(RLIMIT_OFILE, &rlim);
927 #endif /* RLIMIT_NOFILE */
928  if (getrlimit_status != 0)
929  ereport(WARNING, (errmsg("getrlimit failed: %m")));
930 #endif /* HAVE_GETRLIMIT */
931 
932  /* dup until failure or probe limit reached */
933  for (;;)
934  {
935  int thisfd;
936 
937 #ifdef HAVE_GETRLIMIT
938 
939  /*
940  * don't go beyond RLIMIT_NOFILE; causes irritating kernel logs on
941  * some platforms
942  */
943  if (getrlimit_status == 0 && highestfd >= rlim.rlim_cur - 1)
944  break;
945 #endif
946 
947  thisfd = dup(0);
948  if (thisfd < 0)
949  {
950  /* Expect EMFILE or ENFILE, else it's fishy */
951  if (errno != EMFILE && errno != ENFILE)
952  elog(WARNING, "dup(0) failed after %d successes: %m", used);
953  break;
954  }
955 
956  if (used >= size)
957  {
958  size *= 2;
959  fd = (int *) repalloc(fd, size * sizeof(int));
960  }
961  fd[used++] = thisfd;
962 
963  if (highestfd < thisfd)
964  highestfd = thisfd;
965 
966  if (used >= max_to_probe)
967  break;
968  }
969 
970  /* release the files we opened */
971  for (j = 0; j < used; j++)
972  close(fd[j]);
973 
974  pfree(fd);
975 
976  /*
977  * Return results. usable_fds is just the number of successful dups. We
978  * assume that the system limit is highestfd+1 (remember 0 is a legal FD
979  * number) and so already_open is highestfd+1 - usable_fds.
980  */
981  *usable_fds = used;
982  *already_open = highestfd + 1 - used;
983 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
void pfree(void *pointer)
Definition: mcxt.c:1169
#define WARNING
Definition: elog.h:40
#define ereport(elevel,...)
Definition: elog.h:157
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1182
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
#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 3584 of file fd.c.

References fsync_fname_ext().

Referenced by SyncDataDirectory().

3585 {
3586  /*
3587  * We want to silently ignoring errors about unreadable files. Pass that
3588  * desire on to fsync_fname_ext().
3589  */
3590  fsync_fname_ext(fname, isdir, true, elevel);
3591 }
static int elevel
Definition: vacuumlazy.c:403
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3619

◆ Delete()

static void Delete ( File  file)
static

Definition at line 1221 of file fd.c.

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

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

1222 {
1223  Vfd *vfdP;
1224 
1225  Assert(file != 0);
1226 
1227  DO_DB(elog(LOG, "Delete %d (%s)",
1228  file, VfdCache[file].fileName));
1229  DO_DB(_dump_lru());
1230 
1231  vfdP = &VfdCache[file];
1232 
1235 
1236  DO_DB(_dump_lru());
1237 }
File lruLessRecently
Definition: fd.c:199
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
Definition: fd.c:192
#define Assert(condition)
Definition: c.h:804
File lruMoreRecently
Definition: fd.c:198
#define elog(elevel,...)
Definition: elog.h:232

◆ durable_rename()

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

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

693 {
694  int fd;
695 
696  /*
697  * First fsync the old and target path (if it exists), to ensure that they
698  * are properly persistent on disk. Syncing the target file is not
699  * strictly necessary, but it makes it easier to reason about crashes;
700  * because it's then guaranteed that either source or target file exists
701  * after a crash.
702  */
703  if (fsync_fname_ext(oldfile, false, false, elevel) != 0)
704  return -1;
705 
706  fd = OpenTransientFile(newfile, PG_BINARY | O_RDWR);
707  if (fd < 0)
708  {
709  if (errno != ENOENT)
710  {
711  ereport(elevel,
713  errmsg("could not open file \"%s\": %m", newfile)));
714  return -1;
715  }
716  }
717  else
718  {
719  if (pg_fsync(fd) != 0)
720  {
721  int save_errno;
722 
723  /* close file upon error, might not be in transaction context */
724  save_errno = errno;
725  CloseTransientFile(fd);
726  errno = save_errno;
727 
728  ereport(elevel,
730  errmsg("could not fsync file \"%s\": %m", newfile)));
731  return -1;
732  }
733 
734  if (CloseTransientFile(fd) != 0)
735  {
736  ereport(elevel,
738  errmsg("could not close file \"%s\": %m", newfile)));
739  return -1;
740  }
741  }
742 
743  /* Time to do the real deal... */
744  if (rename(oldfile, newfile) < 0)
745  {
746  ereport(elevel,
748  errmsg("could not rename file \"%s\" to \"%s\": %m",
749  oldfile, newfile)));
750  return -1;
751  }
752 
753  /*
754  * To guarantee renaming the file is persistent, fsync the file with its
755  * new name, and its containing directory.
756  */
757  if (fsync_fname_ext(newfile, false, false, elevel) != 0)
758  return -1;
759 
760  if (fsync_parent_path(newfile, elevel) != 0)
761  return -1;
762 
763  return 0;
764 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1271
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2467
int errcode_for_file_access(void)
Definition: elog.c:721
int CloseTransientFile(int fd)
Definition: fd.c:2644
static int elevel
Definition: vacuumlazy.c:403
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
int pg_fsync(int fd)
Definition: fd.c:352
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3619
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3695

◆ durable_rename_excl()

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

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

823 {
824  /*
825  * Ensure that, if we crash directly after the rename/link, a file with
826  * valid contents is moved into place.
827  */
828  if (fsync_fname_ext(oldfile, false, false, elevel) != 0)
829  return -1;
830 
831 #ifdef HAVE_WORKING_LINK
832  if (link(oldfile, newfile) < 0)
833  {
834  ereport(elevel,
836  errmsg("could not link file \"%s\" to \"%s\": %m",
837  oldfile, newfile)));
838  return -1;
839  }
840  unlink(oldfile);
841 #else
842  if (rename(oldfile, newfile) < 0)
843  {
844  ereport(elevel,
846  errmsg("could not rename file \"%s\" to \"%s\": %m",
847  oldfile, newfile)));
848  return -1;
849  }
850 #endif
851 
852  /*
853  * Make change persistent in case of an OS crash, both the new entry and
854  * its parent directory need to be flushed.
855  */
856  if (fsync_fname_ext(newfile, false, false, elevel) != 0)
857  return -1;
858 
859  /* Same for parent directory */
860  if (fsync_parent_path(newfile, elevel) != 0)
861  return -1;
862 
863  return 0;
864 }
int errcode_for_file_access(void)
Definition: elog.c:721
static int elevel
Definition: vacuumlazy.c:403
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
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:3619
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3695

◆ durable_unlink()

int durable_unlink ( const char *  fname,
int  elevel 
)

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

783 {
784  if (unlink(fname) < 0)
785  {
786  ereport(elevel,
788  errmsg("could not remove file \"%s\": %m",
789  fname)));
790  return -1;
791  }
792 
793  /*
794  * To guarantee that the removal of the file is persistent, fsync its
795  * parent directory.
796  */
797  if (fsync_parent_path(fname, elevel) != 0)
798  return -1;
799 
800  return 0;
801 }
int errcode_for_file_access(void)
Definition: elog.c:721
static int elevel
Definition: vacuumlazy.c:403
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3695

◆ FileAccess()

static int FileAccess ( File  file)
static

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

1446 {
1447  int returnValue;
1448 
1449  DO_DB(elog(LOG, "FileAccess %d (%s)",
1450  file, VfdCache[file].fileName));
1451 
1452  /*
1453  * Is the file open? If not, open it and put it at the head of the LRU
1454  * ring (possibly closing the least recently used file to get an FD).
1455  */
1456 
1457  if (FileIsNotOpen(file))
1458  {
1459  returnValue = LruInsert(file);
1460  if (returnValue != 0)
1461  return returnValue;
1462  }
1463  else if (VfdCache[0].lruLessRecently != file)
1464  {
1465  /*
1466  * We now know that the file is open and that it is not the last one
1467  * accessed, so we need to move it to the head of the Lru ring.
1468  */
1469 
1470  Delete(file);
1471  Insert(file);
1472  }
1473 
1474  return 0;
1475 }
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
static void Delete(File file)
Definition: fd.c:1221
#define LOG
Definition: elog.h:26
static int LruInsert(File file)
Definition: fd.c:1288
static void Insert(File file)
Definition: fd.c:1266
#define FileIsNotOpen(file)
Definition: fd.c:185
#define elog(elevel,...)
Definition: elog.h:232

◆ FileClose()

void FileClose ( File  file)

Definition at line 1917 of file fd.c.

References Assert, close, data_sync_elevel(), Delete(), DO_DB, elog, ereport, errcode_for_file_access(), errmsg(), 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::st_size, stat, temporary_files_size, and VFD_CLOSED.

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

1918 {
1919  Vfd *vfdP;
1920 
1921  Assert(FileIsValid(file));
1922 
1923  DO_DB(elog(LOG, "FileClose: %d (%s)",
1924  file, VfdCache[file].fileName));
1925 
1926  vfdP = &VfdCache[file];
1927 
1928  if (!FileIsNotOpen(file))
1929  {
1930  /* close the file */
1931  if (close(vfdP->fd) != 0)
1932  {
1933  /*
1934  * We may need to panic on failure to close non-temporary files;
1935  * see LruDelete.
1936  */
1938  "could not close file \"%s\": %m", vfdP->fileName);
1939  }
1940 
1941  --nfile;
1942  vfdP->fd = VFD_CLOSED;
1943 
1944  /* remove the file from the lru ring */
1945  Delete(file);
1946  }
1947 
1948  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
1949  {
1950  /* Subtract its size from current usage (do first in case of error) */
1951  temporary_files_size -= vfdP->fileSize;
1952  vfdP->fileSize = 0;
1953  }
1954 
1955  /*
1956  * Delete the file if it was temporary, and make a log entry if wanted
1957  */
1958  if (vfdP->fdstate & FD_DELETE_AT_CLOSE)
1959  {
1960  struct stat filestats;
1961  int stat_errno;
1962 
1963  /*
1964  * If we get an error, as could happen within the ereport/elog calls,
1965  * we'll come right back here during transaction abort. Reset the
1966  * flag to ensure that we can't get into an infinite loop. This code
1967  * is arranged to ensure that the worst-case consequence is failing to
1968  * emit log message(s), not failing to attempt the unlink.
1969  */
1970  vfdP->fdstate &= ~FD_DELETE_AT_CLOSE;
1971 
1972 
1973  /* first try the stat() */
1974  if (stat(vfdP->fileName, &filestats))
1975  stat_errno = errno;
1976  else
1977  stat_errno = 0;
1978 
1979  /* in any case do the unlink */
1980  if (unlink(vfdP->fileName))
1981  ereport(LOG,
1983  errmsg("could not delete file \"%s\": %m", vfdP->fileName)));
1984 
1985  /* and last report the stat results */
1986  if (stat_errno == 0)
1987  ReportTemporaryFileUsage(vfdP->fileName, filestats.st_size);
1988  else
1989  {
1990  errno = stat_errno;
1991  ereport(LOG,
1993  errmsg("could not stat file \"%s\": %m", vfdP->fileName)));
1994  }
1995  }
1996 
1997  /* Unregister it from the resource owner */
1998  if (vfdP->resowner)
1999  ResourceOwnerForgetFile(vfdP->resowner, file);
2000 
2001  /*
2002  * Return the Vfd slot to the free list
2003  */
2004  FreeVfd(file);
2005 }
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:190
#define DO_DB(A)
Definition: fd.c:176
#define FD_DELETE_AT_CLOSE
Definition: fd.c:188
static Vfd * VfdCache
Definition: fd.c:212
static void Delete(File file)
Definition: fd.c:1221
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:201
int errcode_for_file_access(void)
Definition: elog.c:721
static int nfile
Definition: fd.c:218
unsigned short fdstate
Definition: fd.c:195
Definition: fd.c:192
off_t fileSize
Definition: fd.c:200
int fd
Definition: fd.c:194
ResourceOwner resowner
Definition: fd.c:196
static void ReportTemporaryFileUsage(const char *path, off_t size)
Definition: fd.c:1481
#define FileIsNotOpen(file)
Definition: fd.c:185
int data_sync_elevel(int elevel)
Definition: fd.c:3758
#define FileIsValid(file)
Definition: fd.c:182
#define VFD_CLOSED
Definition: fd.c:180
static uint64 temporary_files_size
Definition: fd.c:232
#define ereport(elevel,...)
Definition: elog.h:157
#define Assert(condition)
Definition: c.h:804
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
static void FreeVfd(File file)
Definition: fd.c:1425
#define close(a)
Definition: win32.h:12
void ResourceOwnerForgetFile(ResourceOwner owner, File file)
Definition: resowner.c:1306
#define stat
Definition: win32_port.h:275

◆ FileGetRawDesc()

int FileGetRawDesc ( File  file)

Definition at line 2311 of file fd.c.

References Assert, vfd::fd, and FileIsValid.

2312 {
2313  Assert(FileIsValid(file));
2314  return VfdCache[file].fd;
2315 }
static Vfd * VfdCache
Definition: fd.c:212
int fd
Definition: fd.c:194
#define FileIsValid(file)
Definition: fd.c:182
#define Assert(condition)
Definition: c.h:804

◆ FileGetRawFlags()

int FileGetRawFlags ( File  file)

Definition at line 2321 of file fd.c.

References Assert, vfd::fileFlags, and FileIsValid.

2322 {
2323  Assert(FileIsValid(file));
2324  return VfdCache[file].fileFlags;
2325 }
static Vfd * VfdCache
Definition: fd.c:212
#define FileIsValid(file)
Definition: fd.c:182
#define Assert(condition)
Definition: c.h:804
int fileFlags
Definition: fd.c:203

◆ FileGetRawMode()

mode_t FileGetRawMode ( File  file)

Definition at line 2331 of file fd.c.

References Assert, FileIsValid, and vfd::fileMode.

2332 {
2333  Assert(FileIsValid(file));
2334  return VfdCache[file].fileMode;
2335 }
static Vfd * VfdCache
Definition: fd.c:212
mode_t fileMode
Definition: fd.c:204
#define FileIsValid(file)
Definition: fd.c:182
#define Assert(condition)
Definition: c.h:804

◆ FilePathName()

char* FilePathName ( File  file)

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

2296 {
2297  Assert(FileIsValid(file));
2298 
2299  return VfdCache[file].fileName;
2300 }
static Vfd * VfdCache
Definition: fd.c:212
char * fileName
Definition: fd.c:201
#define FileIsValid(file)
Definition: fd.c:182
#define Assert(condition)
Definition: c.h:804

◆ FilePrefetch()

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

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

2018 {
2019 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
2020  int returnCode;
2021 
2022  Assert(FileIsValid(file));
2023 
2024  DO_DB(elog(LOG, "FilePrefetch: %d (%s) " INT64_FORMAT " %d",
2025  file, VfdCache[file].fileName,
2026  (int64) offset, amount));
2027 
2028  returnCode = FileAccess(file);
2029  if (returnCode < 0)
2030  return returnCode;
2031 
2032  pgstat_report_wait_start(wait_event_info);
2033  returnCode = posix_fadvise(VfdCache[file].fd, offset, amount,
2034  POSIX_FADV_WILLNEED);
2036 
2037  return returnCode;
2038 #else
2039  Assert(FileIsValid(file));
2040  return 0;
2041 #endif
2042 }
static void pgstat_report_wait_end(void)
Definition: wait_event.h:278
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:262
#define FileIsValid(file)
Definition: fd.c:182
static int FileAccess(File file)
Definition: fd.c:1445
#define Assert(condition)
Definition: c.h:804
#define INT64_FORMAT
Definition: c.h:483
#define elog(elevel,...)
Definition: elog.h:232

◆ FileRead()

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

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

2070 {
2071  int returnCode;
2072  Vfd *vfdP;
2073 
2074  Assert(FileIsValid(file));
2075 
2076  DO_DB(elog(LOG, "FileRead: %d (%s) " INT64_FORMAT " %d %p",
2077  file, VfdCache[file].fileName,
2078  (int64) offset,
2079  amount, buffer));
2080 
2081  returnCode = FileAccess(file);
2082  if (returnCode < 0)
2083  return returnCode;
2084 
2085  vfdP = &VfdCache[file];
2086 
2087 retry:
2088  pgstat_report_wait_start(wait_event_info);
2089  returnCode = pg_pread(vfdP->fd, buffer, amount, offset);
2091 
2092  if (returnCode < 0)
2093  {
2094  /*
2095  * Windows may run out of kernel buffers and return "Insufficient
2096  * system resources" error. Wait a bit and retry to solve it.
2097  *
2098  * It is rumored that EINTR is also possible on some Unix filesystems,
2099  * in which case immediate retry is indicated.
2100  */
2101 #ifdef WIN32
2102  DWORD error = GetLastError();
2103 
2104  switch (error)
2105  {
2106  case ERROR_NO_SYSTEM_RESOURCES:
2107  pg_usleep(1000L);
2108  errno = EINTR;
2109  break;
2110  default:
2111  _dosmaperr(error);
2112  break;
2113  }
2114 #endif
2115  /* OK to retry if interrupted */
2116  if (errno == EINTR)
2117  goto retry;
2118  }
2119 
2120  return returnCode;
2121 }
static void pgstat_report_wait_end(void)
Definition: wait_event.h:278
static void error(void)
Definition: sql-dyntest.c:147
#define DO_DB(A)
Definition: fd.c:176
void _dosmaperr(unsigned long)
Definition: win32error.c:171
static Vfd * VfdCache
Definition: fd.c:212
#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
Definition: fd.c:192
int fd
Definition: fd.c:194
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:262
#define FileIsValid(file)
Definition: fd.c:182
static int FileAccess(File file)
Definition: fd.c:1445
#define Assert(condition)
Definition: c.h:804
#define INT64_FORMAT
Definition: c.h:483
#define elog(elevel,...)
Definition: elog.h:232
#define EINTR
Definition: win32_port.h:343

◆ FileSize()

off_t FileSize ( File  file)

Definition at line 2243 of file fd.c.

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

Referenced by _mdnblocks(), BufFileSeek(), and BufFileSize().

2244 {
2245  Assert(FileIsValid(file));
2246 
2247  DO_DB(elog(LOG, "FileSize %d (%s)",
2248  file, VfdCache[file].fileName));
2249 
2250  if (FileIsNotOpen(file))
2251  {
2252  if (FileAccess(file) < 0)
2253  return (off_t) -1;
2254  }
2255 
2256  return lseek(VfdCache[file].fd, 0, SEEK_END);
2257 }
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#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:185
#define FileIsValid(file)
Definition: fd.c:182
static int FileAccess(File file)
Definition: fd.c:1445
#define Assert(condition)
Definition: c.h:804
#define elog(elevel,...)
Definition: elog.h:232

◆ FileSync()

int FileSync ( File  file,
uint32  wait_event_info 
)

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

2223 {
2224  int returnCode;
2225 
2226  Assert(FileIsValid(file));
2227 
2228  DO_DB(elog(LOG, "FileSync: %d (%s)",
2229  file, VfdCache[file].fileName));
2230 
2231  returnCode = FileAccess(file);
2232  if (returnCode < 0)
2233  return returnCode;
2234 
2235  pgstat_report_wait_start(wait_event_info);
2236  returnCode = pg_fsync(VfdCache[file].fd);
2238 
2239  return returnCode;
2240 }
static void pgstat_report_wait_end(void)
Definition: wait_event.h:278
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:262
#define FileIsValid(file)
Definition: fd.c:182
static int FileAccess(File file)
Definition: fd.c:1445
#define Assert(condition)
Definition: c.h:804
#define elog(elevel,...)
Definition: elog.h:232
int pg_fsync(int fd)
Definition: fd.c:352

◆ FileTruncate()

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

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

2261 {
2262  int returnCode;
2263 
2264  Assert(FileIsValid(file));
2265 
2266  DO_DB(elog(LOG, "FileTruncate %d (%s)",
2267  file, VfdCache[file].fileName));
2268 
2269  returnCode = FileAccess(file);
2270  if (returnCode < 0)
2271  return returnCode;
2272 
2273  pgstat_report_wait_start(wait_event_info);
2274  returnCode = ftruncate(VfdCache[file].fd, offset);
2276 
2277  if (returnCode == 0 && VfdCache[file].fileSize > offset)
2278  {
2279  /* adjust our state for truncation of a temp file */
2280  Assert(VfdCache[file].fdstate & FD_TEMP_FILE_LIMIT);
2281  temporary_files_size -= VfdCache[file].fileSize - offset;
2282  VfdCache[file].fileSize = offset;
2283  }
2284 
2285  return returnCode;
2286 }
static void pgstat_report_wait_end(void)
Definition: wait_event.h:278
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:190
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
off_t fileSize
Definition: fd.c:200
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:262
#define FileIsValid(file)
Definition: fd.c:182
static uint64 temporary_files_size
Definition: fd.c:232
static int FileAccess(File file)
Definition: fd.c:1445
#define Assert(condition)
Definition: c.h:804
#define elog(elevel,...)
Definition: elog.h:232
#define ftruncate(a, b)
Definition: win32_port.h:65

◆ FileWrite()

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

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

2126 {
2127  int returnCode;
2128  Vfd *vfdP;
2129 
2130  Assert(FileIsValid(file));
2131 
2132  DO_DB(elog(LOG, "FileWrite: %d (%s) " INT64_FORMAT " %d %p",
2133  file, VfdCache[file].fileName,
2134  (int64) offset,
2135  amount, buffer));
2136 
2137  returnCode = FileAccess(file);
2138  if (returnCode < 0)
2139  return returnCode;
2140 
2141  vfdP = &VfdCache[file];
2142 
2143  /*
2144  * If enforcing temp_file_limit and it's a temp file, check to see if the
2145  * write would overrun temp_file_limit, and throw error if so. Note: it's
2146  * really a modularity violation to throw error here; we should set errno
2147  * and return -1. However, there's no way to report a suitable error
2148  * message if we do that. All current callers would just throw error
2149  * immediately anyway, so this is safe at present.
2150  */
2151  if (temp_file_limit >= 0 && (vfdP->fdstate & FD_TEMP_FILE_LIMIT))
2152  {
2153  off_t past_write = offset + amount;
2154 
2155  if (past_write > vfdP->fileSize)
2156  {
2157  uint64 newTotal = temporary_files_size;
2158 
2159  newTotal += past_write - vfdP->fileSize;
2160  if (newTotal > (uint64) temp_file_limit * (uint64) 1024)
2161  ereport(ERROR,
2162  (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
2163  errmsg("temporary file size exceeds temp_file_limit (%dkB)",
2164  temp_file_limit)));
2165  }
2166  }
2167 
2168 retry:
2169  errno = 0;
2170  pgstat_report_wait_start(wait_event_info);
2171  returnCode = pg_pwrite(VfdCache[file].fd, buffer, amount, offset);
2173 
2174  /* if write didn't set errno, assume problem is no disk space */
2175  if (returnCode != amount && errno == 0)
2176  errno = ENOSPC;
2177 
2178  if (returnCode >= 0)
2179  {
2180  /*
2181  * Maintain fileSize and temporary_files_size if it's a temp file.
2182  */
2183  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
2184  {
2185  off_t past_write = offset + amount;
2186 
2187  if (past_write > vfdP->fileSize)
2188  {
2189  temporary_files_size += past_write - vfdP->fileSize;
2190  vfdP->fileSize = past_write;
2191  }
2192  }
2193  }
2194  else
2195  {
2196  /*
2197  * See comments in FileRead()
2198  */
2199 #ifdef WIN32
2200  DWORD error = GetLastError();
2201 
2202  switch (error)
2203  {
2204  case ERROR_NO_SYSTEM_RESOURCES:
2205  pg_usleep(1000L);
2206  errno = EINTR;
2207  break;
2208  default:
2209  _dosmaperr(error);
2210  break;
2211  }
2212 #endif
2213  /* OK to retry if interrupted */
2214  if (errno == EINTR)
2215  goto retry;
2216  }
2217 
2218  return returnCode;
2219 }
static void pgstat_report_wait_end(void)
Definition: wait_event.h:278
static void error(void)
Definition: sql-dyntest.c:147
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:190
#define DO_DB(A)
Definition: fd.c:176
void _dosmaperr(unsigned long)
Definition: win32error.c:171
static Vfd * VfdCache
Definition: fd.c:212
int errcode(int sqlerrcode)
Definition: elog.c:698
#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:46
unsigned short fdstate
Definition: fd.c:195
Definition: fd.c:192
off_t fileSize
Definition: fd.c:200
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:262
#define FileIsValid(file)
Definition: fd.c:182
static uint64 temporary_files_size
Definition: fd.c:232
#define ereport(elevel,...)
Definition: elog.h:157
static int FileAccess(File file)
Definition: fd.c:1445
#define Assert(condition)
Definition: c.h:804
#define INT64_FORMAT
Definition: c.h:483
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
#define EINTR
Definition: win32_port.h:343
int temp_file_limit
Definition: guc.c:609

◆ FileWriteback()

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

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

2046 {
2047  int returnCode;
2048 
2049  Assert(FileIsValid(file));
2050 
2051  DO_DB(elog(LOG, "FileWriteback: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
2052  file, VfdCache[file].fileName,
2053  (int64) offset, (int64) nbytes));
2054 
2055  if (nbytes <= 0)
2056  return;
2057 
2058  returnCode = FileAccess(file);
2059  if (returnCode < 0)
2060  return;
2061 
2062  pgstat_report_wait_start(wait_event_info);
2063  pg_flush_data(VfdCache[file].fd, offset, nbytes);
2065 }
static void pgstat_report_wait_end(void)
Definition: wait_event.h:278
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:262
void pg_flush_data(int fd, off_t offset, off_t nbytes)
Definition: fd.c:462
#define FileIsValid(file)
Definition: fd.c:182
static int FileAccess(File file)
Definition: fd.c:1445
#define Assert(condition)
Definition: c.h:804
#define INT64_FORMAT
Definition: c.h:483
#define elog(elevel,...)
Definition: elog.h:232

◆ FreeDesc()

static int FreeDesc ( AllocateDesc desc)
static

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

2578 {
2579  int result;
2580 
2581  /* Close the underlying object */
2582  switch (desc->kind)
2583  {
2584  case AllocateDescFile:
2585  result = fclose(desc->desc.file);
2586  break;
2587  case AllocateDescPipe:
2588  result = pclose(desc->desc.file);
2589  break;
2590  case AllocateDescDir:
2591  result = closedir(desc->desc.dir);
2592  break;
2593  case AllocateDescRawFD:
2594  result = close(desc->desc.fd);
2595  break;
2596  default:
2597  elog(ERROR, "AllocateDesc kind not recognized");
2598  result = 0; /* keep compiler quiet */
2599  break;
2600  }
2601 
2602  /* Compact storage in the allocatedDescs array */
2605 
2606  return result;
2607 }
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:260
DIR * dir
Definition: fd.c:253
int closedir(DIR *)
Definition: dirent.c:123
AllocateDescKind kind
Definition: fd.c:248
#define ERROR
Definition: elog.h:46
FILE * file
Definition: fd.c:252
int fd
Definition: fd.c:254
#define elog(elevel,...)
Definition: elog.h:232
#define close(a)
Definition: win32.h:12
static int numAllocatedDescs
Definition: fd.c:258

◆ FreeDir()

int FreeDir ( DIR dir)

Definition at line 2796 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(), SyncDataDirectory(), UpdateLogicalMappings(), and walkdir().

2797 {
2798  int i;
2799 
2800  /* Nothing to do if AllocateDir failed */
2801  if (dir == NULL)
2802  return 0;
2803 
2804  DO_DB(elog(LOG, "FreeDir: Allocated %d", numAllocatedDescs));
2805 
2806  /* Remove dir from list of allocated dirs, if it's present */
2807  for (i = numAllocatedDescs; --i >= 0;)
2808  {
2809  AllocateDesc *desc = &allocatedDescs[i];
2810 
2811  if (desc->kind == AllocateDescDir && desc->desc.dir == dir)
2812  return FreeDesc(desc);
2813  }
2814 
2815  /* Only get here if someone passes us a dir not in allocatedDescs */
2816  elog(WARNING, "dir passed to FreeDir was not obtained from AllocateDir");
2817 
2818  return closedir(dir);
2819 }
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:260
DIR * dir
Definition: fd.c:253
#define DO_DB(A)
Definition: fd.c:176
int closedir(DIR *)
Definition: dirent.c:123
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:248
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2577
#define WARNING
Definition: elog.h:40
#define elog(elevel,...)
Definition: elog.h:232
int i
static int numAllocatedDescs
Definition: fd.c:258

◆ FreeFile()

int FreeFile ( FILE *  file)

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

2617 {
2618  int i;
2619 
2620  DO_DB(elog(LOG, "FreeFile: Allocated %d", numAllocatedDescs));
2621 
2622  /* Remove file from list of allocated files, if it's present */
2623  for (i = numAllocatedDescs; --i >= 0;)
2624  {
2625  AllocateDesc *desc = &allocatedDescs[i];
2626 
2627  if (desc->kind == AllocateDescFile && desc->desc.file == file)
2628  return FreeDesc(desc);
2629  }
2630 
2631  /* Only get here if someone passes us a file not in allocatedDescs */
2632  elog(WARNING, "file passed to FreeFile was not obtained from AllocateFile");
2633 
2634  return fclose(file);
2635 }
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:260
#define DO_DB(A)
Definition: fd.c:176
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:248
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2577
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:252
#define elog(elevel,...)
Definition: elog.h:232
int i
static int numAllocatedDescs
Definition: fd.c:258

◆ FreeVfd()

static void FreeVfd ( File  file)
static

Definition at line 1425 of file fd.c.

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

Referenced by FileClose(), and PathNameOpenFilePerm().

1426 {
1427  Vfd *vfdP = &VfdCache[file];
1428 
1429  DO_DB(elog(LOG, "FreeVfd: %d (%s)",
1430  file, vfdP->fileName ? vfdP->fileName : ""));
1431 
1432  if (vfdP->fileName != NULL)
1433  {
1434  free(vfdP->fileName);
1435  vfdP->fileName = NULL;
1436  }
1437  vfdP->fdstate = 0x0;
1438 
1439  vfdP->nextFree = VfdCache[0].nextFree;
1440  VfdCache[0].nextFree = file;
1441 }
File nextFree
Definition: fd.c:197
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:201
unsigned short fdstate
Definition: fd.c:195
Definition: fd.c:192
#define free(a)
Definition: header.h:65
#define elog(elevel,...)
Definition: elog.h:232

◆ fsync_fname()

void fsync_fname ( const char *  fname,
bool  isdir 
)

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

667 {
668  fsync_fname_ext(fname, isdir, false, data_sync_elevel(ERROR));
669 }
#define ERROR
Definition: elog.h:46
int data_sync_elevel(int elevel)
Definition: fd.c:3758
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3619

◆ fsync_fname_ext()

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

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

3620 {
3621  int fd;
3622  int flags;
3623  int returncode;
3624 
3625  /*
3626  * Some OSs require directories to be opened read-only whereas other
3627  * systems don't allow us to fsync files opened read-only; so we need both
3628  * cases here. Using O_RDWR will cause us to fail to fsync files that are
3629  * not writable by our userid, but we assume that's OK.
3630  */
3631  flags = PG_BINARY;
3632  if (!isdir)
3633  flags |= O_RDWR;
3634  else
3635  flags |= O_RDONLY;
3636 
3637  fd = OpenTransientFile(fname, flags);
3638 
3639  /*
3640  * Some OSs don't allow us to open directories at all (Windows returns
3641  * EACCES), just ignore the error in that case. If desired also silently
3642  * ignoring errors about unreadable files. Log others.
3643  */
3644  if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES))
3645  return 0;
3646  else if (fd < 0 && ignore_perm && errno == EACCES)
3647  return 0;
3648  else if (fd < 0)
3649  {
3650  ereport(elevel,
3652  errmsg("could not open file \"%s\": %m", fname)));
3653  return -1;
3654  }
3655 
3656  returncode = pg_fsync(fd);
3657 
3658  /*
3659  * Some OSes don't allow us to fsync directories at all, so we can ignore
3660  * those errors. Anything else needs to be logged.
3661  */
3662  if (returncode != 0 && !(isdir && (errno == EBADF || errno == EINVAL)))
3663  {
3664  int save_errno;
3665 
3666  /* close file upon error, might not be in transaction context */
3667  save_errno = errno;
3668  (void) CloseTransientFile(fd);
3669  errno = save_errno;
3670 
3671  ereport(elevel,
3673  errmsg("could not fsync file \"%s\": %m", fname)));
3674  return -1;
3675  }
3676 
3677  if (CloseTransientFile(fd) != 0)
3678  {
3679  ereport(elevel,
3681  errmsg("could not close file \"%s\": %m", fname)));
3682  return -1;
3683  }
3684 
3685  return 0;
3686 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1271
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2467
int errcode_for_file_access(void)
Definition: elog.c:721
int CloseTransientFile(int fd)
Definition: fd.c:2644
static int elevel
Definition: vacuumlazy.c:403
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
int pg_fsync(int fd)
Definition: fd.c:352

◆ fsync_parent_path()

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

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

3696 {
3697  char parentpath[MAXPGPATH];
3698 
3699  strlcpy(parentpath, fname, MAXPGPATH);
3700  get_parent_directory(parentpath);
3701 
3702  /*
3703  * get_parent_directory() returns an empty string if the input argument is
3704  * just a file name (see comments in path.c), so handle that as being the
3705  * current directory.
3706  */
3707  if (strlen(parentpath) == 0)
3708  strlcpy(parentpath, ".", MAXPGPATH);
3709 
3710  if (fsync_fname_ext(parentpath, true, false, elevel) != 0)
3711  return -1;
3712 
3713  return 0;
3714 }
#define MAXPGPATH
void get_parent_directory(char *path)
Definition: path.c:854
static int elevel
Definition: vacuumlazy.c:403
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:3619

◆ GetNextTempTableSpace()

Oid GetNextTempTableSpace ( void  )

Definition at line 2945 of file fd.c.

References InvalidOid, nextTempTableSpace, numTempTableSpaces, and tempTableSpaces.

Referenced by GetDefaultTablespace(), and OpenTemporaryFile().

2946 {
2947  if (numTempTableSpaces > 0)
2948  {
2949  /* Advance nextTempTableSpace counter with wraparound */
2951  nextTempTableSpace = 0;
2953  }
2954  return InvalidOid;
2955 }
static int numTempTableSpaces
Definition: fd.c:280
static int nextTempTableSpace
Definition: fd.c:281
#define InvalidOid
Definition: postgres_ext.h:36
static Oid * tempTableSpaces
Definition: fd.c:279

◆ GetTempTablespaces()

int GetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 2927 of file fd.c.

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

Referenced by SharedFileSetInit().

2928 {
2929  int i;
2930 
2932  for (i = 0; i < numTempTableSpaces && i < numSpaces; ++i)
2933  tableSpaces[i] = tempTableSpaces[i];
2934 
2935  return i;
2936 }
static int numTempTableSpaces
Definition: fd.c:280
bool TempTablespacesAreSet(void)
Definition: fd.c:2912
#define Assert(condition)
Definition: c.h:804
static Oid * tempTableSpaces
Definition: fd.c:279
int i

◆ InitFileAccess()

void InitFileAccess ( void  )

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

874 {
875  Assert(SizeVfdCache == 0); /* call me only once */
876 
877  /* initialize cache header entry */
878  VfdCache = (Vfd *) malloc(sizeof(Vfd));
879  if (VfdCache == NULL)
880  ereport(FATAL,
881  (errcode(ERRCODE_OUT_OF_MEMORY),
882  errmsg("out of memory")));
883 
884  MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));
886 
887  SizeVfdCache = 1;
888 
889  /* register proc-exit hook to ensure temp files are dropped at exit */
891 }
static void AtProcExit_Files(int code, Datum arg)
Definition: fd.c:3013
static Size SizeVfdCache
Definition: fd.c:213
void on_proc_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:305
static Vfd * VfdCache
Definition: fd.c:212
int errcode(int sqlerrcode)
Definition: elog.c:698
#define MemSet(start, val, len)
Definition: c.h:1008
#define malloc(a)
Definition: header.h:50
#define FATAL
Definition: elog.h:49
Definition: fd.c:192
int fd
Definition: fd.c:194
#define VFD_CLOSED
Definition: fd.c:180
#define ereport(elevel,...)
Definition: elog.h:157
#define Assert(condition)
Definition: c.h:804
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ Insert()

static void Insert ( File  file)
static

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

1267 {
1268  Vfd *vfdP;
1269 
1270  Assert(file != 0);
1271 
1272  DO_DB(elog(LOG, "Insert %d (%s)",
1273  file, VfdCache[file].fileName));
1274  DO_DB(_dump_lru());
1275 
1276  vfdP = &VfdCache[file];
1277 
1278  vfdP->lruMoreRecently = 0;
1280  VfdCache[0].lruLessRecently = file;
1282 
1283  DO_DB(_dump_lru());
1284 }
File lruLessRecently
Definition: fd.c:199
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
Definition: fd.c:192
#define Assert(condition)
Definition: c.h:804
File lruMoreRecently
Definition: fd.c:198
#define elog(elevel,...)
Definition: elog.h:232

◆ looks_like_temp_rel_name()

bool looks_like_temp_rel_name ( const char *  name)

Definition at line 3284 of file fd.c.

References CloseTransientFile(), ereport, errcode_for_file_access(), errmsg(), vfd::fd, forkname_chars(), LOG, and OpenTransientFile().

Referenced by RemovePgTempRelationFilesInDbspace(), and sendDir().

3285 {
3286  int pos;
3287  int savepos;
3288 
3289  /* Must start with "t". */
3290  if (name[0] != 't')
3291  return false;
3292 
3293  /* Followed by a non-empty string of digits and then an underscore. */
3294  for (pos = 1; isdigit((unsigned char) name[pos]); ++pos)
3295  ;
3296  if (pos == 1 || name[pos] != '_')
3297  return false;
3298 
3299  /* Followed by another nonempty string of digits. */
3300  for (savepos = ++pos; isdigit((unsigned char) name[pos]); ++pos)
3301  ;
3302  if (savepos == pos)
3303  return false;
3304 
3305  /* We might have _forkname or .segment or both. */
3306  if (name[pos] == '_')
3307  {
3308  int forkchar = forkname_chars(&name[pos + 1], NULL);
3309 
3310  if (forkchar <= 0)
3311  return false;
3312  pos += forkchar + 1;
3313  }
3314  if (name[pos] == '.')
3315  {
3316  int segchar;
3317 
3318  for (segchar = 1; isdigit((unsigned char) name[pos + segchar]); ++segchar)
3319  ;
3320  if (segchar <= 1)
3321  return false;
3322  pos += segchar;
3323  }
3324 
3325  /* Now we should be at the end. */
3326  if (name[pos] != '\0')
3327  return false;
3328  return true;
3329 }
int forkname_chars(const char *str, ForkNumber *fork)
Definition: relpath.c:81
const char * name
Definition: encode.c:515

◆ LruDelete()

static void LruDelete ( File  file)
static

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

1241 {
1242  Vfd *vfdP;
1243 
1244  Assert(file != 0);
1245 
1246  DO_DB(elog(LOG, "LruDelete %d (%s)",
1247  file, VfdCache[file].fileName));
1248 
1249  vfdP = &VfdCache[file];
1250 
1251  /*
1252  * Close the file. We aren't expecting this to fail; if it does, better
1253  * to leak the FD than to mess up our internal state.
1254  */
1255  if (close(vfdP->fd) != 0)
1257  "could not close file \"%s\": %m", vfdP->fileName);
1258  vfdP->fd = VFD_CLOSED;
1259  --nfile;
1260 
1261  /* delete the vfd record from the LRU ring */
1262  Delete(file);
1263 }
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:190
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
static void Delete(File file)
Definition: fd.c:1221
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:201
static int nfile
Definition: fd.c:218
unsigned short fdstate
Definition: fd.c:195
Definition: fd.c:192
int fd
Definition: fd.c:194
int data_sync_elevel(int elevel)
Definition: fd.c:3758
#define VFD_CLOSED
Definition: fd.c:180
#define Assert(condition)
Definition: c.h:804
#define elog(elevel,...)
Definition: elog.h:232
#define close(a)
Definition: win32.h:12

◆ LruInsert()

static int LruInsert ( File  file)
static

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

1289 {
1290  Vfd *vfdP;
1291 
1292  Assert(file != 0);
1293 
1294  DO_DB(elog(LOG, "LruInsert %d (%s)",
1295  file, VfdCache[file].fileName));
1296 
1297  vfdP = &VfdCache[file];
1298 
1299  if (FileIsNotOpen(file))
1300  {
1301  /* Close excess kernel FDs. */
1302  ReleaseLruFiles();
1303 
1304  /*
1305  * The open could still fail for lack of file descriptors, eg due to
1306  * overall system file table being full. So, be prepared to release
1307  * another FD if necessary...
1308  */
1309  vfdP->fd = BasicOpenFilePerm(vfdP->fileName, vfdP->fileFlags,
1310  vfdP->fileMode);
1311  if (vfdP->fd < 0)
1312  {
1313  DO_DB(elog(LOG, "re-open failed: %m"));
1314  return -1;
1315  }
1316  else
1317  {
1318  ++nfile;
1319  }
1320  }
1321 
1322  /*
1323  * put it at the head of the Lru ring
1324  */
1325 
1326  Insert(file);
1327 
1328  return 0;
1329 }
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
mode_t fileMode
Definition: fd.c:204
char * fileName
Definition: fd.c:201
static int nfile
Definition: fd.c:218
Definition: fd.c:192
int fd
Definition: fd.c:194
static void Insert(File file)
Definition: fd.c:1266
static void ReleaseLruFiles(void)
Definition: fd.c:1357
#define FileIsNotOpen(file)
Definition: fd.c:185
#define Assert(condition)
Definition: c.h:804
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1055
#define elog(elevel,...)
Definition: elog.h:232
int fileFlags
Definition: fd.c:203

◆ MakePGDirectory()

int MakePGDirectory ( const char *  directoryName)

◆ OpenPipeStream()

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

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

2521 {
2522  FILE *file;
2523  int save_errno;
2524 
2525  DO_DB(elog(LOG, "OpenPipeStream: Allocated %d (%s)",
2526  numAllocatedDescs, command));
2527 
2528  /* Can we allocate another non-virtual FD? */
2529  if (!reserveAllocatedDesc())
2530  ereport(ERROR,
2531  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2532  errmsg("exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"",
2533  maxAllocatedDescs, command)));
2534 
2535  /* Close excess kernel FDs. */
2536  ReleaseLruFiles();
2537 
2538 TryAgain:
2539  fflush(stdout);
2540  fflush(stderr);
2542  errno = 0;
2543  file = popen(command, mode);
2544  save_errno = errno;
2546  errno = save_errno;
2547  if (file != NULL)
2548  {
2550 
2551  desc->kind = AllocateDescPipe;
2552  desc->desc.file = file;
2555  return desc->desc.file;
2556  }
2557 
2558  if (errno == EMFILE || errno == ENFILE)
2559  {
2560  ereport(LOG,
2561  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2562  errmsg("out of file descriptors: %m; release and retry")));
2563  if (ReleaseLruFile())
2564  goto TryAgain;
2565  errno = save_errno;
2566  }
2567 
2568  return NULL;
2569 }
static PgChecksumMode mode
Definition: pg_checksums.c:65
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:260
#define DO_DB(A)
Definition: fd.c:176
int errcode(int sqlerrcode)
Definition: elog.c:698
static bool reserveAllocatedDesc(void)
Definition: fd.c:2342
#define SIGPIPE
Definition: win32_port.h:164
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:248
static bool ReleaseLruFile(void)
Definition: fd.c:1335
#define ERROR
Definition: elog.h:46
#define SIG_IGN
Definition: win32_port.h:156
static void ReleaseLruFiles(void)
Definition: fd.c:1357
FILE * file
Definition: fd.c:252
#define ereport(elevel,...)
Definition: elog.h:157
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:170
#define SIG_DFL
Definition: win32_port.h:154
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:723
SubTransactionId create_subid
Definition: fd.c:249
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
static int maxAllocatedDescs
Definition: fd.c:259
static int numAllocatedDescs
Definition: fd.c:258

◆ OpenTemporaryFile()

File OpenTemporaryFile ( bool  interXact)

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

1670 {
1671  File file = 0;
1672 
1673  /*
1674  * Make sure the current resource owner has space for this File before we
1675  * open it, if we'll be registering it below.
1676  */
1677  if (!interXact)
1679 
1680  /*
1681  * If some temp tablespace(s) have been given to us, try to use the next
1682  * one. If a given tablespace can't be found, we silently fall back to
1683  * the database's default tablespace.
1684  *
1685  * BUT: if the temp file is slated to outlive the current transaction,
1686  * force it into the database's default tablespace, so that it will not
1687  * pose a threat to possible tablespace drop attempts.
1688  */
1689  if (numTempTableSpaces > 0 && !interXact)
1690  {
1691  Oid tblspcOid = GetNextTempTableSpace();
1692 
1693  if (OidIsValid(tblspcOid))
1694  file = OpenTemporaryFileInTablespace(tblspcOid, false);
1695  }
1696 
1697  /*
1698  * If not, or if tablespace is bad, create in database's default
1699  * tablespace. MyDatabaseTableSpace should normally be set before we get
1700  * here, but just in case it isn't, fall back to pg_default tablespace.
1701  */
1702  if (file <= 0)
1705  DEFAULTTABLESPACE_OID,
1706  true);
1707 
1708  /* Mark it for deletion at close and temporary file size limit */
1710 
1711  /* Register it with the current resource owner */
1712  if (!interXact)
1713  RegisterTemporaryFile(file);
1714 
1715  return file;
1716 }
static File OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError)
Definition: fd.c:1747
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:190
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
#define FD_DELETE_AT_CLOSE
Definition: fd.c:188
static Vfd * VfdCache
Definition: fd.c:212
static int numTempTableSpaces
Definition: fd.c:280
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
Oid MyDatabaseTableSpace
Definition: globals.c:90
Oid GetNextTempTableSpace(void)
Definition: fd.c:2945
unsigned short fdstate
Definition: fd.c:195
static void RegisterTemporaryFile(File file)
Definition: fd.c:1500
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1286
int File
Definition: fd.h:54

◆ OpenTemporaryFileInTablespace()

static File OpenTemporaryFileInTablespace ( Oid  tblspcOid,
bool  rejectError 
)
static

Definition at line 1747 of file fd.c.

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

Referenced by OpenTemporaryFile().

1748 {
1749  char tempdirpath[MAXPGPATH];
1750  char tempfilepath[MAXPGPATH];
1751  File file;
1752 
1753  TempTablespacePath(tempdirpath, tblspcOid);
1754 
1755  /*
1756  * Generate a tempfile name that should be unique within the current
1757  * database instance.
1758  */
1759  snprintf(tempfilepath, sizeof(tempfilepath), "%s/%s%d.%ld",
1760  tempdirpath, PG_TEMP_FILE_PREFIX, MyProcPid, tempFileCounter++);
1761 
1762  /*
1763  * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1764  * temp file that can be reused.
1765  */
1766  file = PathNameOpenFile(tempfilepath,
1767  O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1768  if (file <= 0)
1769  {
1770  /*
1771  * We might need to create the tablespace's tempfile directory, if no
1772  * one has yet done so.
1773  *
1774  * Don't check for an error from MakePGDirectory; it could fail if
1775  * someone else just did the same thing. If it doesn't work then
1776  * we'll bomb out on the second create attempt, instead.
1777  */
1778  (void) MakePGDirectory(tempdirpath);
1779 
1780  file = PathNameOpenFile(tempfilepath,
1781  O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1782  if (file <= 0 && rejectError)
1783  elog(ERROR, "could not create temporary file \"%s\": %m",
1784  tempfilepath);
1785  }
1786 
1787  return file;
1788 }
int MyProcPid
Definition: globals.c:43
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1528
void TempTablespacePath(char *path, Oid tablespace)
Definition: fd.c:1722
#define PG_BINARY
Definition: c.h:1271
#define ERROR
Definition: elog.h:46
#define PG_TEMP_FILE_PREFIX
Definition: pg_checksums.c:63
#define MAXPGPATH
int MakePGDirectory(const char *directoryName)
Definition: fd.c:3735
static long tempFileCounter
Definition: fd.c:271
#define elog(elevel,...)
Definition: elog.h:232
#define snprintf
Definition: port.h:216
int File
Definition: fd.h:54

◆ OpenTransientFile()

◆ OpenTransientFilePerm()

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

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

2477 {
2478  int fd;
2479 
2480  DO_DB(elog(LOG, "OpenTransientFile: Allocated %d (%s)",
2481  numAllocatedDescs, fileName));
2482 
2483  /* Can we allocate another non-virtual FD? */
2484  if (!reserveAllocatedDesc())
2485  ereport(ERROR,
2486  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2487  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2488  maxAllocatedDescs, fileName)));
2489 
2490  /* Close excess kernel FDs. */
2491  ReleaseLruFiles();
2492 
2493  fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
2494 
2495  if (fd >= 0)
2496  {
2498 
2499  desc->kind = AllocateDescRawFD;
2500  desc->desc.fd = fd;
2503 
2504  return fd;
2505  }
2506 
2507  return -1; /* failure */
2508 }
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:260
#define DO_DB(A)
Definition: fd.c:176
int errcode(int sqlerrcode)
Definition: elog.c:698
static bool reserveAllocatedDesc(void)
Definition: fd.c:2342
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:248
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define ERROR
Definition: elog.h:46
static void ReleaseLruFiles(void)
Definition: fd.c:1357
#define ereport(elevel,...)
Definition: elog.h:157
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:723
SubTransactionId create_subid
Definition: fd.c:249
int fd
Definition: fd.c:254
int errmsg(const char *fmt,...)
Definition: elog.c:909
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1055
#define elog(elevel,...)
Definition: elog.h:232
static int maxAllocatedDescs
Definition: fd.c:259
static int numAllocatedDescs
Definition: fd.c:258

◆ PathNameCreateTemporaryDir()

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

Definition at line 1605 of file fd.c.

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

Referenced by SharedFileSetCreate().

1606 {
1607  if (MakePGDirectory(directory) < 0)
1608  {
1609  if (errno == EEXIST)
1610  return;
1611 
1612  /*
1613  * Failed. Try to create basedir first in case it's missing. Tolerate
1614  * EEXIST to close a race against another process following the same
1615  * algorithm.
1616  */
1617  if (MakePGDirectory(basedir) < 0 && errno != EEXIST)
1618  ereport(ERROR,
1620  errmsg("cannot create temporary directory \"%s\": %m",
1621  basedir)));
1622 
1623  /* Try again. */
1624  if (MakePGDirectory(directory) < 0 && errno != EEXIST)
1625  ereport(ERROR,
1627  errmsg("cannot create temporary subdirectory \"%s\": %m",
1628  directory)));
1629  }
1630 }
static char * basedir
#define ERROR
Definition: elog.h:46
int errcode_for_file_access(void)
Definition: elog.c:721
#define ereport(elevel,...)
Definition: elog.h:157
int MakePGDirectory(const char *directoryName)
Definition: fd.c:3735
static const char * directory
Definition: zic.c:632
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ PathNameCreateTemporaryFile()

File PathNameCreateTemporaryFile ( const char *  path,
bool  error_on_failure 
)

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

1805 {
1806  File file;
1807 
1809 
1810  /*
1811  * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1812  * temp file that can be reused.
1813  */
1814  file = PathNameOpenFile(path, O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1815  if (file <= 0)
1816  {
1817  if (error_on_failure)
1818  ereport(ERROR,
1820  errmsg("could not create temporary file \"%s\": %m",
1821  path)));
1822  else
1823  return file;
1824  }
1825 
1826  /* Mark it for temp_file_limit accounting. */
1828 
1829  /* Register it for automatic close. */
1830  RegisterTemporaryFile(file);
1831 
1832  return file;
1833 }
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1528
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:190
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
static Vfd * VfdCache
Definition: fd.c:212
#define PG_BINARY
Definition: c.h:1271
#define ERROR
Definition: elog.h:46
int errcode_for_file_access(void)
Definition: elog.c:721
unsigned short fdstate
Definition: fd.c:195
#define ereport(elevel,...)
Definition: elog.h:157
static void RegisterTemporaryFile(File file)
Definition: fd.c:1500
int errmsg(const char *fmt,...)
Definition: elog.c:909
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1286
int File
Definition: fd.h:54

◆ PathNameDeleteTemporaryDir()

void PathNameDeleteTemporaryDir ( const char *  dirname)

Definition at line 1636 of file fd.c.

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

Referenced by SharedFileSetDeleteAll().

1637 {
1638  struct stat statbuf;
1639 
1640  /* Silently ignore missing directory. */
1641  if (stat(dirname, &statbuf) != 0 && errno == ENOENT)
1642  return;
1643 
1644  /*
1645  * Currently, walkdir doesn't offer a way for our passed in function to
1646  * maintain state. Perhaps it should, so that we could tell the caller
1647  * whether this operation succeeded or failed. Since this operation is
1648  * used in a cleanup path, we wouldn't actually behave differently: we'll
1649  * just log failures.
1650  */
1651  walkdir(dirname, unlink_if_exists_fname, false, LOG);
1652 }
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
Definition: fd.c:3486
#define LOG
Definition: elog.h:26
static void unlink_if_exists_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3594
#define stat
Definition: win32_port.h:275

◆ PathNameDeleteTemporaryFile()

bool PathNameDeleteTemporaryFile ( const char *  path,
bool  error_on_failure 
)

Definition at line 1871 of file fd.c.

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

Referenced by SharedFileSetDelete(), and unlink_if_exists_fname().

1872 {
1873  struct stat filestats;
1874  int stat_errno;
1875 
1876  /* Get the final size for pgstat reporting. */
1877  if (stat(path, &filestats) != 0)
1878  stat_errno = errno;
1879  else
1880  stat_errno = 0;
1881 
1882  /*
1883  * Unlike FileClose's automatic file deletion code, we tolerate
1884  * non-existence to support BufFileDeleteShared which doesn't know how
1885  * many segments it has to delete until it runs out.
1886  */
1887  if (stat_errno == ENOENT)
1888  return false;
1889 
1890  if (unlink(path) < 0)
1891  {
1892  if (errno != ENOENT)
1893  ereport(error_on_failure ? ERROR : LOG,
1895  errmsg("could not unlink temporary file \"%s\": %m",
1896  path)));
1897  return false;
1898  }
1899 
1900  if (stat_errno == 0)
1901  ReportTemporaryFileUsage(path, filestats.st_size);
1902  else
1903  {
1904  errno = stat_errno;
1905  ereport(LOG,
1907  errmsg("could not stat file \"%s\": %m", path)));
1908  }
1909 
1910  return true;
1911 }
#define LOG
Definition: elog.h:26
#define ERROR
Definition: elog.h:46
int errcode_for_file_access(void)
Definition: elog.c:721
static void ReportTemporaryFileUsage(const char *path, off_t size)
Definition: fd.c:1481
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define stat
Definition: win32_port.h:275

◆ PathNameOpenFile()

File PathNameOpenFile ( const char *  fileName,
int  fileFlags 
)

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

1529 {
1530  return PathNameOpenFilePerm(fileName, fileFlags, pg_file_create_mode);
1531 }
File PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1541
int pg_file_create_mode
Definition: file_perm.c:19

◆ PathNameOpenFilePerm()

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

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

1542 {
1543  char *fnamecopy;
1544  File file;
1545  Vfd *vfdP;
1546 
1547  DO_DB(elog(LOG, "PathNameOpenFilePerm: %s %x %o",
1548  fileName, fileFlags, fileMode));
1549 
1550  /*
1551  * We need a malloc'd copy of the file name; fail cleanly if no room.
1552  */
1553  fnamecopy = strdup(fileName);
1554  if (fnamecopy == NULL)
1555  ereport(ERROR,
1556  (errcode(ERRCODE_OUT_OF_MEMORY),
1557  errmsg("out of memory")));
1558 
1559  file = AllocateVfd();
1560  vfdP = &VfdCache[file];
1561 
1562  /* Close excess kernel FDs. */
1563  ReleaseLruFiles();
1564 
1565  vfdP->fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
1566 
1567  if (vfdP->fd < 0)
1568  {
1569  int save_errno = errno;
1570 
1571  FreeVfd(file);
1572  free(fnamecopy);
1573  errno = save_errno;
1574  return -1;
1575  }
1576  ++nfile;
1577  DO_DB(elog(LOG, "PathNameOpenFile: success %d",
1578  vfdP->fd));
1579 
1580  vfdP->fileName = fnamecopy;
1581  /* Saved flags are adjusted to be OK for re-opening file */
1582  vfdP->fileFlags = fileFlags & ~(O_CREAT | O_TRUNC | O_EXCL);
1583  vfdP->fileMode = fileMode;
1584  vfdP->fileSize = 0;
1585  vfdP->fdstate = 0x0;
1586  vfdP->resowner = NULL;
1587 
1588  Insert(file);
1589 
1590  return file;
1591 }
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
int errcode(int sqlerrcode)
Definition: elog.c:698
#define LOG
Definition: elog.h:26
mode_t fileMode
Definition: fd.c:204
#define ERROR
Definition: elog.h:46
char * fileName
Definition: fd.c:201
static int nfile
Definition: fd.c:218
static File AllocateVfd(void)
Definition: fd.c:1367
unsigned short fdstate
Definition: fd.c:195
Definition: fd.c:192
off_t fileSize
Definition: fd.c:200
int fd
Definition: fd.c:194
static void Insert(File file)
Definition: fd.c:1266
ResourceOwner resowner
Definition: fd.c:196
static void ReleaseLruFiles(void)
Definition: fd.c:1357
#define ereport(elevel,...)
Definition: elog.h:157
#define free(a)
Definition: header.h:65
int errmsg(const char *fmt,...)
Definition: elog.c:909
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1055
#define elog(elevel,...)
Definition: elog.h:232
static void FreeVfd(File file)
Definition: fd.c:1425
int fileFlags
Definition: fd.c:203
int File
Definition: fd.h:54

◆ PathNameOpenTemporaryFile()

File PathNameOpenTemporaryFile ( const char *  path,
int  mode 
)

Definition at line 1842 of file fd.c.

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

Referenced by SharedFileSetOpen().

1843 {
1844  File file;
1845 
1847 
1848  file = PathNameOpenFile(path, mode | PG_BINARY);
1849 
1850  /* If no such file, then we don't raise an error. */
1851  if (file <= 0 && errno != ENOENT)
1852  ereport(ERROR,
1854  errmsg("could not open temporary file \"%s\": %m",
1855  path)));
1856 
1857  if (file > 0)
1858  {
1859  /* Register it for automatic close. */
1860  RegisterTemporaryFile(file);
1861  }
1862 
1863  return file;
1864 }
static PgChecksumMode mode
Definition: pg_checksums.c:65
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1528
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
#define PG_BINARY
Definition: c.h:1271
#define ERROR
Definition: elog.h:46
int errcode_for_file_access(void)
Definition: elog.c:721
#define ereport(elevel,...)
Definition: elog.h:157
static void RegisterTemporaryFile(File file)
Definition: fd.c:1500
int errmsg(const char *fmt,...)
Definition: elog.c:909
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1286
int File
Definition: fd.h:54

◆ pg_fdatasync()

int pg_fdatasync ( int  fd)

Definition at line 442 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync().

443 {
444  if (enableFsync)
445  {
446 #ifdef HAVE_FDATASYNC
447  return fdatasync(fd);
448 #else
449  return fsync(fd);
450 #endif
451  }
452  else
453  return 0;
454 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define fsync(fd)
Definition: win32_port.h:68
bool enableFsync
Definition: globals.c:122

◆ pg_flush_data()

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

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

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

◆ pg_fsync()

int pg_fsync ( int  fd)

Definition at line 352 of file fd.c.

References Assert, fstat, pg_fsync_no_writethrough(), pg_fsync_writethrough(), S_ISDIR, stat::st_mode, 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 XLogFileInitInternal().

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

◆ pg_fsync_no_writethrough()

int pg_fsync_no_writethrough ( int  fd)

Definition at line 407 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync(), and pg_fsync().

408 {
409  if (enableFsync)
410  return fsync(fd);
411  else
412  return 0;
413 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define fsync(fd)
Definition: win32_port.h:68
bool enableFsync
Definition: globals.c:122

◆ pg_fsync_writethrough()

int pg_fsync_writethrough ( int  fd)

Definition at line 419 of file fd.c.

References enableFsync.

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

420 {
421  if (enableFsync)
422  {
423 #ifdef WIN32
424  return _commit(fd);
425 #elif defined(F_FULLFSYNC)
426  return (fcntl(fd, F_FULLFSYNC, 0) == -1) ? -1 : 0;
427 #else
428  errno = ENOSYS;
429  return -1;
430 #endif
431  }
432  else
433  return 0;
434 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
bool enableFsync
Definition: globals.c:122

◆ pg_pwritev_with_retry()

ssize_t pg_pwritev_with_retry ( int  fd,
const struct iovec iov,
int  iovcnt,
off_t  offset 
)

Definition at line 3768 of file fd.c.

References Assert, iovec::iov_base, iovec::iov_len, Min, and pg_pwritev().

Referenced by XLogFileInitInternal().

3769 {
3770  struct iovec iov_copy[PG_IOV_MAX];
3771  ssize_t sum = 0;
3772  ssize_t part;
3773 
3774  /* We'd better have space to make a copy, in case we need to retry. */
3775  if (iovcnt > PG_IOV_MAX)
3776  {
3777  errno = EINVAL;
3778  return -1;
3779  }
3780 
3781  for (;;)
3782  {
3783  /* Write as much as we can. */
3784  part = pg_pwritev(fd, iov, iovcnt, offset);
3785  if (part < 0)
3786  return -1;
3787 
3788 #ifdef SIMULATE_SHORT_WRITE
3789  part = Min(part, 4096);
3790 #endif
3791 
3792  /* Count our progress. */
3793  sum += part;
3794  offset += part;
3795 
3796  /* Step over iovecs that are done. */
3797  while (iovcnt > 0 && iov->iov_len <= part)
3798  {
3799  part -= iov->iov_len;
3800  ++iov;
3801  --iovcnt;
3802  }
3803 
3804  /* Are they all done? */
3805  if (iovcnt == 0)
3806  {
3807  /* We don't expect the kernel to write more than requested. */
3808  Assert(part == 0);
3809  break;
3810  }
3811 
3812  /*
3813  * Move whatever's left to the front of our mutable copy and adjust
3814  * the leading iovec.
3815  */
3816  Assert(iovcnt > 0);
3817  memmove(iov_copy, iov, sizeof(*iov) * iovcnt);
3818  Assert(iov->iov_len > part);
3819  iov_copy[0].iov_base = (char *) iov_copy[0].iov_base + part;
3820  iov_copy[0].iov_len -= part;
3821  iov = iov_copy;
3822  }
3823 
3824  return sum;
3825 }
size_t iov_len
Definition: pg_iovec.h:27
void * iov_base
Definition: pg_iovec.h:26
#define Min(x, y)
Definition: c.h:986
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ssize_t pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
Definition: pwritev.c:29
#define PG_IOV_MAX
Definition: pg_iovec.h:40
Definition: pg_iovec.h:24
#define Assert(condition)
Definition: c.h:804

◆ pg_truncate()

int pg_truncate ( const char *  path,
off_t  length 
)

Definition at line 635 of file fd.c.

References CloseTransientFile(), vfd::fd, ftruncate, OpenTransientFile(), and PG_BINARY.

Referenced by do_truncate().

636 {
637 #ifdef WIN32
638  int save_errno;
639  int ret;
640  int fd;
641 
642  fd = OpenTransientFile(path, O_RDWR | PG_BINARY);
643  if (fd >= 0)
644  {
645  ret = ftruncate(fd, 0);
646  save_errno = errno;
647  CloseTransientFile(fd);
648  errno = save_errno;
649  }
650  else
651  ret = -1;
652 
653  return ret;
654 #else
655  return truncate(path, length);
656 #endif
657 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1271
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2467
int CloseTransientFile(int fd)
Definition: fd.c:2644
#define ftruncate(a, b)
Definition: win32_port.h:65

◆ ReadDir()

◆ ReadDirExtended()

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

Definition at line 2759 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(), SyncDataDirectory(), and walkdir().

2760 {
2761  struct dirent *dent;
2762 
2763  /* Give a generic message for AllocateDir failure, if caller didn't */
2764  if (dir == NULL)
2765  {
2766  ereport(elevel,
2768  errmsg("could not open directory \"%s\": %m",
2769  dirname)));
2770  return NULL;
2771  }
2772 
2773  errno = 0;
2774  if ((dent = readdir(dir)) != NULL)
2775  return dent;
2776 
2777  if (errno)
2778  ereport(elevel,
2780  errmsg("could not read directory \"%s\": %m",
2781  dirname)));
2782  return NULL;
2783 }
Definition: dirent.h:9
int errcode_for_file_access(void)
Definition: elog.c:721
static int elevel
Definition: vacuumlazy.c:403
#define ereport(elevel,...)
Definition: elog.h:157
struct dirent * readdir(DIR *)
Definition: dirent.c:78
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ RegisterTemporaryFile()

static void RegisterTemporaryFile ( File  file)
static

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

1501 {
1504 
1505  /* Backup mechanism for closing at end of xact. */
1508 }
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
static Vfd * VfdCache
Definition: fd.c:212
static bool have_xact_temporary_files
Definition: fd.c:224
void ResourceOwnerRememberFile(ResourceOwner owner, File file)
Definition: resowner.c:1297
unsigned short fdstate
Definition: fd.c:195
ResourceOwner resowner
Definition: fd.c:196
#define FD_CLOSE_AT_EOXACT
Definition: fd.c:189

◆ ReleaseExternalFD()

◆ ReleaseLruFile()

static bool ReleaseLruFile ( void  )
static

Definition at line 1335 of file fd.c.

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

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

1336 {
1337  DO_DB(elog(LOG, "ReleaseLruFile. Opened %d", nfile));
1338 
1339  if (nfile > 0)
1340  {
1341  /*
1342  * There are opened files and so there should be at least one used vfd
1343  * in the ring.
1344  */
1345  Assert(VfdCache[0].lruMoreRecently != 0);
1346  LruDelete(VfdCache[0].lruMoreRecently);
1347  return true; /* freed a file */
1348  }
1349  return false; /* no files available to free */
1350 }
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
static void LruDelete(File file)
Definition: fd.c:1240
static int nfile
Definition: fd.c:218
#define Assert(condition)
Definition: c.h:804
#define elog(elevel,...)
Definition: elog.h:232

◆ ReleaseLruFiles()

static void ReleaseLruFiles ( void  )
static

Definition at line 1357 of file fd.c.

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

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

1358 {
1360  {
1361  if (!ReleaseLruFile())
1362  break;
1363  }
1364 }
static int numExternalFDs
Definition: fd.c:265
int max_safe_fds
Definition: fd.c:158
static bool ReleaseLruFile(void)
Definition: fd.c:1335
static int nfile
Definition: fd.c:218
static int numAllocatedDescs
Definition: fd.c:258

◆ RemovePgTempFiles()

void RemovePgTempFiles ( void  )

Definition at line 3103 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(), and PostmasterStateMachine().

3104 {
3105  char temp_path[MAXPGPATH + 10 + sizeof(TABLESPACE_VERSION_DIRECTORY) + sizeof(PG_TEMP_FILES_DIR)];
3106  DIR *spc_dir;
3107  struct dirent *spc_de;
3108 
3109  /*
3110  * First process temp files in pg_default ($PGDATA/base)
3111  */
3112  snprintf(temp_path, sizeof(temp_path), "base/%s", PG_TEMP_FILES_DIR);
3113  RemovePgTempFilesInDir(temp_path, true, false);
3114  RemovePgTempRelationFiles("base");
3115 
3116  /*
3117  * Cycle through temp directories for all non-default tablespaces.
3118  */
3119  spc_dir = AllocateDir("pg_tblspc");
3120 
3121  while ((spc_de = ReadDirExtended(spc_dir, "pg_tblspc", LOG)) != NULL)
3122  {
3123  if (strcmp(spc_de->d_name, ".") == 0 ||
3124  strcmp(spc_de->d_name, "..") == 0)
3125  continue;
3126 
3127  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s/%s",
3129  RemovePgTempFilesInDir(temp_path, true, false);
3130 
3131  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s",
3133  RemovePgTempRelationFiles(temp_path);
3134  }
3135 
3136  FreeDir(spc_dir);
3137 
3138  /*
3139  * In EXEC_BACKEND case there is a pgsql_tmp directory at the top level of
3140  * DataDir as well. However, that is *not* cleaned here because doing so
3141  * would create a race condition. It's done separately, earlier in
3142  * postmaster startup.
3143  */
3144 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2759
#define PG_TEMP_FILES_DIR
Definition: pg_checksums.c:62
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
static void RemovePgTempRelationFiles(const char *tsdirname)
Definition: fd.c:3228
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:3162
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2678
char d_name[MAX_PATH]
Definition: dirent.h:15
#define snprintf
Definition: port.h:216
int FreeDir(DIR *dir)
Definition: fd.c:2796

◆ RemovePgTempFilesInDir()

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

Definition at line 3162 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::st_mode.

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

3163 {
3164  DIR *temp_dir;
3165  struct dirent *temp_de;
3166  char rm_path[MAXPGPATH * 2];
3167 
3168  temp_dir = AllocateDir(tmpdirname);
3169 
3170  if (temp_dir == NULL && errno == ENOENT && missing_ok)
3171  return;
3172 
3173  while ((temp_de = ReadDirExtended(temp_dir, tmpdirname, LOG)) != NULL)
3174  {
3175  if (strcmp(temp_de->d_name, ".") == 0 ||
3176  strcmp(temp_de->d_name, "..") == 0)
3177  continue;
3178 
3179  snprintf(rm_path, sizeof(rm_path), "%s/%s",
3180  tmpdirname, temp_de->d_name);
3181 
3182  if (unlink_all ||
3183  strncmp(temp_de->d_name,
3185  strlen(PG_TEMP_FILE_PREFIX)) == 0)
3186  {
3187  struct stat statbuf;
3188 
3189  if (lstat(rm_path, &statbuf) < 0)
3190  {
3191  ereport(LOG,
3193  errmsg("could not stat file \"%s\": %m", rm_path)));
3194  continue;
3195  }
3196 
3197  if (S_ISDIR(statbuf.st_mode))
3198  {
3199  /* recursively remove contents, then directory itself */
3200  RemovePgTempFilesInDir(rm_path, false, true);
3201 
3202  if (rmdir(rm_path) < 0)
3203  ereport(LOG,
3205  errmsg("could not remove directory \"%s\": %m",
3206  rm_path)));
3207  }
3208  else
3209  {
3210  if (unlink(rm_path) < 0)
3211  ereport(LOG,
3213  errmsg("could not remove file \"%s\": %m",
3214  rm_path)));
3215  }
3216  }
3217  else
3218  ereport(LOG,
3219  (errmsg("unexpected file found in temporary-files directory: \"%s\"",
3220  rm_path)));
3221  }
3222 
3223  FreeDir(temp_dir);
3224 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2759
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
Definition: dirent.c:25
#define PG_TEMP_FILE_PREFIX
Definition: pg_checksums.c:63
#define MAXPGPATH
void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok, bool unlink_all)
Definition: fd.c:3162
int errcode_for_file_access(void)
Definition: elog.c:721
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2678
#define ereport(elevel,...)
Definition: elog.h:157
#define S_ISDIR(m)
Definition: win32_port.h:316
#define lstat(path, sb)
Definition: win32_port.h:276
int errmsg(const char *fmt,...)
Definition: elog.c:909
char d_name[MAX_PATH]
Definition: dirent.h:15
#define snprintf
Definition: port.h:216
int FreeDir(DIR *dir)
Definition: fd.c:2796

◆ RemovePgTempRelationFiles()

static void RemovePgTempRelationFiles ( const char *  tsdirname)
static

Definition at line 3228 of file fd.c.

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

Referenced by RemovePgTempFiles().

3229 {
3230  DIR *ts_dir;
3231  struct dirent *de;
3232  char dbspace_path[MAXPGPATH * 2];
3233 
3234  ts_dir = AllocateDir(tsdirname);
3235 
3236  while ((de = ReadDirExtended(ts_dir, tsdirname, LOG)) != NULL)
3237  {
3238  /*
3239  * We're only interested in the per-database directories, which have
3240  * numeric names. Note that this code will also (properly) ignore "."
3241  * and "..".
3242  */
3243  if (strspn(de->d_name, "0123456789") != strlen(de->d_name))
3244  continue;
3245 
3246  snprintf(dbspace_path, sizeof(dbspace_path), "%s/%s",
3247  tsdirname, de->d_name);
3248  RemovePgTempRelationFilesInDbspace(dbspace_path);
3249  }
3250 
3251  FreeDir(ts_dir);
3252 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2759
static void RemovePgTempRelationFilesInDbspace(const char *dbspacedirname)
Definition: fd.c:3256
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2678
char d_name[MAX_PATH]
Definition: dirent.h:15
#define snprintf
Definition: port.h:216
int FreeDir(DIR *dir)
Definition: fd.c:2796

◆ RemovePgTempRelationFilesInDbspace()

static void RemovePgTempRelationFilesInDbspace ( const char *  dbspacedirname)
static

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

3257 {
3258  DIR *dbspace_dir;
3259  struct dirent *de;
3260  char rm_path[MAXPGPATH * 2];
3261 
3262  dbspace_dir = AllocateDir(dbspacedirname);
3263 
3264  while ((de = ReadDirExtended(dbspace_dir, dbspacedirname, LOG)) != NULL)
3265  {
3266  if (!looks_like_temp_rel_name(de->d_name))
3267  continue;
3268 
3269  snprintf(rm_path, sizeof(rm_path), "%s/%s",
3270  dbspacedirname, de->d_name);
3271 
3272  if (unlink(rm_path) < 0)
3273  ereport(LOG,
3275  errmsg("could not remove file \"%s\": %m",
3276  rm_path)));
3277  }
3278 
3279  FreeDir(dbspace_dir);
3280 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2759
#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:721
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2678
#define ereport(elevel,...)
Definition: elog.h:157
bool looks_like_temp_rel_name(const char *name)
Definition: fd.c:3284
int errmsg(const char *fmt,...)
Definition: elog.c:909
char d_name[MAX_PATH]
Definition: dirent.h:15
#define snprintf
Definition: port.h:216
int FreeDir(DIR *dir)
Definition: fd.c:2796

◆ ReportTemporaryFileUsage()

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

Definition at line 1481 of file fd.c.

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

Referenced by FileClose(), and PathNameDeleteTemporaryFile().

1482 {
1483  pgstat_report_tempfile(size);
1484 
1485  if (log_temp_files >= 0)
1486  {
1487  if ((size / 1024) >= log_temp_files)
1488  ereport(LOG,
1489  (errmsg("temporary file: path \"%s\", size %lu",
1490  path, (unsigned long) size)));
1491  }
1492 }
int log_temp_files
Definition: guc.c:602
void pgstat_report_tempfile(size_t filesize)
Definition: pgstat.c:1788
#define LOG
Definition: elog.h:26
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ reserveAllocatedDesc()

static bool reserveAllocatedDesc ( void  )
static

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

2343 {
2344  AllocateDesc *newDescs;
2345  int newMax;
2346 
2347  /* Quick out if array already has a free slot. */
2349  return true;
2350 
2351  /*
2352  * If the array hasn't yet been created in the current process, initialize
2353  * it with FD_MINFREE / 3 elements. In many scenarios this is as many as
2354  * we will ever need, anyway. We don't want to look at max_safe_fds
2355  * immediately because set_max_safe_fds() may not have run yet.
2356  */
2357  if (allocatedDescs == NULL)
2358  {
2359  newMax = FD_MINFREE / 3;
2360  newDescs = (AllocateDesc *) malloc(newMax * sizeof(AllocateDesc));
2361  /* Out of memory already? Treat as fatal error. */
2362  if (newDescs == NULL)
2363  ereport(ERROR,
2364  (errcode(ERRCODE_OUT_OF_MEMORY),
2365  errmsg("out of memory")));
2366  allocatedDescs = newDescs;
2367  maxAllocatedDescs = newMax;
2368  return true;
2369  }
2370 
2371  /*
2372  * Consider enlarging the array beyond the initial allocation used above.
2373  * By the time this happens, max_safe_fds should be known accurately.
2374  *
2375  * We mustn't let allocated descriptors hog all the available FDs, and in
2376  * practice we'd better leave a reasonable number of FDs for VFD use. So
2377  * set the maximum to max_safe_fds / 3. (This should certainly be at
2378  * least as large as the initial size, FD_MINFREE / 3, so we aren't
2379  * tightening the restriction here.) Recall that "external" FDs are
2380  * allowed to consume another third of max_safe_fds.
2381  */
2382  newMax = max_safe_fds / 3;
2383  if (newMax > maxAllocatedDescs)
2384  {
2385  newDescs = (AllocateDesc *) realloc(allocatedDescs,
2386  newMax * sizeof(AllocateDesc));
2387  /* Treat out-of-memory as a non-fatal error. */
2388  if (newDescs == NULL)
2389  return false;
2390  allocatedDescs = newDescs;
2391  maxAllocatedDescs = newMax;
2392  return true;
2393  }
2394 
2395  /* Can't enlarge allocatedDescs[] any more. */
2396  return false;
2397 }
static AllocateDesc * allocatedDescs
Definition: fd.c:260
int max_safe_fds
Definition: fd.c:158
int errcode(int sqlerrcode)
Definition: elog.c:698
#define malloc(a)
Definition: header.h:50
#define ERROR
Definition: elog.h:46
#define ereport(elevel,...)
Definition: elog.h:157
#define FD_MINFREE
Definition: fd.c:137
#define realloc(a, b)
Definition: header.h:60
int errmsg(const char *fmt,...)
Definition: elog.c:909
static int maxAllocatedDescs
Definition: fd.c:259
static int numAllocatedDescs
Definition: fd.c:258

◆ ReserveExternalFD()

void ReserveExternalFD ( void  )

Definition at line 1174 of file fd.c.

References numExternalFDs, and ReleaseLruFiles().

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

1175 {
1176  /*
1177  * Release VFDs if needed to stay safe. Because we do this before
1178  * incrementing numExternalFDs, the final state will be as desired, i.e.,
1179  * nfile + numAllocatedDescs + numExternalFDs <= max_safe_fds.
1180  */
1181  ReleaseLruFiles();
1182 
1183  numExternalFDs++;
1184 }
static int numExternalFDs
Definition: fd.c:265
static void ReleaseLruFiles(void)
Definition: fd.c:1357

◆ set_max_safe_fds()

void set_max_safe_fds ( void  )

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

991 {
992  int usable_fds;
993  int already_open;
994 
995  /*----------
996  * We want to set max_safe_fds to
997  * MIN(usable_fds, max_files_per_process - already_open)
998  * less the slop factor for files that are opened without consulting
999  * fd.c. This ensures that we won't exceed either max_files_per_process
1000  * or the experimentally-determined EMFILE limit.
1001  *----------
1002  */
1004  &usable_fds, &already_open);
1005 
1006  max_safe_fds = Min(usable_fds, max_files_per_process - already_open);
1007 
1008  /*
1009  * Take off the FDs reserved for system() etc.
1010  */
1012 
1013  /*
1014  * Make sure we still have enough to get by.
1015  */
1016  if (max_safe_fds < FD_MINFREE)
1017  ereport(FATAL,
1018  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
1019  errmsg("insufficient file descriptors available to start server process"),
1020  errdetail("System allows %d, we need at least %d.",
1023 
1024  elog(DEBUG2, "max_safe_fds = %d, usable_fds = %d, already_open = %d",
1025  max_safe_fds, usable_fds, already_open);
1026 }
static void count_usable_fds(int max_to_probe, int *usable_fds, int *already_open)
Definition: fd.c:906
#define NUM_RESERVED_FDS
Definition: fd.c:128
int max_safe_fds
Definition: fd.c:158
#define Min(x, y)
Definition: c.h:986
int errcode(int sqlerrcode)
Definition: elog.c:698
#define FATAL
Definition: elog.h:49
#define DEBUG2
Definition: elog.h:24
int errdetail(const char *fmt,...)
Definition: elog.c:1042
int max_files_per_process
Definition: fd.c:145
#define ereport(elevel,...)
Definition: elog.h:157
#define FD_MINFREE
Definition: fd.c:137
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232

◆ SetTempTablespaces()

void SetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 2884 of file fd.c.

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

Referenced by assign_temp_tablespaces(), and PrepareTempTablespaces().

2885 {
2886  Assert(numSpaces >= 0);
2887  tempTableSpaces = tableSpaces;
2888  numTempTableSpaces = numSpaces;
2889 
2890  /*
2891  * Select a random starting point in the list. This is to minimize
2892  * conflicts between backends that are most likely sharing the same list
2893  * of temp tablespaces. Note that if we create multiple temp files in the
2894  * same transaction, we'll advance circularly through the list --- this
2895  * ensures that large temporary sort files are nicely spread across all
2896  * available tablespaces.
2897  */
2898  if (numSpaces > 1)
2899  nextTempTableSpace = random() % numSpaces;
2900  else
2901  nextTempTableSpace = 0;
2902 }
long random(void)
Definition: random.c:22
static int numTempTableSpaces
Definition: fd.c:280
static int nextTempTableSpace
Definition: fd.c:281
#define Assert(condition)
Definition: c.h:804
static Oid * tempTableSpaces
Definition: fd.c:279

◆ SyncDataDirectory()

void SyncDataDirectory ( void  )

Definition at line 3376 of file fd.c.

References AllocateDir(), dirent::d_name, datadir_fsync_fname(), DEBUG1, enableFsync, ereport, errcode_for_file_access(), errmsg(), FreeDir(), LOG, lstat, MAXPGPATH, pgwin32_is_junction(), ReadDirExtended(), recovery_init_sync_method, RECOVERY_INIT_SYNC_METHOD_SYNCFS, snprintf, stat::st_mode, and walkdir().

Referenced by StartupXLOG().

3377 {
3378  bool xlog_is_symlink;
3379 
3380  /* We can skip this whole thing if fsync is disabled. */
3381  if (!enableFsync)
3382  return;
3383 
3384  /*
3385  * If pg_wal is a symlink, we'll need to recurse into it separately,
3386  * because the first walkdir below will ignore it.
3387  */
3388  xlog_is_symlink = false;
3389 
3390 #ifndef WIN32
3391  {
3392  struct stat st;
3393 
3394  if (lstat("pg_wal", &st) < 0)
3395  ereport(LOG,
3397  errmsg("could not stat file \"%s\": %m",
3398  "pg_wal")));
3399  else if (S_ISLNK(st.st_mode))
3400  xlog_is_symlink = true;
3401  }
3402 #else
3403  if (pgwin32_is_junction("pg_wal"))
3404  xlog_is_symlink = true;
3405 #endif
3406 
3407 #ifdef HAVE_SYNCFS
3409  {
3410  DIR *dir;
3411  struct dirent *de;
3412 
3413  /*
3414  * On Linux, we don't have to open every single file one by one. We
3415  * can use syncfs() to sync whole filesystems. We only expect
3416  * filesystem boundaries to exist where we tolerate symlinks, namely
3417  * pg_wal and the tablespaces, so we call syncfs() for each of those
3418  * directories.
3419  */
3420 
3421  /* Sync the top level pgdata directory. */
3422  do_syncfs(".");
3423  /* If any tablespaces are configured, sync each of those. */
3424  dir = AllocateDir("pg_tblspc");
3425  while ((de = ReadDirExtended(dir, "pg_tblspc", LOG)))
3426  {
3427  char path[MAXPGPATH];
3428 
3429  if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
3430  continue;
3431 
3432  snprintf(path, MAXPGPATH, "pg_tblspc/%s", de->d_name);
3433  do_syncfs(path);
3434  }
3435  FreeDir(dir);
3436  /* If pg_wal is a symlink, process that too. */
3437  if (xlog_is_symlink)
3438  do_syncfs("pg_wal");
3439  return;
3440  }
3441 #endif /* !HAVE_SYNCFS */
3442 
3443  /*
3444  * If possible, hint to the kernel that we're soon going to fsync the data
3445  * directory and its contents. Errors in this step are even less
3446  * interesting than normal, so log them only at DEBUG1.
3447  */
3448 #ifdef PG_FLUSH_DATA_WORKS
3449  walkdir(".", pre_sync_fname, false, DEBUG1);
3450  if (xlog_is_symlink)
3451  walkdir("pg_wal", pre_sync_fname, false, DEBUG1);
3452  walkdir("pg_tblspc", pre_sync_fname, true, DEBUG1);
3453 #endif
3454 
3455  /*
3456  * Now we do the fsync()s in the same order.
3457  *
3458  * The main call ignores symlinks, so in addition to specially processing
3459  * pg_wal if it's a symlink, pg_tblspc has to be visited separately with
3460  * process_symlinks = true. Note that if there are any plain directories
3461  * in pg_tblspc, they'll get fsync'd twice. That's not an expected case
3462  * so we don't worry about optimizing it.
3463  */
3464  walkdir(".", datadir_fsync_fname, false, LOG);
3465  if (xlog_is_symlink)
3466  walkdir("pg_wal", datadir_fsync_fname, false, LOG);
3467  walkdir("pg_tblspc", datadir_fsync_fname, true, LOG);
3468 }
#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:3486
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2759
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
Definition: dirent.c:25
int recovery_init_sync_method
Definition: fd.c:164
#define MAXPGPATH
int errcode_for_file_access(void)
Definition: elog.c:721
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2678
static void datadir_fsync_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3584
#define ereport(elevel,...)
Definition: elog.h:157
#define lstat(path, sb)
Definition: win32_port.h:276
bool enableFsync
Definition: globals.c:122
int errmsg(const char *fmt,...)
Definition: elog.c:909
char d_name[MAX_PATH]
Definition: dirent.h:15
#define snprintf
Definition: port.h:216
int FreeDir(DIR *dir)
Definition: fd.c:2796
bool pgwin32_is_junction(const char *path)

◆ TempTablespacePath()

void TempTablespacePath ( char *  path,
Oid  tablespace 
)

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

1723 {
1724  /*
1725  * Identify the tempfile directory for this tablespace.
1726  *
1727  * If someone tries to specify pg_global, use pg_default instead.
1728  */
1729  if (tablespace == InvalidOid ||
1730  tablespace == DEFAULTTABLESPACE_OID ||
1731  tablespace == GLOBALTABLESPACE_OID)
1732  snprintf(path, MAXPGPATH, "base/%s", PG_TEMP_FILES_DIR);
1733  else
1734  {
1735  /* All other tablespaces are accessed via symlinks */
1736  snprintf(path, MAXPGPATH, "pg_tblspc/%u/%s/%s",
1739  }
1740 }
#define PG_TEMP_FILES_DIR
Definition: pg_checksums.c:62
#define MAXPGPATH
#define TABLESPACE_VERSION_DIRECTORY
Definition: relpath.h:26
char * tablespace
Definition: pgbench.c:226
#define InvalidOid
Definition: postgres_ext.h:36
#define snprintf
Definition: port.h:216

◆ TempTablespacesAreSet()

bool TempTablespacesAreSet ( void  )

Definition at line 2912 of file fd.c.

References numTempTableSpaces.

Referenced by GetTempTablespaces(), and PrepareTempTablespaces().

2913 {
2914  return (numTempTableSpaces >= 0);
2915 }
static int numTempTableSpaces
Definition: fd.c:280

◆ unlink_if_exists_fname()

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

Definition at line 3594 of file fd.c.

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

Referenced by PathNameDeleteTemporaryDir().

3595 {
3596  if (isdir)
3597  {
3598  if (rmdir(fname) != 0 && errno != ENOENT)
3599  ereport(elevel,
3601  errmsg("could not remove directory \"%s\": %m", fname)));
3602  }
3603  else
3604  {
3605  /* Use PathNameDeleteTemporaryFile to report filesize */
3606  PathNameDeleteTemporaryFile(fname, false);
3607  }
3608 }
bool PathNameDeleteTemporaryFile(const char *path, bool error_on_failure)
Definition: fd.c:1871
int errcode_for_file_access(void)
Definition: elog.c:721
static int elevel
Definition: vacuumlazy.c:403
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ 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 3486 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().

3490 {
3491  DIR *dir;
3492  struct dirent *de;
3493 
3494  dir = AllocateDir(path);
3495 
3496  while ((de = ReadDirExtended(dir, path, elevel)) != NULL)
3497  {
3498  char subpath[MAXPGPATH * 2];
3499 
3501 
3502  if (strcmp(de->d_name, ".") == 0 ||
3503  strcmp(de->d_name, "..") == 0)
3504  continue;
3505 
3506  snprintf(subpath, sizeof(subpath), "%s/%s", path, de->d_name);
3507 
3508  switch (get_dirent_type(subpath, de, process_symlinks, elevel))
3509  {
3510  case PGFILETYPE_REG:
3511  (*action) (subpath, false, elevel);
3512  break;
3513  case PGFILETYPE_DIR:
3514  walkdir(subpath, action, false, elevel);
3515  break;
3516  default:
3517 
3518  /*
3519  * Errors are already reported directly by get_dirent_type(),
3520  * and any remaining symlinks and unknown file types are
3521  * ignored.
3522  */
3523  break;
3524  }
3525  }
3526 
3527  FreeDir(dir); /* we ignore any error here */
3528 
3529  /*
3530  * It's important to fsync the destination directory itself as individual
3531  * file fsyncs don't guarantee that the directory entry for the file is
3532  * synced. However, skip this if AllocateDir failed; the action function
3533  * might not be robust against that.
3534  */
3535  if (dir)
3536  (*action) (path, true, elevel);
3537 }
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
Definition: fd.c:3486
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2759
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2678
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:403
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:120
char d_name[MAX_PATH]
Definition: dirent.h:15
#define snprintf
Definition: port.h:216
int FreeDir(DIR *dir)
Definition: fd.c:2796
Datum subpath(PG_FUNCTION_ARGS)
Definition: ltree_op.c:241

Variable Documentation

◆ allocatedDescs

AllocateDesc* allocatedDescs = NULL
static

Definition at line 260 of file fd.c.

◆ data_sync_retry

bool data_sync_retry = false

Definition at line 161 of file fd.c.

Referenced by data_sync_elevel().

◆ have_xact_temporary_files

bool have_xact_temporary_files = false
static

Definition at line 224 of file fd.c.

Referenced by CleanupTempFiles(), and RegisterTemporaryFile().

◆ max_files_per_process

int max_files_per_process = 1000

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

Referenced by GetNextTempTableSpace(), and SetTempTablespaces().

◆ nfile

int nfile = 0
static

◆ numAllocatedDescs

◆ numExternalFDs

int numExternalFDs = 0
static

Definition at line 265 of file fd.c.

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

◆ numTempTableSpaces

int numTempTableSpaces = -1
static

◆ recovery_init_sync_method

int recovery_init_sync_method = RECOVERY_INIT_SYNC_METHOD_FSYNC

Definition at line 164 of file fd.c.

Referenced by SyncDataDirectory().

◆ SizeVfdCache

Size SizeVfdCache = 0
static

Definition at line 213 of file fd.c.

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

◆ tempFileCounter

long tempFileCounter = 0
static

Definition at line 271 of file fd.c.

Referenced by OpenTemporaryFileInTablespace().

◆ temporary_files_size

uint64 temporary_files_size = 0
static

Definition at line 232 of file fd.c.

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

◆ tempTableSpaces

Oid* tempTableSpaces = NULL
static

◆ VfdCache

Vfd* VfdCache
static

Definition at line 212 of file fd.c.