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

Go to the source code of this file.

Data Structures

struct  vfd
 
struct  AllocateDesc
 

Macros

#define NUM_RESERVED_FDS   10
 
#define FD_MINFREE   10
 
#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 RemovePgTempFilesInDir (const char *tmpdirname, bool missing_ok, bool unlink_all)
 
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_fname_ext (const char *fname, bool isdir, bool ignore_perm, int elevel)
 
static int fsync_parent_path (const char *fname, int elevel)
 
int pg_fsync (int fd)
 
int pg_fsync_no_writethrough (int fd)
 
int pg_fsync_writethrough (int fd)
 
int pg_fdatasync (int fd)
 
void pg_flush_data (int fd, off_t offset, off_t nbytes)
 
void fsync_fname (const char *fname, bool isdir)
 
int durable_rename (const char *oldfile, const char *newfile, int elevel)
 
int durable_unlink (const char *fname, int elevel)
 
int durable_link_or_rename (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)
 
static void ReportTemporaryFileUsage (const char *path, off_t size)
 
static void RegisterTemporaryFile (File file)
 
File PathNameOpenFile (const char *fileName, int fileFlags)
 
File PathNameOpenFilePerm (const char *fileName, int fileFlags, mode_t fileMode)
 
void PathNameCreateTemporaryDir (const char *basedir, const char *directory)
 
void PathNameDeleteTemporaryDir (const char *dirname)
 
File OpenTemporaryFile (bool interXact)
 
void TempTablespacePath (char *path, Oid tablespace)
 
File PathNameCreateTemporaryFile (const char *path, bool error_on_failure)
 
File PathNameOpenTemporaryFile (const char *path)
 
bool PathNameDeleteTemporaryFile (const char *path, bool error_on_failure)
 
void FileClose (File file)
 
int FilePrefetch (File file, off_t offset, int amount, uint32 wait_event_info)
 
void FileWriteback (File file, off_t offset, off_t nbytes, uint32 wait_event_info)
 
int FileRead (File file, char *buffer, int amount, off_t offset, uint32 wait_event_info)
 
int FileWrite (File file, char *buffer, int amount, off_t offset, uint32 wait_event_info)
 
int FileSync (File file, uint32 wait_event_info)
 
off_t FileSize (File file)
 
int FileTruncate (File file, off_t offset, uint32 wait_event_info)
 
char * FilePathName (File file)
 
int FileGetRawDesc (File file)
 
int FileGetRawFlags (File file)
 
mode_t FileGetRawMode (File file)
 
FILE * AllocateFile (const char *name, const char *mode)
 
int OpenTransientFile (const char *fileName, int fileFlags)
 
int OpenTransientFilePerm (const char *fileName, int fileFlags, mode_t fileMode)
 
FILE * OpenPipeStream (const char *command, const char *mode)
 
int FreeFile (FILE *file)
 
int CloseTransientFile (int fd)
 
DIRAllocateDir (const char *dirname)
 
struct direntReadDir (DIR *dir, const char *dirname)
 
struct direntReadDirExtended (DIR *dir, const char *dirname, int elevel)
 
int FreeDir (DIR *dir)
 
int ClosePipeStream (FILE *file)
 
void closeAllVfds (void)
 
void SetTempTablespaces (Oid *tableSpaces, int numSpaces)
 
bool TempTablespacesAreSet (void)
 
int GetTempTablespaces (Oid *tableSpaces, int numSpaces)
 
Oid GetNextTempTableSpace (void)
 
void AtEOSubXact_Files (bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
 
void AtEOXact_Files (bool isCommit)
 
void RemovePgTempFiles (void)
 
bool looks_like_temp_rel_name (const char *name)
 
void SyncDataDirectory (void)
 
int MakePGDirectory (const char *directoryName)
 
int data_sync_elevel (int elevel)
 

Variables

int max_files_per_process = 1000
 
int max_safe_fds = 32
 
bool data_sync_retry = false
 
static VfdVfdCache
 
static Size SizeVfdCache = 0
 
static int nfile = 0
 
static bool have_xact_temporary_files = false
 
static uint64 temporary_files_size = 0
 
static int numAllocatedDescs = 0
 
static int maxAllocatedDescs = 0
 
static AllocateDescallocatedDescs = NULL
 
static 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 174 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 173 of file fd.c.

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

◆ FD_MINFREE

#define FD_MINFREE   10

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

Referenced by set_max_safe_fds().

◆ VFD_CLOSED

#define VFD_CLOSED   (-1)

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

Function Documentation

◆ AllocateDir()

DIR* AllocateDir ( const char *  dirname)

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

2469 {
2470  DIR *dir;
2471 
2472  DO_DB(elog(LOG, "AllocateDir: Allocated %d (%s)",
2473  numAllocatedDescs, dirname));
2474 
2475  /* Can we allocate another non-virtual FD? */
2476  if (!reserveAllocatedDesc())
2477  ereport(ERROR,
2478  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2479  errmsg("exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"",
2480  maxAllocatedDescs, dirname)));
2481 
2482  /* Close excess kernel FDs. */
2483  ReleaseLruFiles();
2484 
2485 TryAgain:
2486  if ((dir = opendir(dirname)) != NULL)
2487  {
2489 
2490  desc->kind = AllocateDescDir;
2491  desc->desc.dir = dir;
2494  return desc->desc.dir;
2495  }
2496 
2497  if (errno == EMFILE || errno == ENFILE)
2498  {
2499  int save_errno = errno;
2500 
2501  ereport(LOG,
2502  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2503  errmsg("out of file descriptors: %m; release and retry")));
2504  errno = 0;
2505  if (ReleaseLruFile())
2506  goto TryAgain;
2507  errno = save_errno;
2508  }
2509 
2510  return NULL;
2511 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
union AllocateDesc::@26 desc
DIR * dir
Definition: fd.c:238
#define DO_DB(A)
Definition: fd.c:161
int errcode(int sqlerrcode)
Definition: elog.c:570
static bool reserveAllocatedDesc(void)
Definition: fd.c:2134
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static bool ReleaseLruFile(void)
Definition: fd.c:1130
Definition: dirent.c:25
#define ERROR
Definition: elog.h:43
DIR * opendir(const char *)
Definition: dirent.c:33
#define ereport(elevel, rest)
Definition: elog.h:141
static void ReleaseLruFiles(void)
Definition: fd.c:1152
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:708
SubTransactionId create_subid
Definition: fd.c:234
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
static int maxAllocatedDescs
Definition: fd.c:244
static int numAllocatedDescs
Definition: fd.c:243

◆ AllocateFile()

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

Definition at line 2207 of file fd.c.

References AllocateDescFile, AllocateDesc::create_subid, AllocateDesc::desc, DO_DB, elog, ereport, errcode(), errmsg(), ERROR, AllocateDesc::file, GetCurrentSubTransactionId(), AllocateDesc::kind, LOG, maxAllocatedDescs, numAllocatedDescs, ReleaseLruFile(), ReleaseLruFiles(), and reserveAllocatedDesc().

Referenced by _ShowOption(), AlterSystemSetConfigFile(), apw_dump_now(), apw_load_buffers(), BackendRun(), BeginCopyFrom(), BeginCopyTo(), checkControlFile(), do_pg_start_backup(), do_pg_stop_backup(), entry_reset(), existsTimeLineHistory(), ExportSnapshot(), fill_hba_view(), gc_qtexts(), ImportSnapshot(), load_dh_file(), load_hba(), load_ident(), load_relcache_init_file(), parse_extension_control_file(), ParseTzFile(), perform_base_backup(), pg_backup_start_time(), pg_current_logfile(), pg_file_write_internal(), pg_promote(), PGSharedMemoryAttach(), pgss_shmem_shutdown(), pgss_shmem_startup(), pgstat_read_db_statsfile(), pgstat_read_db_statsfile_timestamp(), pgstat_read_statsfiles(), pgstat_write_db_statsfile(), pgstat_write_statsfiles(), PostmasterMarkPIDForWorkerNotify(), read_backup_label(), read_binary_file(), read_tablespace_map(), read_whole_file(), readTimeLineHistory(), sendFile(), tokenize_inc_file(), tsearch_readline_begin(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

2208 {
2209  FILE *file;
2210 
2211  DO_DB(elog(LOG, "AllocateFile: Allocated %d (%s)",
2213 
2214  /* Can we allocate another non-virtual FD? */
2215  if (!reserveAllocatedDesc())
2216  ereport(ERROR,
2217  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2218  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2219  maxAllocatedDescs, name)));
2220 
2221  /* Close excess kernel FDs. */
2222  ReleaseLruFiles();
2223 
2224 TryAgain:
2225  if ((file = fopen(name, mode)) != NULL)
2226  {
2228 
2229  desc->kind = AllocateDescFile;
2230  desc->desc.file = file;
2233  return desc->desc.file;
2234  }
2235 
2236  if (errno == EMFILE || errno == ENFILE)
2237  {
2238  int save_errno = errno;
2239 
2240  ereport(LOG,
2241  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2242  errmsg("out of file descriptors: %m; release and retry")));
2243  errno = 0;
2244  if (ReleaseLruFile())
2245  goto TryAgain;
2246  errno = save_errno;
2247  }
2248 
2249  return NULL;
2250 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
static AllocateDesc * allocatedDescs
Definition: fd.c:245
union AllocateDesc::@26 desc
#define DO_DB(A)
Definition: fd.c:161
int errcode(int sqlerrcode)
Definition: elog.c:570
static bool reserveAllocatedDesc(void)
Definition: fd.c:2134
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static bool ReleaseLruFile(void)
Definition: fd.c:1130
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
static void ReleaseLruFiles(void)
Definition: fd.c:1152
FILE * file
Definition: fd.c:237
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:708
SubTransactionId create_subid
Definition: fd.c:234
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
static int maxAllocatedDescs
Definition: fd.c:244
static int numAllocatedDescs
Definition: fd.c:243

◆ AllocateVfd()

static File AllocateVfd ( void  )
static

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

1163 {
1164  Index i;
1165  File file;
1166 
1167  DO_DB(elog(LOG, "AllocateVfd. Size %zu", SizeVfdCache));
1168 
1169  Assert(SizeVfdCache > 0); /* InitFileAccess not called? */
1170 
1171  if (VfdCache[0].nextFree == 0)
1172  {
1173  /*
1174  * The free list is empty so it is time to increase the size of the
1175  * array. We choose to double it each time this happens. However,
1176  * there's not much point in starting *real* small.
1177  */
1178  Size newCacheSize = SizeVfdCache * 2;
1179  Vfd *newVfdCache;
1180 
1181  if (newCacheSize < 32)
1182  newCacheSize = 32;
1183 
1184  /*
1185  * Be careful not to clobber VfdCache ptr if realloc fails.
1186  */
1187  newVfdCache = (Vfd *) realloc(VfdCache, sizeof(Vfd) * newCacheSize);
1188  if (newVfdCache == NULL)
1189  ereport(ERROR,
1190  (errcode(ERRCODE_OUT_OF_MEMORY),
1191  errmsg("out of memory")));
1192  VfdCache = newVfdCache;
1193 
1194  /*
1195  * Initialize the new entries and link them into the free list.
1196  */
1197  for (i = SizeVfdCache; i < newCacheSize; i++)
1198  {
1199  MemSet((char *) &(VfdCache[i]), 0, sizeof(Vfd));
1200  VfdCache[i].nextFree = i + 1;
1201  VfdCache[i].fd = VFD_CLOSED;
1202  }
1203  VfdCache[newCacheSize - 1].nextFree = 0;
1205 
1206  /*
1207  * Record the new size
1208  */
1209  SizeVfdCache = newCacheSize;
1210  }
1211 
1212  file = VfdCache[0].nextFree;
1213 
1214  VfdCache[0].nextFree = VfdCache[file].nextFree;
1215 
1216  return file;
1217 }
File nextFree
Definition: fd.c:182
static Size SizeVfdCache
Definition: fd.c:198
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
int errcode(int sqlerrcode)
Definition: elog.c:570
#define MemSet(start, val, len)
Definition: c.h:955
#define LOG
Definition: elog.h:26
#define ERROR
Definition: elog.h:43
Definition: fd.c:177
int fd
Definition: fd.c:179
#define ereport(elevel, rest)
Definition: elog.h:141
unsigned int Index
Definition: c.h:475
#define VFD_CLOSED
Definition: fd.c:165
#define Assert(condition)
Definition: c.h:732
size_t Size
Definition: c.h:466
#define realloc(a, b)
Definition: header.h:60
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
int i
int File
Definition: fd.h:45

◆ AtEOSubXact_Files()

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

Definition at line 2750 of file fd.c.

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

2752 {
2753  Index i;
2754 
2755  for (i = 0; i < numAllocatedDescs; i++)
2756  {
2757  if (allocatedDescs[i].create_subid == mySubid)
2758  {
2759  if (isCommit)
2760  allocatedDescs[i].create_subid = parentSubid;
2761  else
2762  {
2763  /* have to recheck the item after FreeDesc (ugly) */
2764  FreeDesc(&allocatedDescs[i--]);
2765  }
2766  }
2767  }
2768 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2367
unsigned int Index
Definition: c.h:475
SubTransactionId create_subid
Definition: fd.c:234
int i
static int numAllocatedDescs
Definition: fd.c:243

◆ AtEOXact_Files()

void AtEOXact_Files ( bool  isCommit)

Definition at line 2783 of file fd.c.

References CleanupTempFiles(), numTempTableSpaces, and tempTableSpaces.

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

2784 {
2785  CleanupTempFiles(isCommit, false);
2786  tempTableSpaces = NULL;
2787  numTempTableSpaces = -1;
2788 }
static int numTempTableSpaces
Definition: fd.c:258
static Oid * tempTableSpaces
Definition: fd.c:257
static void CleanupTempFiles(bool isCommit, bool isProcExit)
Definition: fd.c:2815

◆ AtProcExit_Files()

static void AtProcExit_Files ( int  code,
Datum  arg 
)
static

Definition at line 2797 of file fd.c.

References CleanupTempFiles().

Referenced by InitFileAccess().

2798 {
2799  CleanupTempFiles(false, true);
2800 }
static void CleanupTempFiles(bool isCommit, bool isProcExit)
Definition: fd.c:2815

◆ BasicOpenFile()

int BasicOpenFile ( const char *  fileName,
int  fileFlags 
)

Definition at line 946 of file fd.c.

References BasicOpenFilePerm(), and pg_file_create_mode.

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

947 {
948  return BasicOpenFilePerm(fileName, fileFlags, pg_file_create_mode);
949 }
int pg_file_create_mode
Definition: file_perm.c:19
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:968

◆ BasicOpenFilePerm()

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

Definition at line 968 of file fd.c.

References buf, elog, ereport, errcode(), errmsg(), vfd::fd, LOG, vfd::lruLessRecently, ReleaseLruFile(), and snprintf.

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

969 {
970  int fd;
971 
972 tryAgain:
973  fd = open(fileName, fileFlags, fileMode);
974 
975  if (fd >= 0)
976  return fd; /* success! */
977 
978  if (errno == EMFILE || errno == ENFILE)
979  {
980  int save_errno = errno;
981 
982  ereport(LOG,
983  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
984  errmsg("out of file descriptors: %m; release and retry")));
985  errno = 0;
986  if (ReleaseLruFile())
987  goto tryAgain;
988  errno = save_errno;
989  }
990 
991  return -1; /* failure */
992 }
int errcode(int sqlerrcode)
Definition: elog.c:570
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static bool ReleaseLruFile(void)
Definition: fd.c:1130
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ CleanupTempFiles()

static void CleanupTempFiles ( bool  isCommit,
bool  isProcExit 
)
static

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

2816 {
2817  Index i;
2818 
2819  /*
2820  * Careful here: at proc_exit we need extra cleanup, not just
2821  * xact_temporary files.
2822  */
2823  if (isProcExit || have_xact_temporary_files)
2824  {
2825  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2826  for (i = 1; i < SizeVfdCache; i++)
2827  {
2828  unsigned short fdstate = VfdCache[i].fdstate;
2829 
2830  if (((fdstate & FD_DELETE_AT_CLOSE) || (fdstate & FD_CLOSE_AT_EOXACT)) &&
2831  VfdCache[i].fileName != NULL)
2832  {
2833  /*
2834  * If we're in the process of exiting a backend process, close
2835  * all temporary files. Otherwise, only close temporary files
2836  * local to the current transaction. They should be closed by
2837  * the ResourceOwner mechanism already, so this is just a
2838  * debugging cross-check.
2839  */
2840  if (isProcExit)
2841  FileClose(i);
2842  else if (fdstate & FD_CLOSE_AT_EOXACT)
2843  {
2844  elog(WARNING,
2845  "temporary file %s not closed at end-of-transaction",
2846  VfdCache[i].fileName);
2847  FileClose(i);
2848  }
2849  }
2850  }
2851 
2852  have_xact_temporary_files = false;
2853  }
2854 
2855  /* Complain if any allocated files remain open at commit. */
2856  if (isCommit && numAllocatedDescs > 0)
2857  elog(WARNING, "%d temporary files and directories not closed at end-of-transaction",
2859 
2860  /* Clean up "allocated" stdio files, dirs and fds. */
2861  while (numAllocatedDescs > 0)
2862  FreeDesc(&allocatedDescs[0]);
2863 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
static Size SizeVfdCache
Definition: fd.c:198
#define FD_DELETE_AT_CLOSE
Definition: fd.c:173
static Vfd * VfdCache
Definition: fd.c:197
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2367
static bool have_xact_temporary_files
Definition: fd.c:209
unsigned short fdstate
Definition: fd.c:180
#define WARNING
Definition: elog.h:40
#define FileIsNotOpen(file)
Definition: fd.c:170
unsigned int Index
Definition: c.h:475
void FileClose(File file)
Definition: fd.c:1713
#define Assert(condition)
Definition: c.h:732
#define elog(elevel,...)
Definition: elog.h:226
int i
#define FD_CLOSE_AT_EOXACT
Definition: fd.c:174
static int numAllocatedDescs
Definition: fd.c:243

◆ closeAllVfds()

void closeAllVfds ( void  )

Definition at line 2645 of file fd.c.

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

Referenced by standard_ProcessUtility().

2646 {
2647  Index i;
2648 
2649  if (SizeVfdCache > 0)
2650  {
2651  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2652  for (i = 1; i < SizeVfdCache; i++)
2653  {
2654  if (!FileIsNotOpen(i))
2655  LruDelete(i);
2656  }
2657  }
2658 }
static Size SizeVfdCache
Definition: fd.c:198
static void LruDelete(File file)
Definition: fd.c:1035
#define FileIsNotOpen(file)
Definition: fd.c:170
unsigned int Index
Definition: c.h:475
#define Assert(condition)
Definition: c.h:732
int i

◆ ClosePipeStream()

int ClosePipeStream ( FILE *  file)

Definition at line 2616 of file fd.c.

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

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

2617 {
2618  int i;
2619 
2620  DO_DB(elog(LOG, "ClosePipeStream: 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 == AllocateDescPipe && 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 ClosePipeStream was not obtained from OpenPipeStream");
2633 
2634  return pclose(file);
2635 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
union AllocateDesc::@26 desc
#define DO_DB(A)
Definition: fd.c:161
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2367
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:237
#define elog(elevel,...)
Definition: elog.h:226
int i
static int numAllocatedDescs
Definition: fd.c:243

◆ CloseTransientFile()

int CloseTransientFile ( int  fd)

Definition at line 2434 of file fd.c.

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

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

2435 {
2436  int i;
2437 
2438  DO_DB(elog(LOG, "CloseTransientFile: Allocated %d", numAllocatedDescs));
2439 
2440  /* Remove fd from list of allocated files, if it's present */
2441  for (i = numAllocatedDescs; --i >= 0;)
2442  {
2443  AllocateDesc *desc = &allocatedDescs[i];
2444 
2445  if (desc->kind == AllocateDescRawFD && desc->desc.fd == fd)
2446  return FreeDesc(desc);
2447  }
2448 
2449  /* Only get here if someone passes us a file not in allocatedDescs */
2450  elog(WARNING, "fd passed to CloseTransientFile was not obtained from OpenTransientFile");
2451 
2452  return close(fd);
2453 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
union AllocateDesc::@26 desc
#define DO_DB(A)
Definition: fd.c:161
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2367
#define WARNING
Definition: elog.h:40
int fd
Definition: fd.c:239
#define elog(elevel,...)
Definition: elog.h:226
int i
#define close(a)
Definition: win32.h:12
static int numAllocatedDescs
Definition: fd.c:243

◆ count_usable_fds()

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

Definition at line 819 of file fd.c.

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

Referenced by set_max_safe_fds().

820 {
821  int *fd;
822  int size;
823  int used = 0;
824  int highestfd = 0;
825  int j;
826 
827 #ifdef HAVE_GETRLIMIT
828  struct rlimit rlim;
829  int getrlimit_status;
830 #endif
831 
832  size = 1024;
833  fd = (int *) palloc(size * sizeof(int));
834 
835 #ifdef HAVE_GETRLIMIT
836 #ifdef RLIMIT_NOFILE /* most platforms use RLIMIT_NOFILE */
837  getrlimit_status = getrlimit(RLIMIT_NOFILE, &rlim);
838 #else /* but BSD doesn't ... */
839  getrlimit_status = getrlimit(RLIMIT_OFILE, &rlim);
840 #endif /* RLIMIT_NOFILE */
841  if (getrlimit_status != 0)
842  ereport(WARNING, (errmsg("getrlimit failed: %m")));
843 #endif /* HAVE_GETRLIMIT */
844 
845  /* dup until failure or probe limit reached */
846  for (;;)
847  {
848  int thisfd;
849 
850 #ifdef HAVE_GETRLIMIT
851 
852  /*
853  * don't go beyond RLIMIT_NOFILE; causes irritating kernel logs on
854  * some platforms
855  */
856  if (getrlimit_status == 0 && highestfd >= rlim.rlim_cur - 1)
857  break;
858 #endif
859 
860  thisfd = dup(0);
861  if (thisfd < 0)
862  {
863  /* Expect EMFILE or ENFILE, else it's fishy */
864  if (errno != EMFILE && errno != ENFILE)
865  elog(WARNING, "dup(0) failed after %d successes: %m", used);
866  break;
867  }
868 
869  if (used >= size)
870  {
871  size *= 2;
872  fd = (int *) repalloc(fd, size * sizeof(int));
873  }
874  fd[used++] = thisfd;
875 
876  if (highestfd < thisfd)
877  highestfd = thisfd;
878 
879  if (used >= max_to_probe)
880  break;
881  }
882 
883  /* release the files we opened */
884  for (j = 0; j < used; j++)
885  close(fd[j]);
886 
887  pfree(fd);
888 
889  /*
890  * Return results. usable_fds is just the number of successful dups. We
891  * assume that the system limit is highestfd+1 (remember 0 is a legal FD
892  * number) and so already_open is highestfd+1 - usable_fds.
893  */
894  *usable_fds = used;
895  *already_open = highestfd + 1 - used;
896 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
void pfree(void *pointer)
Definition: mcxt.c:1031
#define ereport(elevel, rest)
Definition: elog.h:141
#define WARNING
Definition: elog.h:40
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1044
void * palloc(Size size)
Definition: mcxt.c:924
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
#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 3311 of file fd.c.

References fsync_fname_ext().

Referenced by SyncDataDirectory().

3312 {
3313  /*
3314  * We want to silently ignoring errors about unreadable files. Pass that
3315  * desire on to fsync_fname_ext().
3316  */
3317  fsync_fname_ext(fname, isdir, true, elevel);
3318 }
static int elevel
Definition: vacuumlazy.c:143
static int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3346

◆ Delete()

static void Delete ( File  file)
static

Definition at line 1016 of file fd.c.

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

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

1017 {
1018  Vfd *vfdP;
1019 
1020  Assert(file != 0);
1021 
1022  DO_DB(elog(LOG, "Delete %d (%s)",
1023  file, VfdCache[file].fileName));
1024  DO_DB(_dump_lru());
1025 
1026  vfdP = &VfdCache[file];
1027 
1030 
1031  DO_DB(_dump_lru());
1032 }
File lruLessRecently
Definition: fd.c:184
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
Definition: fd.c:177
#define Assert(condition)
Definition: c.h:732
File lruMoreRecently
Definition: fd.c:183
#define elog(elevel,...)
Definition: elog.h:226

◆ durable_link_or_rename()

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

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

735 {
736  /*
737  * Ensure that, if we crash directly after the rename/link, a file with
738  * valid contents is moved into place.
739  */
740  if (fsync_fname_ext(oldfile, false, false, elevel) != 0)
741  return -1;
742 
743 #if HAVE_WORKING_LINK
744  if (link(oldfile, newfile) < 0)
745  {
746  ereport(elevel,
748  errmsg("could not link file \"%s\" to \"%s\": %m",
749  oldfile, newfile)));
750  return -1;
751  }
752  unlink(oldfile);
753 #else
754  /* XXX: Add racy file existence check? */
755  if (rename(oldfile, newfile) < 0)
756  {
757  ereport(elevel,
759  errmsg("could not rename file \"%s\" to \"%s\": %m",
760  oldfile, newfile)));
761  return -1;
762  }
763 #endif
764 
765  /*
766  * Make change persistent in case of an OS crash, both the new entry and
767  * its parent directory need to be flushed.
768  */
769  if (fsync_fname_ext(newfile, false, false, elevel) != 0)
770  return -1;
771 
772  /* Same for parent directory */
773  if (fsync_parent_path(newfile, elevel) != 0)
774  return -1;
775 
776  return 0;
777 }
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
int link(const char *fromname, const char *toname)
static int elevel
Definition: vacuumlazy.c:143
int errmsg(const char *fmt,...)
Definition: elog.c:784
static int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3346
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3422

◆ durable_rename()

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

Definition at line 608 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(), CancelBackup(), CheckPointReplicationOrigin(), dir_close(), KeepFileRestoredFromArchive(), pgarch_archiveDone(), pgss_shmem_shutdown(), StartupXLOG(), and XLogArchiveForceDone().

609 {
610  int fd;
611 
612  /*
613  * First fsync the old and target path (if it exists), to ensure that they
614  * are properly persistent on disk. Syncing the target file is not
615  * strictly necessary, but it makes it easier to reason about crashes;
616  * because it's then guaranteed that either source or target file exists
617  * after a crash.
618  */
619  if (fsync_fname_ext(oldfile, false, false, elevel) != 0)
620  return -1;
621 
622  fd = OpenTransientFile(newfile, PG_BINARY | O_RDWR);
623  if (fd < 0)
624  {
625  if (errno != ENOENT)
626  {
627  ereport(elevel,
629  errmsg("could not open file \"%s\": %m", newfile)));
630  return -1;
631  }
632  }
633  else
634  {
635  if (pg_fsync(fd) != 0)
636  {
637  int save_errno;
638 
639  /* close file upon error, might not be in transaction context */
640  save_errno = errno;
641  CloseTransientFile(fd);
642  errno = save_errno;
643 
644  ereport(elevel,
646  errmsg("could not fsync file \"%s\": %m", newfile)));
647  return -1;
648  }
649 
650  if (CloseTransientFile(fd) != 0)
651  {
652  ereport(elevel,
654  errmsg("could not close file \"%s\": %m", newfile)));
655  return -1;
656  }
657  }
658 
659  /* Time to do the real deal... */
660  if (rename(oldfile, newfile) < 0)
661  {
662  ereport(elevel,
664  errmsg("could not rename file \"%s\" to \"%s\": %m",
665  oldfile, newfile)));
666  return -1;
667  }
668 
669  /*
670  * To guarantee renaming the file is persistent, fsync the file with its
671  * new name, and its containing directory.
672  */
673  if (fsync_fname_ext(newfile, false, false, elevel) != 0)
674  return -1;
675 
676  if (fsync_parent_path(newfile, elevel) != 0)
677  return -1;
678 
679  return 0;
680 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1191
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2257
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
int CloseTransientFile(int fd)
Definition: fd.c:2434
static int elevel
Definition: vacuumlazy.c:143
int errmsg(const char *fmt,...)
Definition: elog.c:784
static int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3346
int pg_fsync(int fd)
Definition: fd.c:333
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3422

◆ durable_unlink()

int durable_unlink ( const char *  fname,
int  elevel 
)

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

699 {
700  if (unlink(fname) < 0)
701  {
702  ereport(elevel,
704  errmsg("could not remove file \"%s\": %m",
705  fname)));
706  return -1;
707  }
708 
709  /*
710  * To guarantee that the removal of the file is persistent, fsync its
711  * parent directory.
712  */
713  if (fsync_parent_path(fname, elevel) != 0)
714  return -1;
715 
716  return 0;
717 }
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
static int elevel
Definition: vacuumlazy.c:143
int errmsg(const char *fmt,...)
Definition: elog.c:784
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3422

◆ FileAccess()

static int FileAccess ( File  file)
static

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

1241 {
1242  int returnValue;
1243 
1244  DO_DB(elog(LOG, "FileAccess %d (%s)",
1245  file, VfdCache[file].fileName));
1246 
1247  /*
1248  * Is the file open? If not, open it and put it at the head of the LRU
1249  * ring (possibly closing the least recently used file to get an FD).
1250  */
1251 
1252  if (FileIsNotOpen(file))
1253  {
1254  returnValue = LruInsert(file);
1255  if (returnValue != 0)
1256  return returnValue;
1257  }
1258  else if (VfdCache[0].lruLessRecently != file)
1259  {
1260  /*
1261  * We now know that the file is open and that it is not the last one
1262  * accessed, so we need to move it to the head of the Lru ring.
1263  */
1264 
1265  Delete(file);
1266  Insert(file);
1267  }
1268 
1269  return 0;
1270 }
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
static void Delete(File file)
Definition: fd.c:1016
#define LOG
Definition: elog.h:26
static int LruInsert(File file)
Definition: fd.c:1083
static void Insert(File file)
Definition: fd.c:1061
#define FileIsNotOpen(file)
Definition: fd.c:170
#define elog(elevel,...)
Definition: elog.h:226

◆ FileClose()

void FileClose ( File  file)

Definition at line 1713 of file fd.c.

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

Referenced by BufFileClose(), CleanupTempFiles(), logical_end_heap_rewrite(), mdclose(), mdtruncate(), and ResourceOwnerReleaseInternal().

1714 {
1715  Vfd *vfdP;
1716 
1717  Assert(FileIsValid(file));
1718 
1719  DO_DB(elog(LOG, "FileClose: %d (%s)",
1720  file, VfdCache[file].fileName));
1721 
1722  vfdP = &VfdCache[file];
1723 
1724  if (!FileIsNotOpen(file))
1725  {
1726  /* close the file */
1727  if (close(vfdP->fd) != 0)
1728  {
1729  /*
1730  * We may need to panic on failure to close non-temporary files;
1731  * see LruDelete.
1732  */
1734  "could not close file \"%s\": %m", vfdP->fileName);
1735  }
1736 
1737  --nfile;
1738  vfdP->fd = VFD_CLOSED;
1739 
1740  /* remove the file from the lru ring */
1741  Delete(file);
1742  }
1743 
1744  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
1745  {
1746  /* Subtract its size from current usage (do first in case of error) */
1747  temporary_files_size -= vfdP->fileSize;
1748  vfdP->fileSize = 0;
1749  }
1750 
1751  /*
1752  * Delete the file if it was temporary, and make a log entry if wanted
1753  */
1754  if (vfdP->fdstate & FD_DELETE_AT_CLOSE)
1755  {
1756  struct stat filestats;
1757  int stat_errno;
1758 
1759  /*
1760  * If we get an error, as could happen within the ereport/elog calls,
1761  * we'll come right back here during transaction abort. Reset the
1762  * flag to ensure that we can't get into an infinite loop. This code
1763  * is arranged to ensure that the worst-case consequence is failing to
1764  * emit log message(s), not failing to attempt the unlink.
1765  */
1766  vfdP->fdstate &= ~FD_DELETE_AT_CLOSE;
1767 
1768 
1769  /* first try the stat() */
1770  if (stat(vfdP->fileName, &filestats))
1771  stat_errno = errno;
1772  else
1773  stat_errno = 0;
1774 
1775  /* in any case do the unlink */
1776  if (unlink(vfdP->fileName))
1777  elog(LOG, "could not unlink file \"%s\": %m", vfdP->fileName);
1778 
1779  /* and last report the stat results */
1780  if (stat_errno == 0)
1781  ReportTemporaryFileUsage(vfdP->fileName, filestats.st_size);
1782  else
1783  {
1784  errno = stat_errno;
1785  elog(LOG, "could not stat file \"%s\": %m", vfdP->fileName);
1786  }
1787  }
1788 
1789  /* Unregister it from the resource owner */
1790  if (vfdP->resowner)
1791  ResourceOwnerForgetFile(vfdP->resowner, file);
1792 
1793  /*
1794  * Return the Vfd slot to the free list
1795  */
1796  FreeVfd(file);
1797 }
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:175
#define DO_DB(A)
Definition: fd.c:161
#define FD_DELETE_AT_CLOSE
Definition: fd.c:173
static Vfd * VfdCache
Definition: fd.c:197
static void Delete(File file)
Definition: fd.c:1016
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:186
static int nfile
Definition: fd.c:203
unsigned short fdstate
Definition: fd.c:180
Definition: fd.c:177
off_t fileSize
Definition: fd.c:185
int fd
Definition: fd.c:179
ResourceOwner resowner
Definition: fd.c:181
static void ReportTemporaryFileUsage(const char *path, off_t size)
Definition: fd.c:1276
#define stat(a, b)
Definition: win32_port.h:264
#define FileIsNotOpen(file)
Definition: fd.c:170
int data_sync_elevel(int elevel)
Definition: fd.c:3485
#define FileIsValid(file)
Definition: fd.c:167
#define VFD_CLOSED
Definition: fd.c:165
static uint64 temporary_files_size
Definition: fd.c:217
#define Assert(condition)
Definition: c.h:732
#define elog(elevel,...)
Definition: elog.h:226
static void FreeVfd(File file)
Definition: fd.c:1220
#define close(a)
Definition: win32.h:12
void ResourceOwnerForgetFile(ResourceOwner owner, File file)
Definition: resowner.c:1253

◆ FileGetRawDesc()

int FileGetRawDesc ( File  file)

Definition at line 2103 of file fd.c.

References Assert, vfd::fd, and FileIsValid.

2104 {
2105  Assert(FileIsValid(file));
2106  return VfdCache[file].fd;
2107 }
static Vfd * VfdCache
Definition: fd.c:197
int fd
Definition: fd.c:179
#define FileIsValid(file)
Definition: fd.c:167
#define Assert(condition)
Definition: c.h:732

◆ FileGetRawFlags()

int FileGetRawFlags ( File  file)

Definition at line 2113 of file fd.c.

References Assert, vfd::fileFlags, and FileIsValid.

2114 {
2115  Assert(FileIsValid(file));
2116  return VfdCache[file].fileFlags;
2117 }
static Vfd * VfdCache
Definition: fd.c:197
#define FileIsValid(file)
Definition: fd.c:167
#define Assert(condition)
Definition: c.h:732
int fileFlags
Definition: fd.c:188

◆ FileGetRawMode()

mode_t FileGetRawMode ( File  file)

Definition at line 2123 of file fd.c.

References Assert, FileIsValid, and vfd::fileMode.

2124 {
2125  Assert(FileIsValid(file));
2126  return VfdCache[file].fileMode;
2127 }
static Vfd * VfdCache
Definition: fd.c:197
mode_t fileMode
Definition: fd.c:189
#define FileIsValid(file)
Definition: fd.c:167
#define Assert(condition)
Definition: c.h:732

◆ FilePathName()

char* FilePathName ( File  file)

Definition at line 2087 of file fd.c.

References Assert, FileIsValid, and vfd::fileName.

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

2088 {
2089  Assert(FileIsValid(file));
2090 
2091  return VfdCache[file].fileName;
2092 }
static Vfd * VfdCache
Definition: fd.c:197
char * fileName
Definition: fd.c:186
#define FileIsValid(file)
Definition: fd.c:167
#define Assert(condition)
Definition: c.h:732

◆ FilePrefetch()

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

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

1810 {
1811 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
1812  int returnCode;
1813 
1814  Assert(FileIsValid(file));
1815 
1816  DO_DB(elog(LOG, "FilePrefetch: %d (%s) " INT64_FORMAT " %d",
1817  file, VfdCache[file].fileName,
1818  (int64) offset, amount));
1819 
1820  returnCode = FileAccess(file);
1821  if (returnCode < 0)
1822  return returnCode;
1823 
1824  pgstat_report_wait_start(wait_event_info);
1825  returnCode = posix_fadvise(VfdCache[file].fd, offset, amount,
1826  POSIX_FADV_WILLNEED);
1828 
1829  return returnCode;
1830 #else
1831  Assert(FileIsValid(file));
1832  return 0;
1833 #endif
1834 }
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1342
#define FileIsValid(file)
Definition: fd.c:167
static int FileAccess(File file)
Definition: fd.c:1240
#define Assert(condition)
Definition: c.h:732
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1318
#define INT64_FORMAT
Definition: c.h:400
#define elog(elevel,...)
Definition: elog.h:226

◆ FileRead()

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

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

1862 {
1863  int returnCode;
1864  Vfd *vfdP;
1865 
1866  Assert(FileIsValid(file));
1867 
1868  DO_DB(elog(LOG, "FileRead: %d (%s) " INT64_FORMAT " %d %p",
1869  file, VfdCache[file].fileName,
1870  (int64) offset,
1871  amount, buffer));
1872 
1873  returnCode = FileAccess(file);
1874  if (returnCode < 0)
1875  return returnCode;
1876 
1877  vfdP = &VfdCache[file];
1878 
1879 retry:
1880  pgstat_report_wait_start(wait_event_info);
1881  returnCode = pg_pread(vfdP->fd, buffer, amount, offset);
1883 
1884  if (returnCode < 0)
1885  {
1886  /*
1887  * Windows may run out of kernel buffers and return "Insufficient
1888  * system resources" error. Wait a bit and retry to solve it.
1889  *
1890  * It is rumored that EINTR is also possible on some Unix filesystems,
1891  * in which case immediate retry is indicated.
1892  */
1893 #ifdef WIN32
1894  DWORD error = GetLastError();
1895 
1896  switch (error)
1897  {
1898  case ERROR_NO_SYSTEM_RESOURCES:
1899  pg_usleep(1000L);
1900  errno = EINTR;
1901  break;
1902  default:
1903  _dosmaperr(error);
1904  break;
1905  }
1906 #endif
1907  /* OK to retry if interrupted */
1908  if (errno == EINTR)
1909  goto retry;
1910  }
1911 
1912  return returnCode;
1913 }
static void error(void)
Definition: sql-dyntest.c:147
#define DO_DB(A)
Definition: fd.c:161
void _dosmaperr(unsigned long)
Definition: win32error.c:171
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
ssize_t pg_pread(int fd, void *buf, size_t nbyte, off_t offset)
Definition: pread.c:27
void pg_usleep(long microsec)
Definition: signal.c:53
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1342
Definition: fd.c:177
int fd
Definition: fd.c:179
#define FileIsValid(file)
Definition: fd.c:167
static int FileAccess(File file)
Definition: fd.c:1240
#define Assert(condition)
Definition: c.h:732
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1318
#define INT64_FORMAT
Definition: c.h:400
#define elog(elevel,...)
Definition: elog.h:226
#define EINTR
Definition: win32_port.h:332

◆ FileSize()

off_t FileSize ( File  file)

Definition at line 2035 of file fd.c.

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

Referenced by _mdnblocks(), and BufFileSize().

2036 {
2037  Assert(FileIsValid(file));
2038 
2039  DO_DB(elog(LOG, "FileSize %d (%s)",
2040  file, VfdCache[file].fileName));
2041 
2042  if (FileIsNotOpen(file))
2043  {
2044  if (FileAccess(file) < 0)
2045  return (off_t) -1;
2046  }
2047 
2048  return lseek(VfdCache[file].fd, 0, SEEK_END);
2049 }
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define FileIsNotOpen(file)
Definition: fd.c:170
#define FileIsValid(file)
Definition: fd.c:167
static int FileAccess(File file)
Definition: fd.c:1240
#define Assert(condition)
Definition: c.h:732
#define elog(elevel,...)
Definition: elog.h:226

◆ FileSync()

int FileSync ( File  file,
uint32  wait_event_info 
)

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

2015 {
2016  int returnCode;
2017 
2018  Assert(FileIsValid(file));
2019 
2020  DO_DB(elog(LOG, "FileSync: %d (%s)",
2021  file, VfdCache[file].fileName));
2022 
2023  returnCode = FileAccess(file);
2024  if (returnCode < 0)
2025  return returnCode;
2026 
2027  pgstat_report_wait_start(wait_event_info);
2028  returnCode = pg_fsync(VfdCache[file].fd);
2030 
2031  return returnCode;
2032 }
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1342
#define FileIsValid(file)
Definition: fd.c:167
static int FileAccess(File file)
Definition: fd.c:1240
#define Assert(condition)
Definition: c.h:732
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1318
#define elog(elevel,...)
Definition: elog.h:226
int pg_fsync(int fd)
Definition: fd.c:333

◆ FileTruncate()

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

Definition at line 2052 of file fd.c.

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

Referenced by mdtruncate().

2053 {
2054  int returnCode;
2055 
2056  Assert(FileIsValid(file));
2057 
2058  DO_DB(elog(LOG, "FileTruncate %d (%s)",
2059  file, VfdCache[file].fileName));
2060 
2061  returnCode = FileAccess(file);
2062  if (returnCode < 0)
2063  return returnCode;
2064 
2065  pgstat_report_wait_start(wait_event_info);
2066  returnCode = ftruncate(VfdCache[file].fd, offset);
2068 
2069  if (returnCode == 0 && VfdCache[file].fileSize > offset)
2070  {
2071  /* adjust our state for truncation of a temp file */
2072  Assert(VfdCache[file].fdstate & FD_TEMP_FILE_LIMIT);
2073  temporary_files_size -= VfdCache[file].fileSize - offset;
2074  VfdCache[file].fileSize = offset;
2075  }
2076 
2077  return returnCode;
2078 }
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:175
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1342
off_t fileSize
Definition: fd.c:185
#define FileIsValid(file)
Definition: fd.c:167
static uint64 temporary_files_size
Definition: fd.c:217
static int FileAccess(File file)
Definition: fd.c:1240
#define Assert(condition)
Definition: c.h:732
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1318
#define elog(elevel,...)
Definition: elog.h:226
#define ftruncate(a, b)
Definition: win32_port.h:60

◆ FileWrite()

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

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

1918 {
1919  int returnCode;
1920  Vfd *vfdP;
1921 
1922  Assert(FileIsValid(file));
1923 
1924  DO_DB(elog(LOG, "FileWrite: %d (%s) " INT64_FORMAT " %d %p",
1925  file, VfdCache[file].fileName,
1926  (int64) offset,
1927  amount, buffer));
1928 
1929  returnCode = FileAccess(file);
1930  if (returnCode < 0)
1931  return returnCode;
1932 
1933  vfdP = &VfdCache[file];
1934 
1935  /*
1936  * If enforcing temp_file_limit and it's a temp file, check to see if the
1937  * write would overrun temp_file_limit, and throw error if so. Note: it's
1938  * really a modularity violation to throw error here; we should set errno
1939  * and return -1. However, there's no way to report a suitable error
1940  * message if we do that. All current callers would just throw error
1941  * immediately anyway, so this is safe at present.
1942  */
1943  if (temp_file_limit >= 0 && (vfdP->fdstate & FD_TEMP_FILE_LIMIT))
1944  {
1945  off_t past_write = offset + amount;
1946 
1947  if (past_write > vfdP->fileSize)
1948  {
1949  uint64 newTotal = temporary_files_size;
1950 
1951  newTotal += past_write - vfdP->fileSize;
1952  if (newTotal > (uint64) temp_file_limit * (uint64) 1024)
1953  ereport(ERROR,
1954  (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
1955  errmsg("temporary file size exceeds temp_file_limit (%dkB)",
1956  temp_file_limit)));
1957  }
1958  }
1959 
1960 retry:
1961  errno = 0;
1962  pgstat_report_wait_start(wait_event_info);
1963  returnCode = pg_pwrite(VfdCache[file].fd, buffer, amount, offset);
1965 
1966  /* if write didn't set errno, assume problem is no disk space */
1967  if (returnCode != amount && errno == 0)
1968  errno = ENOSPC;
1969 
1970  if (returnCode >= 0)
1971  {
1972  /*
1973  * Maintain fileSize and temporary_files_size if it's a temp file.
1974  */
1975  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
1976  {
1977  off_t past_write = offset + amount;
1978 
1979  if (past_write > vfdP->fileSize)
1980  {
1981  temporary_files_size += past_write - vfdP->fileSize;
1982  vfdP->fileSize = past_write;
1983  }
1984  }
1985  }
1986  else
1987  {
1988  /*
1989  * See comments in FileRead()
1990  */
1991 #ifdef WIN32
1992  DWORD error = GetLastError();
1993 
1994  switch (error)
1995  {
1996  case ERROR_NO_SYSTEM_RESOURCES:
1997  pg_usleep(1000L);
1998  errno = EINTR;
1999  break;
2000  default:
2001  _dosmaperr(error);
2002  break;
2003  }
2004 #endif
2005  /* OK to retry if interrupted */
2006  if (errno == EINTR)
2007  goto retry;
2008  }
2009 
2010  return returnCode;
2011 }
static void error(void)
Definition: sql-dyntest.c:147
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:175
#define DO_DB(A)
Definition: fd.c:161
void _dosmaperr(unsigned long)
Definition: win32error.c:171
static Vfd * VfdCache
Definition: fd.c:197
int errcode(int sqlerrcode)
Definition: elog.c:570
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ssize_t pg_pwrite(int fd, const void *buf, size_t nbyte, off_t offset)
Definition: pwrite.c:27
void pg_usleep(long microsec)
Definition: signal.c:53
#define ERROR
Definition: elog.h:43
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1342
unsigned short fdstate
Definition: fd.c:180
Definition: fd.c:177
off_t fileSize
Definition: fd.c:185
#define ereport(elevel, rest)
Definition: elog.h:141
#define FileIsValid(file)
Definition: fd.c:167
static uint64 temporary_files_size
Definition: fd.c:217
static int FileAccess(File file)
Definition: fd.c:1240
#define Assert(condition)
Definition: c.h:732
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1318
#define INT64_FORMAT
Definition: c.h:400
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
#define EINTR
Definition: win32_port.h:332
int temp_file_limit
Definition: guc.c:517

◆ FileWriteback()

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

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

1838 {
1839  int returnCode;
1840 
1841  Assert(FileIsValid(file));
1842 
1843  DO_DB(elog(LOG, "FileWriteback: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
1844  file, VfdCache[file].fileName,
1845  (int64) offset, (int64) nbytes));
1846 
1847  if (nbytes <= 0)
1848  return;
1849 
1850  returnCode = FileAccess(file);
1851  if (returnCode < 0)
1852  return;
1853 
1854  pgstat_report_wait_start(wait_event_info);
1855  pg_flush_data(VfdCache[file].fd, offset, nbytes);
1857 }
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1342
void pg_flush_data(int fd, off_t offset, off_t nbytes)
Definition: fd.c:405
#define FileIsValid(file)
Definition: fd.c:167
static int FileAccess(File file)
Definition: fd.c:1240
#define Assert(condition)
Definition: c.h:732
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1318
#define INT64_FORMAT
Definition: c.h:400
#define elog(elevel,...)
Definition: elog.h:226

◆ FreeDesc()

static int FreeDesc ( AllocateDesc desc)
static

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

2368 {
2369  int result;
2370 
2371  /* Close the underlying object */
2372  switch (desc->kind)
2373  {
2374  case AllocateDescFile:
2375  result = fclose(desc->desc.file);
2376  break;
2377  case AllocateDescPipe:
2378  result = pclose(desc->desc.file);
2379  break;
2380  case AllocateDescDir:
2381  result = closedir(desc->desc.dir);
2382  break;
2383  case AllocateDescRawFD:
2384  result = close(desc->desc.fd);
2385  break;
2386  default:
2387  elog(ERROR, "AllocateDesc kind not recognized");
2388  result = 0; /* keep compiler quiet */
2389  break;
2390  }
2391 
2392  /* Compact storage in the allocatedDescs array */
2395 
2396  return result;
2397 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
union AllocateDesc::@26 desc
DIR * dir
Definition: fd.c:238
int closedir(DIR *)
Definition: dirent.c:113
AllocateDescKind kind
Definition: fd.c:233
#define ERROR
Definition: elog.h:43
FILE * file
Definition: fd.c:237
int fd
Definition: fd.c:239
#define elog(elevel,...)
Definition: elog.h:226
#define close(a)
Definition: win32.h:12
static int numAllocatedDescs
Definition: fd.c:243

◆ FreeDir()

int FreeDir ( DIR dir)

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

2587 {
2588  int i;
2589 
2590  /* Nothing to do if AllocateDir failed */
2591  if (dir == NULL)
2592  return 0;
2593 
2594  DO_DB(elog(LOG, "FreeDir: Allocated %d", numAllocatedDescs));
2595 
2596  /* Remove dir from list of allocated dirs, if it's present */
2597  for (i = numAllocatedDescs; --i >= 0;)
2598  {
2599  AllocateDesc *desc = &allocatedDescs[i];
2600 
2601  if (desc->kind == AllocateDescDir && desc->desc.dir == dir)
2602  return FreeDesc(desc);
2603  }
2604 
2605  /* Only get here if someone passes us a dir not in allocatedDescs */
2606  elog(WARNING, "dir passed to FreeDir was not obtained from AllocateDir");
2607 
2608  return closedir(dir);
2609 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
union AllocateDesc::@26 desc
DIR * dir
Definition: fd.c:238
#define DO_DB(A)
Definition: fd.c:161
int closedir(DIR *)
Definition: dirent.c:113
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2367
#define WARNING
Definition: elog.h:40
#define elog(elevel,...)
Definition: elog.h:226
int i
static int numAllocatedDescs
Definition: fd.c:243

◆ FreeFile()

int FreeFile ( FILE *  file)

Definition at line 2406 of file fd.c.

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

Referenced by _ShowOption(), AlterSystemSetConfigFile(), apw_dump_now(), apw_load_buffers(), BackendRun(), checkControlFile(), do_pg_start_backup(), do_pg_stop_backup(), EndCopy(), entry_reset(), existsTimeLineHistory(), ExportSnapshot(), fill_hba_view(), gc_qtexts(), ImportSnapshot(), load_dh_file(), load_hba(), load_ident(), load_relcache_init_file(), parse_extension_control_file(), ParseTzFile(), perform_base_backup(), pg_backup_start_time(), pg_current_logfile(), pg_file_write_internal(), pg_promote(), PGSharedMemoryAttach(), pgss_shmem_shutdown(), pgss_shmem_startup(), pgstat_read_db_statsfile(), pgstat_read_db_statsfile_timestamp(), pgstat_read_statsfiles(), pgstat_write_db_statsfile(), pgstat_write_statsfiles(), PostmasterMarkPIDForWorkerNotify(), read_backup_label(), read_binary_file(), read_tablespace_map(), read_whole_file(), readTimeLineHistory(), sendFile(), tokenize_inc_file(), tsearch_readline_end(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

2407 {
2408  int i;
2409 
2410  DO_DB(elog(LOG, "FreeFile: Allocated %d", numAllocatedDescs));
2411 
2412  /* Remove file from list of allocated files, if it's present */
2413  for (i = numAllocatedDescs; --i >= 0;)
2414  {
2415  AllocateDesc *desc = &allocatedDescs[i];
2416 
2417  if (desc->kind == AllocateDescFile && desc->desc.file == file)
2418  return FreeDesc(desc);
2419  }
2420 
2421  /* Only get here if someone passes us a file not in allocatedDescs */
2422  elog(WARNING, "file passed to FreeFile was not obtained from AllocateFile");
2423 
2424  return fclose(file);
2425 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
union AllocateDesc::@26 desc
#define DO_DB(A)
Definition: fd.c:161
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2367
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:237
#define elog(elevel,...)
Definition: elog.h:226
int i
static int numAllocatedDescs
Definition: fd.c:243

◆ FreeVfd()

static void FreeVfd ( File  file)
static

Definition at line 1220 of file fd.c.

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

Referenced by FileClose(), and PathNameOpenFilePerm().

1221 {
1222  Vfd *vfdP = &VfdCache[file];
1223 
1224  DO_DB(elog(LOG, "FreeVfd: %d (%s)",
1225  file, vfdP->fileName ? vfdP->fileName : ""));
1226 
1227  if (vfdP->fileName != NULL)
1228  {
1229  free(vfdP->fileName);
1230  vfdP->fileName = NULL;
1231  }
1232  vfdP->fdstate = 0x0;
1233 
1234  vfdP->nextFree = VfdCache[0].nextFree;
1235  VfdCache[0].nextFree = file;
1236 }
File nextFree
Definition: fd.c:182
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:186
unsigned short fdstate
Definition: fd.c:180
Definition: fd.c:177
#define free(a)
Definition: header.h:65
#define elog(elevel,...)
Definition: elog.h:226

◆ fsync_fname()

void fsync_fname ( const char *  fname,
bool  isdir 
)

◆ fsync_fname_ext()

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

Definition at line 3346 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_link_or_rename(), durable_rename(), fsync_fname(), and fsync_parent_path().

3347 {
3348  int fd;
3349  int flags;
3350  int returncode;
3351 
3352  /*
3353  * Some OSs require directories to be opened read-only whereas other
3354  * systems don't allow us to fsync files opened read-only; so we need both
3355  * cases here. Using O_RDWR will cause us to fail to fsync files that are
3356  * not writable by our userid, but we assume that's OK.
3357  */
3358  flags = PG_BINARY;
3359  if (!isdir)
3360  flags |= O_RDWR;
3361  else
3362  flags |= O_RDONLY;
3363 
3364  fd = OpenTransientFile(fname, flags);
3365 
3366  /*
3367  * Some OSs don't allow us to open directories at all (Windows returns
3368  * EACCES), just ignore the error in that case. If desired also silently
3369  * ignoring errors about unreadable files. Log others.
3370  */
3371  if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES))
3372  return 0;
3373  else if (fd < 0 && ignore_perm && errno == EACCES)
3374  return 0;
3375  else if (fd < 0)
3376  {
3377  ereport(elevel,
3379  errmsg("could not open file \"%s\": %m", fname)));
3380  return -1;
3381  }
3382 
3383  returncode = pg_fsync(fd);
3384 
3385  /*
3386  * Some OSes don't allow us to fsync directories at all, so we can ignore
3387  * those errors. Anything else needs to be logged.
3388  */
3389  if (returncode != 0 && !(isdir && (errno == EBADF || errno == EINVAL)))
3390  {
3391  int save_errno;
3392 
3393  /* close file upon error, might not be in transaction context */
3394  save_errno = errno;
3395  (void) CloseTransientFile(fd);
3396  errno = save_errno;
3397 
3398  ereport(elevel,
3400  errmsg("could not fsync file \"%s\": %m", fname)));
3401  return -1;
3402  }
3403 
3404  if (CloseTransientFile(fd) != 0)
3405  {
3406  ereport(elevel,
3408  errmsg("could not close file \"%s\": %m", fname)));
3409  return -1;
3410  }
3411 
3412  return 0;
3413 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1191
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2257
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
int CloseTransientFile(int fd)
Definition: fd.c:2434
static int elevel
Definition: vacuumlazy.c:143
int errmsg(const char *fmt,...)
Definition: elog.c:784
int pg_fsync(int fd)
Definition: fd.c:333

◆ fsync_parent_path()

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

Definition at line 3422 of file fd.c.

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

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

3423 {
3424  char parentpath[MAXPGPATH];
3425 
3426  strlcpy(parentpath, fname, MAXPGPATH);
3427  get_parent_directory(parentpath);
3428 
3429  /*
3430  * get_parent_directory() returns an empty string if the input argument is
3431  * just a file name (see comments in path.c), so handle that as being the
3432  * current directory.
3433  */
3434  if (strlen(parentpath) == 0)
3435  strlcpy(parentpath, ".", MAXPGPATH);
3436 
3437  if (fsync_fname_ext(parentpath, true, false, elevel) != 0)
3438  return -1;
3439 
3440  return 0;
3441 }
#define MAXPGPATH
void get_parent_directory(char *path)
Definition: path.c:854
static int elevel
Definition: vacuumlazy.c:143
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
static int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3346

◆ GetNextTempTableSpace()

Oid GetNextTempTableSpace ( void  )

Definition at line 2729 of file fd.c.

References InvalidOid, nextTempTableSpace, numTempTableSpaces, and tempTableSpaces.

Referenced by GetDefaultTablespace(), and OpenTemporaryFile().

2730 {
2731  if (numTempTableSpaces > 0)
2732  {
2733  /* Advance nextTempTableSpace counter with wraparound */
2735  nextTempTableSpace = 0;
2737  }
2738  return InvalidOid;
2739 }
static int numTempTableSpaces
Definition: fd.c:258
static int nextTempTableSpace
Definition: fd.c:259
#define InvalidOid
Definition: postgres_ext.h:36
static Oid * tempTableSpaces
Definition: fd.c:257

◆ GetTempTablespaces()

int GetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 2711 of file fd.c.

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

Referenced by SharedFileSetInit().

2712 {
2713  int i;
2714 
2716  for (i = 0; i < numTempTableSpaces && i < numSpaces; ++i)
2717  tableSpaces[i] = tempTableSpaces[i];
2718 
2719  return i;
2720 }
static int numTempTableSpaces
Definition: fd.c:258
bool TempTablespacesAreSet(void)
Definition: fd.c:2699
#define Assert(condition)
Definition: c.h:732
static Oid * tempTableSpaces
Definition: fd.c:257
int i

◆ InitFileAccess()

void InitFileAccess ( void  )

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

787 {
788  Assert(SizeVfdCache == 0); /* call me only once */
789 
790  /* initialize cache header entry */
791  VfdCache = (Vfd *) malloc(sizeof(Vfd));
792  if (VfdCache == NULL)
793  ereport(FATAL,
794  (errcode(ERRCODE_OUT_OF_MEMORY),
795  errmsg("out of memory")));
796 
797  MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));
799 
800  SizeVfdCache = 1;
801 
802  /* register proc-exit hook to ensure temp files are dropped at exit */
804 }
static void AtProcExit_Files(int code, Datum arg)
Definition: fd.c:2797
static Size SizeVfdCache
Definition: fd.c:198
void on_proc_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:305
static Vfd * VfdCache
Definition: fd.c:197
int errcode(int sqlerrcode)
Definition: elog.c:570
#define MemSet(start, val, len)
Definition: c.h:955
#define malloc(a)
Definition: header.h:50
#define FATAL
Definition: elog.h:52
Definition: fd.c:177
int fd
Definition: fd.c:179
#define ereport(elevel, rest)
Definition: elog.h:141
#define VFD_CLOSED
Definition: fd.c:165
#define Assert(condition)
Definition: c.h:732
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ Insert()

static void Insert ( File  file)
static

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

1062 {
1063  Vfd *vfdP;
1064 
1065  Assert(file != 0);
1066 
1067  DO_DB(elog(LOG, "Insert %d (%s)",
1068  file, VfdCache[file].fileName));
1069  DO_DB(_dump_lru());
1070 
1071  vfdP = &VfdCache[file];
1072 
1073  vfdP->lruMoreRecently = 0;
1075  VfdCache[0].lruLessRecently = file;
1077 
1078  DO_DB(_dump_lru());
1079 }
File lruLessRecently
Definition: fd.c:184
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
Definition: fd.c:177
#define Assert(condition)
Definition: c.h:732
File lruMoreRecently
Definition: fd.c:183
#define elog(elevel,...)
Definition: elog.h:226

◆ looks_like_temp_rel_name()

bool looks_like_temp_rel_name ( const char *  name)

Definition at line 3067 of file fd.c.

References forkname_chars().

Referenced by RemovePgTempRelationFilesInDbspace(), and sendDir().

3068 {
3069  int pos;
3070  int savepos;
3071 
3072  /* Must start with "t". */
3073  if (name[0] != 't')
3074  return false;
3075 
3076  /* Followed by a non-empty string of digits and then an underscore. */
3077  for (pos = 1; isdigit((unsigned char) name[pos]); ++pos)
3078  ;
3079  if (pos == 1 || name[pos] != '_')
3080  return false;
3081 
3082  /* Followed by another nonempty string of digits. */
3083  for (savepos = ++pos; isdigit((unsigned char) name[pos]); ++pos)
3084  ;
3085  if (savepos == pos)
3086  return false;
3087 
3088  /* We might have _forkname or .segment or both. */
3089  if (name[pos] == '_')
3090  {
3091  int forkchar = forkname_chars(&name[pos + 1], NULL);
3092 
3093  if (forkchar <= 0)
3094  return false;
3095  pos += forkchar + 1;
3096  }
3097  if (name[pos] == '.')
3098  {
3099  int segchar;
3100 
3101  for (segchar = 1; isdigit((unsigned char) name[pos + segchar]); ++segchar)
3102  ;
3103  if (segchar <= 1)
3104  return false;
3105  pos += segchar;
3106  }
3107 
3108  /* Now we should be at the end. */
3109  if (name[pos] != '\0')
3110  return false;
3111  return true;
3112 }
int forkname_chars(const char *str, ForkNumber *fork)
Definition: relpath.c:78
const char * name
Definition: encode.c:521

◆ LruDelete()

static void LruDelete ( File  file)
static

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

1036 {
1037  Vfd *vfdP;
1038 
1039  Assert(file != 0);
1040 
1041  DO_DB(elog(LOG, "LruDelete %d (%s)",
1042  file, VfdCache[file].fileName));
1043 
1044  vfdP = &VfdCache[file];
1045 
1046  /*
1047  * Close the file. We aren't expecting this to fail; if it does, better
1048  * to leak the FD than to mess up our internal state.
1049  */
1050  if (close(vfdP->fd) != 0)
1052  "could not close file \"%s\": %m", vfdP->fileName);
1053  vfdP->fd = VFD_CLOSED;
1054  --nfile;
1055 
1056  /* delete the vfd record from the LRU ring */
1057  Delete(file);
1058 }
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:175
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
static void Delete(File file)
Definition: fd.c:1016
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:186
static int nfile
Definition: fd.c:203
unsigned short fdstate
Definition: fd.c:180
Definition: fd.c:177
int fd
Definition: fd.c:179
int data_sync_elevel(int elevel)
Definition: fd.c:3485
#define VFD_CLOSED
Definition: fd.c:165
#define Assert(condition)
Definition: c.h:732
#define elog(elevel,...)
Definition: elog.h:226
#define close(a)
Definition: win32.h:12

◆ LruInsert()

static int LruInsert ( File  file)
static

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

1084 {
1085  Vfd *vfdP;
1086 
1087  Assert(file != 0);
1088 
1089  DO_DB(elog(LOG, "LruInsert %d (%s)",
1090  file, VfdCache[file].fileName));
1091 
1092  vfdP = &VfdCache[file];
1093 
1094  if (FileIsNotOpen(file))
1095  {
1096  /* Close excess kernel FDs. */
1097  ReleaseLruFiles();
1098 
1099  /*
1100  * The open could still fail for lack of file descriptors, eg due to
1101  * overall system file table being full. So, be prepared to release
1102  * another FD if necessary...
1103  */
1104  vfdP->fd = BasicOpenFilePerm(vfdP->fileName, vfdP->fileFlags,
1105  vfdP->fileMode);
1106  if (vfdP->fd < 0)
1107  {
1108  DO_DB(elog(LOG, "re-open failed: %m"));
1109  return -1;
1110  }
1111  else
1112  {
1113  ++nfile;
1114  }
1115  }
1116 
1117  /*
1118  * put it at the head of the Lru ring
1119  */
1120 
1121  Insert(file);
1122 
1123  return 0;
1124 }
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
mode_t fileMode
Definition: fd.c:189
char * fileName
Definition: fd.c:186
static int nfile
Definition: fd.c:203
Definition: fd.c:177
int fd
Definition: fd.c:179
static void Insert(File file)
Definition: fd.c:1061
static void ReleaseLruFiles(void)
Definition: fd.c:1152
#define FileIsNotOpen(file)
Definition: fd.c:170
#define Assert(condition)
Definition: c.h:732
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:968
#define elog(elevel,...)
Definition: elog.h:226
int fileFlags
Definition: fd.c:188

◆ MakePGDirectory()

int MakePGDirectory ( const char *  directoryName)

◆ OpenPipeStream()

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

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

2311 {
2312  FILE *file;
2313  int save_errno;
2314 
2315  DO_DB(elog(LOG, "OpenPipeStream: Allocated %d (%s)",
2316  numAllocatedDescs, command));
2317 
2318  /* Can we allocate another non-virtual FD? */
2319  if (!reserveAllocatedDesc())
2320  ereport(ERROR,
2321  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2322  errmsg("exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"",
2323  maxAllocatedDescs, command)));
2324 
2325  /* Close excess kernel FDs. */
2326  ReleaseLruFiles();
2327 
2328 TryAgain:
2329  fflush(stdout);
2330  fflush(stderr);
2332  errno = 0;
2333  file = popen(command, mode);
2334  save_errno = errno;
2336  errno = save_errno;
2337  if (file != NULL)
2338  {
2340 
2341  desc->kind = AllocateDescPipe;
2342  desc->desc.file = file;
2345  return desc->desc.file;
2346  }
2347 
2348  if (errno == EMFILE || errno == ENFILE)
2349  {
2350  ereport(LOG,
2351  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2352  errmsg("out of file descriptors: %m; release and retry")));
2353  if (ReleaseLruFile())
2354  goto TryAgain;
2355  errno = save_errno;
2356  }
2357 
2358  return NULL;
2359 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
static AllocateDesc * allocatedDescs
Definition: fd.c:245
union AllocateDesc::@26 desc
#define DO_DB(A)
Definition: fd.c:161
int errcode(int sqlerrcode)
Definition: elog.c:570
static bool reserveAllocatedDesc(void)
Definition: fd.c:2134
#define SIGPIPE
Definition: win32_port.h:168
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static bool ReleaseLruFile(void)
Definition: fd.c:1130
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
#define SIG_IGN
Definition: win32_port.h:160
static void ReleaseLruFiles(void)
Definition: fd.c:1152
FILE * file
Definition: fd.c:237
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:170
#define SIG_DFL
Definition: win32_port.h:158
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:708
SubTransactionId create_subid
Definition: fd.c:234
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
static int maxAllocatedDescs
Definition: fd.c:244
static int numAllocatedDescs
Definition: fd.c:243

◆ OpenTemporaryFile()

File OpenTemporaryFile ( bool  interXact)

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

1465 {
1466  File file = 0;
1467 
1468  /*
1469  * Make sure the current resource owner has space for this File before we
1470  * open it, if we'll be registering it below.
1471  */
1472  if (!interXact)
1474 
1475  /*
1476  * If some temp tablespace(s) have been given to us, try to use the next
1477  * one. If a given tablespace can't be found, we silently fall back to
1478  * the database's default tablespace.
1479  *
1480  * BUT: if the temp file is slated to outlive the current transaction,
1481  * force it into the database's default tablespace, so that it will not
1482  * pose a threat to possible tablespace drop attempts.
1483  */
1484  if (numTempTableSpaces > 0 && !interXact)
1485  {
1486  Oid tblspcOid = GetNextTempTableSpace();
1487 
1488  if (OidIsValid(tblspcOid))
1489  file = OpenTemporaryFileInTablespace(tblspcOid, false);
1490  }
1491 
1492  /*
1493  * If not, or if tablespace is bad, create in database's default
1494  * tablespace. MyDatabaseTableSpace should normally be set before we get
1495  * here, but just in case it isn't, fall back to pg_default tablespace.
1496  */
1497  if (file <= 0)
1500  DEFAULTTABLESPACE_OID,
1501  true);
1502 
1503  /* Mark it for deletion at close and temporary file size limit */
1505 
1506  /* Register it with the current resource owner */
1507  if (!interXact)
1508  RegisterTemporaryFile(file);
1509 
1510  return file;
1511 }
static File OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError)
Definition: fd.c:1542
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:175
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
#define FD_DELETE_AT_CLOSE
Definition: fd.c:173
static Vfd * VfdCache
Definition: fd.c:197
static int numTempTableSpaces
Definition: fd.c:258
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
Oid MyDatabaseTableSpace
Definition: globals.c:87
Oid GetNextTempTableSpace(void)
Definition: fd.c:2729
unsigned short fdstate
Definition: fd.c:180
static void RegisterTemporaryFile(File file)
Definition: fd.c:1295
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1233
int File
Definition: fd.h:45

◆ OpenTemporaryFileInTablespace()

static File OpenTemporaryFileInTablespace ( Oid  tblspcOid,
bool  rejectError 
)
static

Definition at line 1542 of file fd.c.

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

Referenced by OpenTemporaryFile().

1543 {
1544  char tempdirpath[MAXPGPATH];
1545  char tempfilepath[MAXPGPATH];
1546  File file;
1547 
1548  TempTablespacePath(tempdirpath, tblspcOid);
1549 
1550  /*
1551  * Generate a tempfile name that should be unique within the current
1552  * database instance.
1553  */
1554  snprintf(tempfilepath, sizeof(tempfilepath), "%s/%s%d.%ld",
1555  tempdirpath, PG_TEMP_FILE_PREFIX, MyProcPid, tempFileCounter++);
1556 
1557  /*
1558  * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1559  * temp file that can be reused.
1560  */
1561  file = PathNameOpenFile(tempfilepath,
1562  O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1563  if (file <= 0)
1564  {
1565  /*
1566  * We might need to create the tablespace's tempfile directory, if no
1567  * one has yet done so.
1568  *
1569  * Don't check for an error from MakePGDirectory; it could fail if
1570  * someone else just did the same thing. If it doesn't work then
1571  * we'll bomb out on the second create attempt, instead.
1572  */
1573  (void) MakePGDirectory(tempdirpath);
1574 
1575  file = PathNameOpenFile(tempfilepath,
1576  O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1577  if (file <= 0 && rejectError)
1578  elog(ERROR, "could not create temporary file \"%s\": %m",
1579  tempfilepath);
1580  }
1581 
1582  return file;
1583 }
int MyProcPid
Definition: globals.c:40
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1323
void TempTablespacePath(char *path, Oid tablespace)
Definition: fd.c:1517
#define PG_BINARY
Definition: c.h:1191
#define ERROR
Definition: elog.h:43
#define PG_TEMP_FILE_PREFIX
Definition: pg_checksums.c:59
#define MAXPGPATH
int MakePGDirectory(const char *directoryName)
Definition: fd.c:3462
static long tempFileCounter
Definition: fd.c:251
#define elog(elevel,...)
Definition: elog.h:226
#define snprintf
Definition: port.h:192
int File
Definition: fd.h:45

◆ OpenTransientFile()

◆ OpenTransientFilePerm()

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

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

2267 {
2268  int fd;
2269 
2270  DO_DB(elog(LOG, "OpenTransientFile: Allocated %d (%s)",
2271  numAllocatedDescs, fileName));
2272 
2273  /* Can we allocate another non-virtual FD? */
2274  if (!reserveAllocatedDesc())
2275  ereport(ERROR,
2276  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2277  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2278  maxAllocatedDescs, fileName)));
2279 
2280  /* Close excess kernel FDs. */
2281  ReleaseLruFiles();
2282 
2283  fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
2284 
2285  if (fd >= 0)
2286  {
2288 
2289  desc->kind = AllocateDescRawFD;
2290  desc->desc.fd = fd;
2293 
2294  return fd;
2295  }
2296 
2297  return -1; /* failure */
2298 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
union AllocateDesc::@26 desc
#define DO_DB(A)
Definition: fd.c:161
int errcode(int sqlerrcode)
Definition: elog.c:570
static bool reserveAllocatedDesc(void)
Definition: fd.c:2134
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
static void ReleaseLruFiles(void)
Definition: fd.c:1152
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:708
SubTransactionId create_subid
Definition: fd.c:234
int fd
Definition: fd.c:239
int errmsg(const char *fmt,...)
Definition: elog.c:784
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:968
#define elog(elevel,...)
Definition: elog.h:226
static int maxAllocatedDescs
Definition: fd.c:244
static int numAllocatedDescs
Definition: fd.c:243

◆ PathNameCreateTemporaryDir()

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

Definition at line 1400 of file fd.c.

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

Referenced by SharedFileSetCreate().

1401 {
1402  if (MakePGDirectory(directory) < 0)
1403  {
1404  if (errno == EEXIST)
1405  return;
1406 
1407  /*
1408  * Failed. Try to create basedir first in case it's missing. Tolerate
1409  * EEXIST to close a race against another process following the same
1410  * algorithm.
1411  */
1412  if (MakePGDirectory(basedir) < 0 && errno != EEXIST)
1413  ereport(ERROR,
1415  errmsg("cannot create temporary directory \"%s\": %m",
1416  basedir)));
1417 
1418  /* Try again. */
1419  if (MakePGDirectory(directory) < 0 && errno != EEXIST)
1420  ereport(ERROR,
1422  errmsg("cannot create temporary subdirectory \"%s\": %m",
1423  directory)));
1424  }
1425 }
static char * basedir
Definition: pg_basebackup.c:86
#define ERROR
Definition: elog.h:43
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
int MakePGDirectory(const char *directoryName)
Definition: fd.c:3462
static const char * directory
Definition: zic.c:622
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ PathNameCreateTemporaryFile()

File PathNameCreateTemporaryFile ( const char *  path,
bool  error_on_failure 
)

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

1600 {
1601  File file;
1602 
1604 
1605  /*
1606  * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1607  * temp file that can be reused.
1608  */
1609  file = PathNameOpenFile(path, O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1610  if (file <= 0)
1611  {
1612  if (error_on_failure)
1613  ereport(ERROR,
1615  errmsg("could not create temporary file \"%s\": %m",
1616  path)));
1617  else
1618  return file;
1619  }
1620 
1621  /* Mark it for temp_file_limit accounting. */
1623 
1624  /* Register it for automatic close. */
1625  RegisterTemporaryFile(file);
1626 
1627  return file;
1628 }
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1323
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:175
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
static Vfd * VfdCache
Definition: fd.c:197
#define PG_BINARY
Definition: c.h:1191
#define ERROR
Definition: elog.h:43
int errcode_for_file_access(void)
Definition: elog.c:593
unsigned short fdstate
Definition: fd.c:180
#define ereport(elevel, rest)
Definition: elog.h:141
static void RegisterTemporaryFile(File file)
Definition: fd.c:1295
int errmsg(const char *fmt,...)
Definition: elog.c:784
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1233
int File
Definition: fd.h:45

◆ PathNameDeleteTemporaryDir()

void PathNameDeleteTemporaryDir ( const char *  dirname)

Definition at line 1431 of file fd.c.

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

Referenced by SharedFileSetDeleteAll().

1432 {
1433  struct stat statbuf;
1434 
1435  /* Silently ignore missing directory. */
1436  if (stat(dirname, &statbuf) != 0 && errno == ENOENT)
1437  return;
1438 
1439  /*
1440  * Currently, walkdir doesn't offer a way for our passed in function to
1441  * maintain state. Perhaps it should, so that we could tell the caller
1442  * whether this operation succeeded or failed. Since this operation is
1443  * used in a cleanup path, we wouldn't actually behave differently: we'll
1444  * just log failures.
1445  */
1446  walkdir(dirname, unlink_if_exists_fname, false, LOG);
1447 }
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
Definition: fd.c:3211
#define LOG
Definition: elog.h:26
static void unlink_if_exists_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3321
#define stat(a, b)
Definition: win32_port.h:264

◆ PathNameDeleteTemporaryFile()

bool PathNameDeleteTemporaryFile ( const char *  path,
bool  error_on_failure 
)

Definition at line 1667 of file fd.c.

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

Referenced by SharedFileSetDelete(), and unlink_if_exists_fname().

1668 {
1669  struct stat filestats;
1670  int stat_errno;
1671 
1672  /* Get the final size for pgstat reporting. */
1673  if (stat(path, &filestats) != 0)
1674  stat_errno = errno;
1675  else
1676  stat_errno = 0;
1677 
1678  /*
1679  * Unlike FileClose's automatic file deletion code, we tolerate
1680  * non-existence to support BufFileDeleteShared which doesn't know how
1681  * many segments it has to delete until it runs out.
1682  */
1683  if (stat_errno == ENOENT)
1684  return false;
1685 
1686  if (unlink(path) < 0)
1687  {
1688  if (errno != ENOENT)
1689  ereport(error_on_failure ? ERROR : LOG,
1691  errmsg("cannot unlink temporary file \"%s\": %m",
1692  path)));
1693  return false;
1694  }
1695 
1696  if (stat_errno == 0)
1697  ReportTemporaryFileUsage(path, filestats.st_size);
1698  else
1699  {
1700  errno = stat_errno;
1701  ereport(LOG,
1703  errmsg("could not stat file \"%s\": %m", path)));
1704  }
1705 
1706  return true;
1707 }
#define LOG
Definition: elog.h:26
#define ERROR
Definition: elog.h:43
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
static void ReportTemporaryFileUsage(const char *path, off_t size)
Definition: fd.c:1276
#define stat(a, b)
Definition: win32_port.h:264
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ PathNameOpenFile()

File PathNameOpenFile ( const char *  fileName,
int  fileFlags 
)

Definition at line 1323 of file fd.c.

References PathNameOpenFilePerm(), and pg_file_create_mode.

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

1324 {
1325  return PathNameOpenFilePerm(fileName, fileFlags, pg_file_create_mode);
1326 }
File PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1336
int pg_file_create_mode
Definition: file_perm.c:19

◆ PathNameOpenFilePerm()

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

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

1337 {
1338  char *fnamecopy;
1339  File file;
1340  Vfd *vfdP;
1341 
1342  DO_DB(elog(LOG, "PathNameOpenFilePerm: %s %x %o",
1343  fileName, fileFlags, fileMode));
1344 
1345  /*
1346  * We need a malloc'd copy of the file name; fail cleanly if no room.
1347  */
1348  fnamecopy = strdup(fileName);
1349  if (fnamecopy == NULL)
1350  ereport(ERROR,
1351  (errcode(ERRCODE_OUT_OF_MEMORY),
1352  errmsg("out of memory")));
1353 
1354  file = AllocateVfd();
1355  vfdP = &VfdCache[file];
1356 
1357  /* Close excess kernel FDs. */
1358  ReleaseLruFiles();
1359 
1360  vfdP->fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
1361 
1362  if (vfdP->fd < 0)
1363  {
1364  int save_errno = errno;
1365 
1366  FreeVfd(file);
1367  free(fnamecopy);
1368  errno = save_errno;
1369  return -1;
1370  }
1371  ++nfile;
1372  DO_DB(elog(LOG, "PathNameOpenFile: success %d",
1373  vfdP->fd));
1374 
1375  Insert(file);
1376 
1377  vfdP->fileName = fnamecopy;
1378  /* Saved flags are adjusted to be OK for re-opening file */
1379  vfdP->fileFlags = fileFlags & ~(O_CREAT | O_TRUNC | O_EXCL);
1380  vfdP->fileMode = fileMode;
1381  vfdP->fileSize = 0;
1382  vfdP->fdstate = 0x0;
1383  vfdP->resowner = NULL;
1384 
1385  return file;
1386 }
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
int errcode(int sqlerrcode)
Definition: elog.c:570
#define LOG
Definition: elog.h:26
mode_t fileMode
Definition: fd.c:189
#define ERROR
Definition: elog.h:43
char * fileName
Definition: fd.c:186
static int nfile
Definition: fd.c:203
static File AllocateVfd(void)
Definition: fd.c:1162
unsigned short fdstate
Definition: fd.c:180
Definition: fd.c:177
off_t fileSize
Definition: fd.c:185
int fd
Definition: fd.c:179
#define ereport(elevel, rest)
Definition: elog.h:141
static void Insert(File file)
Definition: fd.c:1061
ResourceOwner resowner
Definition: fd.c:181
static void ReleaseLruFiles(void)
Definition: fd.c:1152
#define free(a)
Definition: header.h:65
int errmsg(const char *fmt,...)
Definition: elog.c:784
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:968
#define elog(elevel,...)
Definition: elog.h:226
static void FreeVfd(File file)
Definition: fd.c:1220
int fileFlags
Definition: fd.c:188
int File
Definition: fd.h:45

◆ PathNameOpenTemporaryFile()

File PathNameOpenTemporaryFile ( const char *  path)

Definition at line 1637 of file fd.c.

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

Referenced by SharedFileSetOpen().

1638 {
1639  File file;
1640 
1642 
1643  /* We open the file read-only. */
1644  file = PathNameOpenFile(path, O_RDONLY | PG_BINARY);
1645 
1646  /* If no such file, then we don't raise an error. */
1647  if (file <= 0 && errno != ENOENT)
1648  ereport(ERROR,
1650  errmsg("could not open temporary file \"%s\": %m",
1651  path)));
1652 
1653  if (file > 0)
1654  {
1655  /* Register it for automatic close. */
1656  RegisterTemporaryFile(file);
1657  }
1658 
1659  return file;
1660 }
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1323
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
#define PG_BINARY
Definition: c.h:1191
#define ERROR
Definition: elog.h:43
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
static void RegisterTemporaryFile(File file)
Definition: fd.c:1295
int errmsg(const char *fmt,...)
Definition: elog.c:784
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1233
int File
Definition: fd.h:45

◆ pg_fdatasync()

int pg_fdatasync ( int  fd)

Definition at line 385 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync().

386 {
387  if (enableFsync)
388  {
389 #ifdef HAVE_FDATASYNC
390  return fdatasync(fd);
391 #else
392  return fsync(fd);
393 #endif
394  }
395  else
396  return 0;
397 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define fsync(fd)
Definition: win32_port.h:63
bool enableFsync
Definition: globals.c:119

◆ pg_flush_data()

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

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

406 {
407  /*
408  * Right now file flushing is primarily used to avoid making later
409  * fsync()/fdatasync() calls have less impact. Thus don't trigger flushes
410  * if fsyncs are disabled - that's a decision we might want to make
411  * configurable at some point.
412  */
413  if (!enableFsync)
414  return;
415 
416  /*
417  * We compile all alternatives that are supported on the current platform,
418  * to find portability problems more easily.
419  */
420 #if defined(HAVE_SYNC_FILE_RANGE)
421  {
422  int rc;
423  static bool not_implemented_by_kernel = false;
424 
425  if (not_implemented_by_kernel)
426  return;
427 
428  /*
429  * sync_file_range(SYNC_FILE_RANGE_WRITE), currently linux specific,
430  * tells the OS that writeback for the specified blocks should be
431  * started, but that we don't want to wait for completion. Note that
432  * this call might block if too much dirty data exists in the range.
433  * This is the preferable method on OSs supporting it, as it works
434  * reliably when available (contrast to msync()) and doesn't flush out
435  * clean data (like FADV_DONTNEED).
436  */
437  rc = sync_file_range(fd, offset, nbytes,
438  SYNC_FILE_RANGE_WRITE);
439  if (rc != 0)
440  {
441  int elevel;
442 
443  /*
444  * For systems that don't have an implementation of
445  * sync_file_range() such as Windows WSL, generate only one
446  * warning and then suppress all further attempts by this process.
447  */
448  if (errno == ENOSYS)
449  {
450  elevel = WARNING;
451  not_implemented_by_kernel = true;
452  }
453  else
454  elevel = data_sync_elevel(WARNING);
455 
456  ereport(elevel,
458  errmsg("could not flush dirty data: %m")));
459  }
460 
461  return;
462  }
463 #endif
464 #if !defined(WIN32) && defined(MS_ASYNC)
465  {
466  void *p;
467  static int pagesize = 0;
468 
469  /*
470  * On several OSs msync(MS_ASYNC) on a mmap'ed file triggers
471  * writeback. On linux it only does so if MS_SYNC is specified, but
472  * then it does the writeback synchronously. Luckily all common linux
473  * systems have sync_file_range(). This is preferable over
474  * FADV_DONTNEED because it doesn't flush out clean data.
475  *
476  * We map the file (mmap()), tell the kernel to sync back the contents
477  * (msync()), and then remove the mapping again (munmap()).
478  */
479 
480  /* mmap() needs actual length if we want to map whole file */
481  if (offset == 0 && nbytes == 0)
482  {
483  nbytes = lseek(fd, 0, SEEK_END);
484  if (nbytes < 0)
485  {
488  errmsg("could not determine dirty data size: %m")));
489  return;
490  }
491  }
492 
493  /*
494  * Some platforms reject partial-page mmap() attempts. To deal with
495  * that, just truncate the request to a page boundary. If any extra
496  * bytes don't get flushed, well, it's only a hint anyway.
497  */
498 
499  /* fetch pagesize only once */
500  if (pagesize == 0)
501  pagesize = sysconf(_SC_PAGESIZE);
502 
503  /* align length to pagesize, dropping any fractional page */
504  if (pagesize > 0)
505  nbytes = (nbytes / pagesize) * pagesize;
506 
507  /* fractional-page request is a no-op */
508  if (nbytes <= 0)
509  return;
510 
511  /*
512  * mmap could well fail, particularly on 32-bit platforms where there
513  * may simply not be enough address space. If so, silently fall
514  * through to the next implementation.
515  */
516  if (nbytes <= (off_t) SSIZE_MAX)
517  p = mmap(NULL, nbytes, PROT_READ, MAP_SHARED, fd, offset);
518  else
519  p = MAP_FAILED;
520 
521  if (p != MAP_FAILED)
522  {
523  int rc;
524 
525  rc = msync(p, (size_t) nbytes, MS_ASYNC);
526  if (rc != 0)
527  {
530  errmsg("could not flush dirty data: %m")));
531  /* NB: need to fall through to munmap()! */
532  }
533 
534  rc = munmap(p, (size_t) nbytes);
535  if (rc != 0)
536  {
537  /* FATAL error because mapping would remain */
538  ereport(FATAL,
540  errmsg("could not munmap() while flushing data: %m")));
541  }
542 
543  return;
544  }
545  }
546 #endif
547 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
548  {
549  int rc;
550 
551  /*
552  * Signal the kernel that the passed in range should not be cached
553  * anymore. This has the, desired, side effect of writing out dirty
554  * data, and the, undesired, side effect of likely discarding useful
555  * clean cached blocks. For the latter reason this is the least
556  * preferable method.
557  */
558 
559  rc = posix_fadvise(fd, offset, nbytes, POSIX_FADV_DONTNEED);
560 
561  if (rc != 0)
562  {
563  /* don't error out, this is just a performance optimization */
566  errmsg("could not flush dirty data: %m")));
567  }
568 
569  return;
570  }
571 #endif
572 }
#define MAP_FAILED
Definition: mem.h:45
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define FATAL
Definition: elog.h:52
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
#define WARNING
Definition: elog.h:40
static int elevel
Definition: vacuumlazy.c:143
int data_sync_elevel(int elevel)
Definition: fd.c:3485
bool enableFsync
Definition: globals.c:119
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ pg_fsync()

int pg_fsync ( int  fd)

Definition at line 333 of file fd.c.

References pg_fsync_no_writethrough(), pg_fsync_writethrough(), sync_method, and SYNC_METHOD_FSYNC_WRITETHROUGH.

Referenced by AddToDataDirLockFile(), assign_xlog_sync_method(), BootStrapXLOG(), CheckPointLogicalRewriteHeap(), CreateLockFile(), do_pg_start_backup(), durable_rename(), FileSync(), fsync_fname_ext(), heap_xlog_logical_rewrite(), readRecoverySignalFile(), RecreateTwoPhaseFile(), RestoreSlotFromDisk(), SaveSlotToPath(), SimpleLruFlush(), SlruPhysicalWritePage(), SnapBuildSerialize(), update_controlfile(), write_auto_conf_file(), write_relmap_file(), WriteControlFile(), writeTimeLineHistory(), writeTimeLineHistoryFile(), XLogFileCopy(), and XLogFileInit().

334 {
335  /* #if is to skip the sync_method test if there's no need for it */
336 #if defined(HAVE_FSYNC_WRITETHROUGH) && !defined(FSYNC_WRITETHROUGH_IS_FSYNC)
338  return pg_fsync_writethrough(fd);
339  else
340 #endif
342 }
#define SYNC_METHOD_FSYNC_WRITETHROUGH
Definition: xlog.h:28
int pg_fsync_writethrough(int fd)
Definition: fd.c:362
int pg_fsync_no_writethrough(int fd)
Definition: fd.c:350
static int fd(const char *x, int i)
Definition: preproc-init.c:105
int sync_method
Definition: xlog.c:102

◆ pg_fsync_no_writethrough()

int pg_fsync_no_writethrough ( int  fd)

Definition at line 350 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync(), and pg_fsync().

351 {
352  if (enableFsync)
353  return fsync(fd);
354  else
355  return 0;
356 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define fsync(fd)
Definition: win32_port.h:63
bool enableFsync
Definition: globals.c:119

◆ pg_fsync_writethrough()

int pg_fsync_writethrough ( int  fd)

Definition at line 362 of file fd.c.

References enableFsync.

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

363 {
364  if (enableFsync)
365  {
366 #ifdef WIN32
367  return _commit(fd);
368 #elif defined(F_FULLFSYNC)
369  return (fcntl(fd, F_FULLFSYNC, 0) == -1) ? -1 : 0;
370 #else
371  errno = ENOSYS;
372  return -1;
373 #endif
374  }
375  else
376  return 0;
377 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
bool enableFsync
Definition: globals.c:119

◆ ReadDir()

◆ ReadDirExtended()

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

Definition at line 2549 of file fd.c.

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

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

2550 {
2551  struct dirent *dent;
2552 
2553  /* Give a generic message for AllocateDir failure, if caller didn't */
2554  if (dir == NULL)
2555  {
2556  ereport(elevel,
2558  errmsg("could not open directory \"%s\": %m",
2559  dirname)));
2560  return NULL;
2561  }
2562 
2563  errno = 0;
2564  if ((dent = readdir(dir)) != NULL)
2565  return dent;
2566 
2567  if (errno)
2568  ereport(elevel,
2570  errmsg("could not read directory \"%s\": %m",
2571  dirname)));
2572  return NULL;
2573 }
Definition: dirent.h:9
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
static int elevel
Definition: vacuumlazy.c:143
struct dirent * readdir(DIR *)
Definition: dirent.c:77
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ RegisterTemporaryFile()

static void RegisterTemporaryFile ( File  file)
static

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

1296 {
1299 
1300  /* Backup mechanism for closing at end of xact. */
1303 }
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
static Vfd * VfdCache
Definition: fd.c:197
static bool have_xact_temporary_files
Definition: fd.c:209
void ResourceOwnerRememberFile(ResourceOwner owner, File file)
Definition: resowner.c:1244
unsigned short fdstate
Definition: fd.c:180
ResourceOwner resowner
Definition: fd.c:181
#define FD_CLOSE_AT_EOXACT
Definition: fd.c:174

◆ ReleaseLruFile()

static bool ReleaseLruFile ( void  )
static

Definition at line 1130 of file fd.c.

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

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

1131 {
1132  DO_DB(elog(LOG, "ReleaseLruFile. Opened %d", nfile));
1133 
1134  if (nfile > 0)
1135  {
1136  /*
1137  * There are opened files and so there should be at least one used vfd
1138  * in the ring.
1139  */
1140  Assert(VfdCache[0].lruMoreRecently != 0);
1141  LruDelete(VfdCache[0].lruMoreRecently);
1142  return true; /* freed a file */
1143  }
1144  return false; /* no files available to free */
1145 }
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
static void LruDelete(File file)
Definition: fd.c:1035
static int nfile
Definition: fd.c:203
#define Assert(condition)
Definition: c.h:732
#define elog(elevel,...)
Definition: elog.h:226

◆ ReleaseLruFiles()

static void ReleaseLruFiles ( void  )
static

Definition at line 1152 of file fd.c.

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

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

1153 {
1154  while (nfile + numAllocatedDescs >= max_safe_fds)
1155  {
1156  if (!ReleaseLruFile())
1157  break;
1158  }
1159 }
int max_safe_fds
Definition: fd.c:146
static bool ReleaseLruFile(void)
Definition: fd.c:1130
static int nfile
Definition: fd.c:203
static int numAllocatedDescs
Definition: fd.c:243

◆ RemovePgTempFiles()

void RemovePgTempFiles ( void  )

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

2886 {
2887  char temp_path[MAXPGPATH + 10 + sizeof(TABLESPACE_VERSION_DIRECTORY) + sizeof(PG_TEMP_FILES_DIR)];
2888  DIR *spc_dir;
2889  struct dirent *spc_de;
2890 
2891  /*
2892  * First process temp files in pg_default ($PGDATA/base)
2893  */
2894  snprintf(temp_path, sizeof(temp_path), "base/%s", PG_TEMP_FILES_DIR);
2895  RemovePgTempFilesInDir(temp_path, true, false);
2896  RemovePgTempRelationFiles("base");
2897 
2898  /*
2899  * Cycle through temp directories for all non-default tablespaces.
2900  */
2901  spc_dir = AllocateDir("pg_tblspc");
2902 
2903  while ((spc_de = ReadDirExtended(spc_dir, "pg_tblspc", LOG)) != NULL)
2904  {
2905  if (strcmp(spc_de->d_name, ".") == 0 ||
2906  strcmp(spc_de->d_name, "..") == 0)
2907  continue;
2908 
2909  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s/%s",
2911  RemovePgTempFilesInDir(temp_path, true, false);
2912 
2913  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s",
2915  RemovePgTempRelationFiles(temp_path);
2916  }
2917 
2918  FreeDir(spc_dir);
2919 
2920  /*
2921  * In EXEC_BACKEND case there is a pgsql_tmp directory at the top level of
2922  * DataDir as well.
2923  */
2924 #ifdef EXEC_BACKEND
2926 #endif
2927 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2549
#define PG_TEMP_FILES_DIR
Definition: pg_checksums.c:58
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
static void RemovePgTempRelationFiles(const char *tsdirname)
Definition: fd.c:3011
Definition: dirent.c:25
#define MAXPGPATH
#define TABLESPACE_VERSION_DIRECTORY
Definition: relpath.h:26
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2468
static void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok, bool unlink_all)
Definition: fd.c:2945
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:192
int FreeDir(DIR *dir)
Definition: fd.c:2586

◆ RemovePgTempFilesInDir()

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

Definition at line 2945 of file fd.c.

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

Referenced by RemovePgTempFiles().

2946 {
2947  DIR *temp_dir;
2948  struct dirent *temp_de;
2949  char rm_path[MAXPGPATH * 2];
2950 
2951  temp_dir = AllocateDir(tmpdirname);
2952 
2953  if (temp_dir == NULL && errno == ENOENT && missing_ok)
2954  return;
2955 
2956  while ((temp_de = ReadDirExtended(temp_dir, tmpdirname, LOG)) != NULL)
2957  {
2958  if (strcmp(temp_de->d_name, ".") == 0 ||
2959  strcmp(temp_de->d_name, "..") == 0)
2960  continue;
2961 
2962  snprintf(rm_path, sizeof(rm_path), "%s/%s",
2963  tmpdirname, temp_de->d_name);
2964 
2965  if (unlink_all ||
2966  strncmp(temp_de->d_name,
2968  strlen(PG_TEMP_FILE_PREFIX)) == 0)
2969  {
2970  struct stat statbuf;
2971 
2972  if (lstat(rm_path, &statbuf) < 0)
2973  {
2974  ereport(LOG,
2976  errmsg("could not stat file \"%s\": %m", rm_path)));
2977  continue;
2978  }
2979 
2980  if (S_ISDIR(statbuf.st_mode))
2981  {
2982  /* recursively remove contents, then directory itself */
2983  RemovePgTempFilesInDir(rm_path, false, true);
2984 
2985  if (rmdir(rm_path) < 0)
2986  ereport(LOG,
2988  errmsg("could not remove directory \"%s\": %m",
2989  rm_path)));
2990  }
2991  else
2992  {
2993  if (unlink(rm_path) < 0)
2994  ereport(LOG,
2996  errmsg("could not remove file \"%s\": %m",
2997  rm_path)));
2998  }
2999  }
3000  else
3001  ereport(LOG,
3002  (errmsg("unexpected file found in temporary-files directory: \"%s\"",
3003  rm_path)));
3004  }
3005 
3006  FreeDir(temp_dir);
3007 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2549
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
Definition: dirent.c:25
#define PG_TEMP_FILE_PREFIX
Definition: pg_checksums.c:59
#define MAXPGPATH
int errcode_for_file_access(void)
Definition: elog.c:593
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2468
#define ereport(elevel, rest)
Definition: elog.h:141
#define stat(a, b)
Definition: win32_port.h:264
static void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok, bool unlink_all)
Definition: fd.c:2945
#define S_ISDIR(m)
Definition: win32_port.h:305
#define lstat(path, sb)
Definition: win32_port.h:253
int errmsg(const char *fmt,...)
Definition: elog.c:784
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:192
int FreeDir(DIR *dir)
Definition: fd.c:2586

◆ RemovePgTempRelationFiles()

static void RemovePgTempRelationFiles ( const char *  tsdirname)
static

Definition at line 3011 of file fd.c.

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

Referenced by RemovePgTempFiles().

3012 {
3013  DIR *ts_dir;
3014  struct dirent *de;
3015  char dbspace_path[MAXPGPATH * 2];
3016 
3017  ts_dir = AllocateDir(tsdirname);
3018 
3019  while ((de = ReadDirExtended(ts_dir, tsdirname, LOG)) != NULL)
3020  {
3021  /*
3022  * We're only interested in the per-database directories, which have
3023  * numeric names. Note that this code will also (properly) ignore "."
3024  * and "..".
3025  */
3026  if (strspn(de->d_name, "0123456789") != strlen(de->d_name))
3027  continue;
3028 
3029  snprintf(dbspace_path, sizeof(dbspace_path), "%s/%s",
3030  tsdirname, de->d_name);
3031  RemovePgTempRelationFilesInDbspace(dbspace_path);
3032  }
3033 
3034  FreeDir(ts_dir);
3035 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2549
static void RemovePgTempRelationFilesInDbspace(const char *dbspacedirname)
Definition: fd.c:3039
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2468
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:192
int FreeDir(DIR *dir)
Definition: fd.c:2586

◆ RemovePgTempRelationFilesInDbspace()

static void RemovePgTempRelationFilesInDbspace ( const char *  dbspacedirname)
static

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

3040 {
3041  DIR *dbspace_dir;
3042  struct dirent *de;
3043  char rm_path[MAXPGPATH * 2];
3044 
3045  dbspace_dir = AllocateDir(dbspacedirname);
3046 
3047  while ((de = ReadDirExtended(dbspace_dir, dbspacedirname, LOG)) != NULL)
3048  {
3049  if (!looks_like_temp_rel_name(de->d_name))
3050  continue;
3051 
3052  snprintf(rm_path, sizeof(rm_path), "%s/%s",
3053  dbspacedirname, de->d_name);
3054 
3055  if (unlink(rm_path) < 0)
3056  ereport(LOG,
3058  errmsg("could not remove file \"%s\": %m",
3059  rm_path)));
3060  }
3061 
3062  FreeDir(dbspace_dir);
3063 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2549
#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:593
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2468
#define ereport(elevel, rest)
Definition: elog.h:141
bool looks_like_temp_rel_name(const char *name)
Definition: fd.c:3067
int errmsg(const char *fmt,...)
Definition: elog.c:784
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:192
int FreeDir(DIR *dir)
Definition: fd.c:2586

◆ ReportTemporaryFileUsage()

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

Definition at line 1276 of file fd.c.

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

Referenced by FileClose(), and PathNameDeleteTemporaryFile().

1277 {
1278  pgstat_report_tempfile(size);
1279 
1280  if (log_temp_files >= 0)
1281  {
1282  if ((size / 1024) >= log_temp_files)
1283  ereport(LOG,
1284  (errmsg("temporary file: path \"%s\", size %lu",
1285  path, (unsigned long) size)));
1286  }
1287 }
int log_temp_files
Definition: guc.c:513
void pgstat_report_tempfile(size_t filesize)
Definition: pgstat.c:1566
#define LOG
Definition: elog.h:26
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ reserveAllocatedDesc()

static bool reserveAllocatedDesc ( void  )
static

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

2135 {
2136  AllocateDesc *newDescs;
2137  int newMax;
2138 
2139  /* Quick out if array already has a free slot. */
2141  return true;
2142 
2143  /*
2144  * If the array hasn't yet been created in the current process, initialize
2145  * it with FD_MINFREE / 2 elements. In many scenarios this is as many as
2146  * we will ever need, anyway. We don't want to look at max_safe_fds
2147  * immediately because set_max_safe_fds() may not have run yet.
2148  */
2149  if (allocatedDescs == NULL)
2150  {
2151  newMax = FD_MINFREE / 2;
2152  newDescs = (AllocateDesc *) malloc(newMax * sizeof(AllocateDesc));
2153  /* Out of memory already? Treat as fatal error. */
2154  if (newDescs == NULL)
2155  ereport(ERROR,
2156  (errcode(ERRCODE_OUT_OF_MEMORY),
2157  errmsg("out of memory")));
2158  allocatedDescs = newDescs;
2159  maxAllocatedDescs = newMax;
2160  return true;
2161  }
2162 
2163  /*
2164  * Consider enlarging the array beyond the initial allocation used above.
2165  * By the time this happens, max_safe_fds should be known accurately.
2166  *
2167  * We mustn't let allocated descriptors hog all the available FDs, and in
2168  * practice we'd better leave a reasonable number of FDs for VFD use. So
2169  * set the maximum to max_safe_fds / 2. (This should certainly be at
2170  * least as large as the initial size, FD_MINFREE / 2.)
2171  */
2172  newMax = max_safe_fds / 2;
2173  if (newMax > maxAllocatedDescs)
2174  {
2175  newDescs = (AllocateDesc *) realloc(allocatedDescs,
2176  newMax * sizeof(AllocateDesc));
2177  /* Treat out-of-memory as a non-fatal error. */
2178  if (newDescs == NULL)
2179  return false;
2180  allocatedDescs = newDescs;
2181  maxAllocatedDescs = newMax;
2182  return true;
2183  }
2184 
2185  /* Can't enlarge allocatedDescs[] any more. */
2186  return false;
2187 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
int max_safe_fds
Definition: fd.c:146
int errcode(int sqlerrcode)
Definition: elog.c:570
#define malloc(a)
Definition: header.h:50
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
#define FD_MINFREE
Definition: fd.c:125
#define realloc(a, b)
Definition: header.h:60
int errmsg(const char *fmt,...)
Definition: elog.c:784
static int maxAllocatedDescs
Definition: fd.c:244
static int numAllocatedDescs
Definition: fd.c:243

◆ set_max_safe_fds()

void set_max_safe_fds ( void  )

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

904 {
905  int usable_fds;
906  int already_open;
907 
908  /*----------
909  * We want to set max_safe_fds to
910  * MIN(usable_fds, max_files_per_process - already_open)
911  * less the slop factor for files that are opened without consulting
912  * fd.c. This ensures that we won't exceed either max_files_per_process
913  * or the experimentally-determined EMFILE limit.
914  *----------
915  */
917  &usable_fds, &already_open);
918 
919  max_safe_fds = Min(usable_fds, max_files_per_process - already_open);
920 
921  /*
922  * Take off the FDs reserved for system() etc.
923  */
925 
926  /*
927  * Make sure we still have enough to get by.
928  */
929  if (max_safe_fds < FD_MINFREE)
930  ereport(FATAL,
931  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
932  errmsg("insufficient file descriptors available to start server process"),
933  errdetail("System allows %d, we need at least %d.",
936 
937  elog(DEBUG2, "max_safe_fds = %d, usable_fds = %d, already_open = %d",
938  max_safe_fds, usable_fds, already_open);
939 }
static void count_usable_fds(int max_to_probe, int *usable_fds, int *already_open)
Definition: fd.c:819
#define NUM_RESERVED_FDS
Definition: fd.c:119
int max_safe_fds
Definition: fd.c:146
#define Min(x, y)
Definition: c.h:904
int errcode(int sqlerrcode)
Definition: elog.c:570
#define FATAL
Definition: elog.h:52
#define DEBUG2
Definition: elog.h:24
int errdetail(const char *fmt,...)
Definition: elog.c:860
int max_files_per_process
Definition: fd.c:133
#define ereport(elevel, rest)
Definition: elog.h:141
#define FD_MINFREE
Definition: fd.c:125
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226

◆ SetTempTablespaces()

void SetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 2671 of file fd.c.

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

Referenced by assign_temp_tablespaces(), and PrepareTempTablespaces().

2672 {
2673  Assert(numSpaces >= 0);
2674  tempTableSpaces = tableSpaces;
2675  numTempTableSpaces = numSpaces;
2676 
2677  /*
2678  * Select a random starting point in the list. This is to minimize
2679  * conflicts between backends that are most likely sharing the same list
2680  * of temp tablespaces. Note that if we create multiple temp files in the
2681  * same transaction, we'll advance circularly through the list --- this
2682  * ensures that large temporary sort files are nicely spread across all
2683  * available tablespaces.
2684  */
2685  if (numSpaces > 1)
2686  nextTempTableSpace = random() % numSpaces;
2687  else
2688  nextTempTableSpace = 0;
2689 }
long random(void)
Definition: random.c:22
static int numTempTableSpaces
Definition: fd.c:258
static int nextTempTableSpace
Definition: fd.c:259
#define Assert(condition)
Definition: c.h:732
static Oid * tempTableSpaces
Definition: fd.c:257

◆ SyncDataDirectory()

void SyncDataDirectory ( void  )

Definition at line 3137 of file fd.c.

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

Referenced by StartupXLOG().

3138 {
3139  bool xlog_is_symlink;
3140 
3141  /* We can skip this whole thing if fsync is disabled. */
3142  if (!enableFsync)
3143  return;
3144 
3145  /*
3146  * If pg_wal is a symlink, we'll need to recurse into it separately,
3147  * because the first walkdir below will ignore it.
3148  */
3149  xlog_is_symlink = false;
3150 
3151 #ifndef WIN32
3152  {
3153  struct stat st;
3154 
3155  if (lstat("pg_wal", &st) < 0)
3156  ereport(LOG,
3158  errmsg("could not stat file \"%s\": %m",
3159  "pg_wal")));
3160  else if (S_ISLNK(st.st_mode))
3161  xlog_is_symlink = true;
3162  }
3163 #else
3164  if (pgwin32_is_junction("pg_wal"))
3165  xlog_is_symlink = true;
3166 #endif
3167 
3168  /*
3169  * If possible, hint to the kernel that we're soon going to fsync the data
3170  * directory and its contents. Errors in this step are even less
3171  * interesting than normal, so log them only at DEBUG1.
3172  */
3173 #ifdef PG_FLUSH_DATA_WORKS
3174  walkdir(".", pre_sync_fname, false, DEBUG1);
3175  if (xlog_is_symlink)
3176  walkdir("pg_wal", pre_sync_fname, false, DEBUG1);
3177  walkdir("pg_tblspc", pre_sync_fname, true, DEBUG1);
3178 #endif
3179 
3180  /*
3181  * Now we do the fsync()s in the same order.
3182  *
3183  * The main call ignores symlinks, so in addition to specially processing
3184  * pg_wal if it's a symlink, pg_tblspc has to be visited separately with
3185  * process_symlinks = true. Note that if there are any plain directories
3186  * in pg_tblspc, they'll get fsync'd twice. That's not an expected case
3187  * so we don't worry about optimizing it.
3188  */
3189  walkdir(".", datadir_fsync_fname, false, LOG);
3190  if (xlog_is_symlink)
3191  walkdir("pg_wal", datadir_fsync_fname, false, LOG);
3192  walkdir("pg_tblspc", datadir_fsync_fname, true, LOG);
3193 }
#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:3211
#define LOG
Definition: elog.h:26
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
static void datadir_fsync_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3311
#define stat(a, b)
Definition: win32_port.h:264
#define lstat(path, sb)
Definition: win32_port.h:253
bool enableFsync
Definition: globals.c:119
int errmsg(const char *fmt,...)
Definition: elog.c:784
bool pgwin32_is_junction(const char *path)

◆ TempTablespacePath()

void TempTablespacePath ( char *  path,
Oid  tablespace 
)

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

1518 {
1519  /*
1520  * Identify the tempfile directory for this tablespace.
1521  *
1522  * If someone tries to specify pg_global, use pg_default instead.
1523  */
1524  if (tablespace == InvalidOid ||
1525  tablespace == DEFAULTTABLESPACE_OID ||
1526  tablespace == GLOBALTABLESPACE_OID)
1527  snprintf(path, MAXPGPATH, "base/%s", PG_TEMP_FILES_DIR);
1528  else
1529  {
1530  /* All other tablespaces are accessed via symlinks */
1531  snprintf(path, MAXPGPATH, "pg_tblspc/%u/%s/%s",
1534  }
1535 }
#define PG_TEMP_FILES_DIR
Definition: pg_checksums.c:58
#define MAXPGPATH
#define TABLESPACE_VERSION_DIRECTORY
Definition: relpath.h:26
char * tablespace
Definition: pgbench.c:186
#define InvalidOid
Definition: postgres_ext.h:36
#define snprintf
Definition: port.h:192

◆ TempTablespacesAreSet()

bool TempTablespacesAreSet ( void  )

Definition at line 2699 of file fd.c.

References numTempTableSpaces.

Referenced by GetTempTablespaces(), and PrepareTempTablespaces().

2700 {
2701  return (numTempTableSpaces >= 0);
2702 }
static int numTempTableSpaces
Definition: fd.c:258

◆ unlink_if_exists_fname()

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

Definition at line 3321 of file fd.c.

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

Referenced by PathNameDeleteTemporaryDir().

3322 {
3323  if (isdir)
3324  {
3325  if (rmdir(fname) != 0 && errno != ENOENT)
3326  ereport(elevel,
3328  errmsg("could not rmdir directory \"%s\": %m", fname)));
3329  }
3330  else
3331  {
3332  /* Use PathNameDeleteTemporaryFile to report filesize */
3333  PathNameDeleteTemporaryFile(fname, false);
3334  }
3335 }
bool PathNameDeleteTemporaryFile(const char *path, bool error_on_failure)
Definition: fd.c:1667
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
static int elevel
Definition: vacuumlazy.c:143
int errmsg(const char *fmt,...)
Definition: elog.c:784

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

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

Referenced by PathNameDeleteTemporaryDir(), and SyncDataDirectory().

3215 {
3216  DIR *dir;
3217  struct dirent *de;
3218 
3219  dir = AllocateDir(path);
3220 
3221  while ((de = ReadDirExtended(dir, path, elevel)) != NULL)
3222  {
3223  char subpath[MAXPGPATH * 2];
3224  struct stat fst;
3225  int sret;
3226 
3228 
3229  if (strcmp(de->d_name, ".") == 0 ||
3230  strcmp(de->d_name, "..") == 0)
3231  continue;
3232 
3233  snprintf(subpath, sizeof(subpath), "%s/%s", path, de->d_name);
3234 
3235  if (process_symlinks)
3236  sret = stat(subpath, &fst);
3237  else
3238  sret = lstat(subpath, &fst);
3239 
3240  if (sret < 0)
3241  {
3242  ereport(elevel,
3244  errmsg("could not stat file \"%s\": %m", subpath)));
3245  continue;
3246  }
3247 
3248  if (S_ISREG(fst.st_mode))
3249  (*action) (subpath, false, elevel);
3250  else if (S_ISDIR(fst.st_mode))
3251  walkdir(subpath, action, false, elevel);
3252  }
3253 
3254  FreeDir(dir); /* we ignore any error here */
3255 
3256  /*
3257  * It's important to fsync the destination directory itself as individual
3258  * file fsyncs don't guarantee that the directory entry for the file is
3259  * synced. However, skip this if AllocateDir failed; the action function
3260  * might not be robust against that.
3261  */
3262  if (dir)
3263  (*action) (path, true, elevel);
3264 }
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
Definition: fd.c:3211
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2549
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
int errcode_for_file_access(void)
Definition: elog.c:593
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2468
#define ereport(elevel, rest)
Definition: elog.h:141
#define S_ISREG(m)
Definition: win32_port.h:308
#define stat(a, b)
Definition: win32_port.h:264
static int elevel
Definition: vacuumlazy.c:143
#define S_ISDIR(m)
Definition: win32_port.h:305
#define lstat(path, sb)
Definition: win32_port.h:253
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:192
int FreeDir(DIR *dir)
Definition: fd.c:2586
Datum subpath(PG_FUNCTION_ARGS)
Definition: ltree_op.c:241

Variable Documentation

◆ allocatedDescs

AllocateDesc* allocatedDescs = NULL
static

Definition at line 245 of file fd.c.

◆ data_sync_retry

bool data_sync_retry = false

Definition at line 149 of file fd.c.

Referenced by data_sync_elevel().

◆ have_xact_temporary_files

bool have_xact_temporary_files = false
static

Definition at line 209 of file fd.c.

Referenced by CleanupTempFiles(), and RegisterTemporaryFile().

◆ max_files_per_process

int max_files_per_process = 1000

Definition at line 133 of file fd.c.

Referenced by set_max_safe_fds().

◆ max_safe_fds

int max_safe_fds = 32

◆ maxAllocatedDescs

int maxAllocatedDescs = 0
static

◆ nextTempTableSpace

int nextTempTableSpace = 0
static

Definition at line 259 of file fd.c.

Referenced by GetNextTempTableSpace(), and SetTempTablespaces().

◆ nfile

int nfile = 0
static

◆ numAllocatedDescs

◆ numTempTableSpaces

int numTempTableSpaces = -1
static

◆ SizeVfdCache

Size SizeVfdCache = 0
static

Definition at line 198 of file fd.c.

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

◆ tempFileCounter

long tempFileCounter = 0
static

Definition at line 251 of file fd.c.

Referenced by OpenTemporaryFileInTablespace().

◆ temporary_files_size

uint64 temporary_files_size = 0
static

Definition at line 217 of file fd.c.

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

◆ tempTableSpaces

Oid* tempTableSpaces = NULL
static

◆ VfdCache

Vfd* VfdCache
static

Definition at line 197 of file fd.c.