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/catalog.h"
#include "catalog/pg_tablespace.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 PG_FILE_MODE_DEFAULT   (S_IRUSR | S_IWUSR)
 
#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 FileUnknownPos   ((off_t) -1)
 
#define FilePosIsUnknown(pos)   ((pos) < 0)
 
#define FD_TEMPORARY   (1 << 0) /* T = delete when closed */
 
#define FD_XACT_TEMPORARY   (1 << 1) /* T = delete at eoXact */
 

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 struct direntReadDirExtended (DIR *dir, const char *dirname, int elevel)
 
static void AtProcExit_Files (int code, Datum arg)
 
static void CleanupTempFiles (bool isProcExit)
 
static void RemovePgTempFilesInDir (const char *tmpdirname)
 
static void RemovePgTempRelationFiles (const char *tsdirname)
 
static void RemovePgTempRelationFilesInDbspace (const char *dbspacedirname)
 
static bool looks_like_temp_rel_name (const char *name)
 
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 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)
 
File PathNameOpenFile (const char *fileName, int fileFlags)
 
File PathNameOpenFilePerm (const char *fileName, int fileFlags, mode_t fileMode)
 
File OpenTemporaryFile (bool interXact)
 
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, uint32 wait_event_info)
 
int FileWrite (File file, char *buffer, int amount, uint32 wait_event_info)
 
int FileSync (File file, uint32 wait_event_info)
 
off_t FileSeek (File file, off_t offset, int whence)
 
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)
 
int FreeDir (DIR *dir)
 
int ClosePipeStream (FILE *file)
 
void closeAllVfds (void)
 
void SetTempTablespaces (Oid *tableSpaces, int numSpaces)
 
bool TempTablespacesAreSet (void)
 
Oid GetNextTempTableSpace (void)
 
void AtEOSubXact_Files (bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
 
void AtEOXact_Files (void)
 
void RemovePgTempFiles (void)
 
void SyncDataDirectory (void)
 

Variables

int max_files_per_process = 1000
 
int max_safe_fds = 32
 
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_MINFREE

#define FD_MINFREE   10

Definition at line 117 of file fd.c.

Referenced by reserveAllocatedDesc(), and set_max_safe_fds().

◆ FD_TEMPORARY

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

Definition at line 178 of file fd.c.

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

◆ FD_XACT_TEMPORARY

#define FD_XACT_TEMPORARY   (1 << 1) /* T = delete at eoXact */

Definition at line 179 of file fd.c.

Referenced by CleanupTempFiles(), and OpenTemporaryFile().

◆ FileIsNotOpen

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

Definition at line 166 of file fd.c.

Referenced by CleanupTempFiles(), closeAllVfds(), FileAccess(), FileClose(), FileSeek(), and LruInsert().

◆ FileIsValid

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

◆ FilePosIsUnknown

#define FilePosIsUnknown (   pos)    ((pos) < 0)

Definition at line 175 of file fd.c.

Referenced by FileRead(), FileSeek(), FileWrite(), and LruDelete().

◆ FileUnknownPos

#define FileUnknownPos   ((off_t) -1)

Definition at line 174 of file fd.c.

Referenced by FileRead(), and FileWrite().

◆ NUM_RESERVED_FDS

#define NUM_RESERVED_FDS   10

Definition at line 111 of file fd.c.

Referenced by set_max_safe_fds().

◆ PG_FILE_MODE_DEFAULT

#define PG_FILE_MODE_DEFAULT   (S_IRUSR | S_IWUSR)

Definition at line 123 of file fd.c.

Referenced by BasicOpenFile(), OpenTransientFile(), and PathNameOpenFile().

◆ VFD_CLOSED

#define VFD_CLOSED   (-1)

Definition at line 161 of file fd.c.

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

Typedef Documentation

◆ Vfd

typedef struct vfd Vfd

Enumeration Type Documentation

◆ AllocateDescKind

Enumerator
AllocateDescFile 
AllocateDescPipe 
AllocateDescDir 
AllocateDescRawFD 

Definition at line 228 of file fd.c.

Function Documentation

◆ AllocateDir()

DIR* AllocateDir ( const char *  dirname)

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

2374 {
2375  DIR *dir;
2376 
2377  DO_DB(elog(LOG, "AllocateDir: Allocated %d (%s)",
2378  numAllocatedDescs, dirname));
2379 
2380  /* Can we allocate another non-virtual FD? */
2381  if (!reserveAllocatedDesc())
2382  ereport(ERROR,
2383  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2384  errmsg("exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"",
2385  maxAllocatedDescs, dirname)));
2386 
2387  /* Close excess kernel FDs. */
2388  ReleaseLruFiles();
2389 
2390 TryAgain:
2391  if ((dir = opendir(dirname)) != NULL)
2392  {
2394 
2395  desc->kind = AllocateDescDir;
2396  desc->desc.dir = dir;
2399  return desc->desc.dir;
2400  }
2401 
2402  if (errno == EMFILE || errno == ENFILE)
2403  {
2404  int save_errno = errno;
2405 
2406  ereport(LOG,
2407  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2408  errmsg("out of file descriptors: %m; release and retry")));
2409  errno = 0;
2410  if (ReleaseLruFile())
2411  goto TryAgain;
2412  errno = save_errno;
2413  }
2414 
2415  return NULL;
2416 }
static AllocateDesc * allocatedDescs
Definition: fd.c:250
DIR * dir
Definition: fd.c:243
#define DO_DB(A)
Definition: fd.c:157
int errcode(int sqlerrcode)
Definition: elog.c:575
static bool reserveAllocatedDesc(void)
Definition: fd.c:2050
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:238
static bool ReleaseLruFile(void)
Definition: fd.c:1155
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:122
static void ReleaseLruFiles(void)
Definition: fd.c:1177
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:642
SubTransactionId create_subid
Definition: fd.c:239
int errmsg(const char *fmt,...)
Definition: elog.c:797
union AllocateDesc::@27 desc
#define elog
Definition: elog.h:219
static int maxAllocatedDescs
Definition: fd.c:249
static int numAllocatedDescs
Definition: fd.c:248

◆ AllocateFile()

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

Definition at line 2123 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(), checkDataDir(), 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(), PGSharedMemoryIsInUse(), 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(), readRecoveryCommandFile(), readTimeLineHistory(), sendFile(), tokenize_inc_file(), tsearch_readline_begin(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

2124 {
2125  FILE *file;
2126 
2127  DO_DB(elog(LOG, "AllocateFile: Allocated %d (%s)",
2129 
2130  /* Can we allocate another non-virtual FD? */
2131  if (!reserveAllocatedDesc())
2132  ereport(ERROR,
2133  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2134  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2135  maxAllocatedDescs, name)));
2136 
2137  /* Close excess kernel FDs. */
2138  ReleaseLruFiles();
2139 
2140 TryAgain:
2141  if ((file = fopen(name, mode)) != NULL)
2142  {
2144 
2145  desc->kind = AllocateDescFile;
2146  desc->desc.file = file;
2149  return desc->desc.file;
2150  }
2151 
2152  if (errno == EMFILE || errno == ENFILE)
2153  {
2154  int save_errno = errno;
2155 
2156  ereport(LOG,
2157  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2158  errmsg("out of file descriptors: %m; release and retry")));
2159  errno = 0;
2160  if (ReleaseLruFile())
2161  goto TryAgain;
2162  errno = save_errno;
2163  }
2164 
2165  return NULL;
2166 }
static AllocateDesc * allocatedDescs
Definition: fd.c:250
#define DO_DB(A)
Definition: fd.c:157
int errcode(int sqlerrcode)
Definition: elog.c:575
static bool reserveAllocatedDesc(void)
Definition: fd.c:2050
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:238
static bool ReleaseLruFile(void)
Definition: fd.c:1155
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static void ReleaseLruFiles(void)
Definition: fd.c:1177
FILE * file
Definition: fd.c:242
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:642
SubTransactionId create_subid
Definition: fd.c:239
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:797
union AllocateDesc::@27 desc
#define elog
Definition: elog.h:219
static int maxAllocatedDescs
Definition: fd.c:249
static int numAllocatedDescs
Definition: fd.c:248

◆ AllocateVfd()

static File AllocateVfd ( void  )
static

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

1188 {
1189  Index i;
1190  File file;
1191 
1192  DO_DB(elog(LOG, "AllocateVfd. Size %zu", SizeVfdCache));
1193 
1194  Assert(SizeVfdCache > 0); /* InitFileAccess not called? */
1195 
1196  if (VfdCache[0].nextFree == 0)
1197  {
1198  /*
1199  * The free list is empty so it is time to increase the size of the
1200  * array. We choose to double it each time this happens. However,
1201  * there's not much point in starting *real* small.
1202  */
1203  Size newCacheSize = SizeVfdCache * 2;
1204  Vfd *newVfdCache;
1205 
1206  if (newCacheSize < 32)
1207  newCacheSize = 32;
1208 
1209  /*
1210  * Be careful not to clobber VfdCache ptr if realloc fails.
1211  */
1212  newVfdCache = (Vfd *) realloc(VfdCache, sizeof(Vfd) * newCacheSize);
1213  if (newVfdCache == NULL)
1214  ereport(ERROR,
1215  (errcode(ERRCODE_OUT_OF_MEMORY),
1216  errmsg("out of memory")));
1217  VfdCache = newVfdCache;
1218 
1219  /*
1220  * Initialize the new entries and link them into the free list.
1221  */
1222  for (i = SizeVfdCache; i < newCacheSize; i++)
1223  {
1224  MemSet((char *) &(VfdCache[i]), 0, sizeof(Vfd));
1225  VfdCache[i].nextFree = i + 1;
1226  VfdCache[i].fd = VFD_CLOSED;
1227  }
1228  VfdCache[newCacheSize - 1].nextFree = 0;
1230 
1231  /*
1232  * Record the new size
1233  */
1234  SizeVfdCache = newCacheSize;
1235  }
1236 
1237  file = VfdCache[0].nextFree;
1238 
1239  VfdCache[0].nextFree = VfdCache[file].nextFree;
1240 
1241  return file;
1242 }
File nextFree
Definition: fd.c:186
static Size SizeVfdCache
Definition: fd.c:203
#define DO_DB(A)
Definition: fd.c:157
static Vfd * VfdCache
Definition: fd.c:202
int errcode(int sqlerrcode)
Definition: elog.c:575
#define MemSet(start, val, len)
Definition: c.h:853
#define LOG
Definition: elog.h:26
#define ERROR
Definition: elog.h:43
Definition: fd.c:181
int fd
Definition: fd.c:183
#define ereport(elevel, rest)
Definition: elog.h:122
unsigned int Index
Definition: c.h:413
#define VFD_CLOSED
Definition: fd.c:161
#define Assert(condition)
Definition: c.h:670
size_t Size
Definition: c.h:404
#define realloc(a, b)
Definition: header.h:60
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
#define elog
Definition: elog.h:219
int File
Definition: fd.h:49

◆ AtEOSubXact_Files()

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

Definition at line 2624 of file fd.c.

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

2626 {
2627  Index i;
2628 
2629  for (i = 0; i < numAllocatedDescs; i++)
2630  {
2631  if (allocatedDescs[i].create_subid == mySubid)
2632  {
2633  if (isCommit)
2634  allocatedDescs[i].create_subid = parentSubid;
2635  else
2636  {
2637  /* have to recheck the item after FreeDesc (ugly) */
2638  FreeDesc(&allocatedDescs[i--]);
2639  }
2640  }
2641  }
2642 }
static AllocateDesc * allocatedDescs
Definition: fd.c:250
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2276
unsigned int Index
Definition: c.h:413
SubTransactionId create_subid
Definition: fd.c:239
int i
static int numAllocatedDescs
Definition: fd.c:248

◆ AtEOXact_Files()

void AtEOXact_Files ( void  )

Definition at line 2655 of file fd.c.

References CleanupTempFiles(), numTempTableSpaces, and tempTableSpaces.

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

2656 {
2657  CleanupTempFiles(false);
2658  tempTableSpaces = NULL;
2659  numTempTableSpaces = -1;
2660 }
static int numTempTableSpaces
Definition: fd.c:263
static void CleanupTempFiles(bool isProcExit)
Definition: fd.c:2684
static Oid * tempTableSpaces
Definition: fd.c:262

◆ AtProcExit_Files()

static void AtProcExit_Files ( int  code,
Datum  arg 
)
static

Definition at line 2669 of file fd.c.

References CleanupTempFiles().

Referenced by InitFileAccess().

2670 {
2671  CleanupTempFiles(true);
2672 }
static void CleanupTempFiles(bool isProcExit)
Definition: fd.c:2684

◆ BasicOpenFile()

int BasicOpenFile ( const char *  fileName,
int  fileFlags 
)

Definition at line 929 of file fd.c.

References BasicOpenFilePerm(), and PG_FILE_MODE_DEFAULT.

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

930 {
931  return BasicOpenFilePerm(fileName, fileFlags, PG_FILE_MODE_DEFAULT);
932 }
#define PG_FILE_MODE_DEFAULT
Definition: fd.c:123
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:951

◆ BasicOpenFilePerm()

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

Definition at line 951 of file fd.c.

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

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

952 {
953  int fd;
954 
955 tryAgain:
956  fd = open(fileName, fileFlags, fileMode);
957 
958  if (fd >= 0)
959  return fd; /* success! */
960 
961  if (errno == EMFILE || errno == ENFILE)
962  {
963  int save_errno = errno;
964 
965  ereport(LOG,
966  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
967  errmsg("out of file descriptors: %m; release and retry")));
968  errno = 0;
969  if (ReleaseLruFile())
970  goto tryAgain;
971  errno = save_errno;
972  }
973 
974  return -1; /* failure */
975 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#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:1155
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ CleanupTempFiles()

static void CleanupTempFiles ( bool  isProcExit)
static

Definition at line 2684 of file fd.c.

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

Referenced by AtEOXact_Files(), and AtProcExit_Files().

2685 {
2686  Index i;
2687 
2688  /*
2689  * Careful here: at proc_exit we need extra cleanup, not just
2690  * xact_temporary files.
2691  */
2692  if (isProcExit || have_xact_temporary_files)
2693  {
2694  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2695  for (i = 1; i < SizeVfdCache; i++)
2696  {
2697  unsigned short fdstate = VfdCache[i].fdstate;
2698 
2699  if ((fdstate & FD_TEMPORARY) && VfdCache[i].fileName != NULL)
2700  {
2701  /*
2702  * If we're in the process of exiting a backend process, close
2703  * all temporary files. Otherwise, only close temporary files
2704  * local to the current transaction. They should be closed by
2705  * the ResourceOwner mechanism already, so this is just a
2706  * debugging cross-check.
2707  */
2708  if (isProcExit)
2709  FileClose(i);
2710  else if (fdstate & FD_XACT_TEMPORARY)
2711  {
2712  elog(WARNING,
2713  "temporary file %s not closed at end-of-transaction",
2714  VfdCache[i].fileName);
2715  FileClose(i);
2716  }
2717  }
2718  }
2719 
2720  have_xact_temporary_files = false;
2721  }
2722 
2723  /* Clean up "allocated" stdio files, dirs and fds. */
2724  while (numAllocatedDescs > 0)
2725  FreeDesc(&allocatedDescs[0]);
2726 }
static AllocateDesc * allocatedDescs
Definition: fd.c:250
static Size SizeVfdCache
Definition: fd.c:203
static Vfd * VfdCache
Definition: fd.c:202
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2276
static bool have_xact_temporary_files
Definition: fd.c:214
unsigned short fdstate
Definition: fd.c:184
#define WARNING
Definition: elog.h:40
#define FileIsNotOpen(file)
Definition: fd.c:166
#define FD_TEMPORARY
Definition: fd.c:178
#define FD_XACT_TEMPORARY
Definition: fd.c:179
unsigned int Index
Definition: c.h:413
void FileClose(File file)
Definition: fd.c:1522
#define Assert(condition)
Definition: c.h:670
int i
#define elog
Definition: elog.h:219
static int numAllocatedDescs
Definition: fd.c:248

◆ closeAllVfds()

void closeAllVfds ( void  )

Definition at line 2537 of file fd.c.

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

Referenced by standard_ProcessUtility().

2538 {
2539  Index i;
2540 
2541  if (SizeVfdCache > 0)
2542  {
2543  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2544  for (i = 1; i < SizeVfdCache; i++)
2545  {
2546  if (!FileIsNotOpen(i))
2547  LruDelete(i);
2548  }
2549  }
2550 }
static Size SizeVfdCache
Definition: fd.c:203
static void LruDelete(File file)
Definition: fd.c:1018
#define FileIsNotOpen(file)
Definition: fd.c:166
unsigned int Index
Definition: c.h:413
#define Assert(condition)
Definition: c.h:670
int i

◆ ClosePipeStream()

int ClosePipeStream ( FILE *  file)

Definition at line 2508 of file fd.c.

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

Referenced by ClosePipeToProgram(), and pg_import_system_collations().

2509 {
2510  int i;
2511 
2512  DO_DB(elog(LOG, "ClosePipeStream: Allocated %d", numAllocatedDescs));
2513 
2514  /* Remove file from list of allocated files, if it's present */
2515  for (i = numAllocatedDescs; --i >= 0;)
2516  {
2517  AllocateDesc *desc = &allocatedDescs[i];
2518 
2519  if (desc->kind == AllocateDescPipe && desc->desc.file == file)
2520  return FreeDesc(desc);
2521  }
2522 
2523  /* Only get here if someone passes us a file not in allocatedDescs */
2524  elog(WARNING, "file passed to ClosePipeStream was not obtained from OpenPipeStream");
2525 
2526  return pclose(file);
2527 }
static AllocateDesc * allocatedDescs
Definition: fd.c:250
#define DO_DB(A)
Definition: fd.c:157
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:238
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2276
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:242
union AllocateDesc::@27 desc
int i
#define elog
Definition: elog.h:219
static int numAllocatedDescs
Definition: fd.c:248

◆ CloseTransientFile()

int CloseTransientFile ( int  fd)

Definition at line 2343 of file fd.c.

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

Referenced by be_lo_export(), CheckPointLogicalRewriteHeap(), CheckPointReplicationOrigin(), copy_file(), dsm_impl_mmap(), durable_rename(), fsync_fname_ext(), 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().

2344 {
2345  int i;
2346 
2347  DO_DB(elog(LOG, "CloseTransientFile: Allocated %d", numAllocatedDescs));
2348 
2349  /* Remove fd from list of allocated files, if it's present */
2350  for (i = numAllocatedDescs; --i >= 0;)
2351  {
2352  AllocateDesc *desc = &allocatedDescs[i];
2353 
2354  if (desc->kind == AllocateDescRawFD && desc->desc.fd == fd)
2355  return FreeDesc(desc);
2356  }
2357 
2358  /* Only get here if someone passes us a file not in allocatedDescs */
2359  elog(WARNING, "fd passed to CloseTransientFile was not obtained from OpenTransientFile");
2360 
2361  return close(fd);
2362 }
static AllocateDesc * allocatedDescs
Definition: fd.c:250
#define DO_DB(A)
Definition: fd.c:157
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:238
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2276
#define WARNING
Definition: elog.h:40
int fd
Definition: fd.c:244
union AllocateDesc::@27 desc
int i
#define elog
Definition: elog.h:219
#define close(a)
Definition: win32.h:12
static int numAllocatedDescs
Definition: fd.c:248

◆ count_usable_fds()

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

Definition at line 802 of file fd.c.

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

Referenced by set_max_safe_fds().

803 {
804  int *fd;
805  int size;
806  int used = 0;
807  int highestfd = 0;
808  int j;
809 
810 #ifdef HAVE_GETRLIMIT
811  struct rlimit rlim;
812  int getrlimit_status;
813 #endif
814 
815  size = 1024;
816  fd = (int *) palloc(size * sizeof(int));
817 
818 #ifdef HAVE_GETRLIMIT
819 #ifdef RLIMIT_NOFILE /* most platforms use RLIMIT_NOFILE */
820  getrlimit_status = getrlimit(RLIMIT_NOFILE, &rlim);
821 #else /* but BSD doesn't ... */
822  getrlimit_status = getrlimit(RLIMIT_OFILE, &rlim);
823 #endif /* RLIMIT_NOFILE */
824  if (getrlimit_status != 0)
825  ereport(WARNING, (errmsg("getrlimit failed: %m")));
826 #endif /* HAVE_GETRLIMIT */
827 
828  /* dup until failure or probe limit reached */
829  for (;;)
830  {
831  int thisfd;
832 
833 #ifdef HAVE_GETRLIMIT
834 
835  /*
836  * don't go beyond RLIMIT_NOFILE; causes irritating kernel logs on
837  * some platforms
838  */
839  if (getrlimit_status == 0 && highestfd >= rlim.rlim_cur - 1)
840  break;
841 #endif
842 
843  thisfd = dup(0);
844  if (thisfd < 0)
845  {
846  /* Expect EMFILE or ENFILE, else it's fishy */
847  if (errno != EMFILE && errno != ENFILE)
848  elog(WARNING, "dup(0) failed after %d successes: %m", used);
849  break;
850  }
851 
852  if (used >= size)
853  {
854  size *= 2;
855  fd = (int *) repalloc(fd, size * sizeof(int));
856  }
857  fd[used++] = thisfd;
858 
859  if (highestfd < thisfd)
860  highestfd = thisfd;
861 
862  if (used >= max_to_probe)
863  break;
864  }
865 
866  /* release the files we opened */
867  for (j = 0; j < used; j++)
868  close(fd[j]);
869 
870  pfree(fd);
871 
872  /*
873  * Return results. usable_fds is just the number of successful dups. We
874  * assume that the system limit is highestfd+1 (remember 0 is a legal FD
875  * number) and so already_open is highestfd+1 - usable_fds.
876  */
877  *usable_fds = used;
878  *already_open = highestfd + 1 - used;
879 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
void pfree(void *pointer)
Definition: mcxt.c:949
#define ereport(elevel, rest)
Definition: elog.h:122
#define WARNING
Definition: elog.h:40
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:962
void * palloc(Size size)
Definition: mcxt.c:848
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
#define close(a)
Definition: win32.h:12

◆ datadir_fsync_fname()

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

Definition at line 3146 of file fd.c.

References fsync_fname_ext().

Referenced by SyncDataDirectory().

3147 {
3148  /*
3149  * We want to silently ignoring errors about unreadable files. Pass that
3150  * desire on to fsync_fname_ext().
3151  */
3152  fsync_fname_ext(fname, isdir, true, elevel);
3153 }
static int elevel
Definition: vacuumlazy.c:136
static int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3164

◆ Delete()

static void Delete ( File  file)
static

Definition at line 999 of file fd.c.

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

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

1000 {
1001  Vfd *vfdP;
1002 
1003  Assert(file != 0);
1004 
1005  DO_DB(elog(LOG, "Delete %d (%s)",
1006  file, VfdCache[file].fileName));
1007  DO_DB(_dump_lru());
1008 
1009  vfdP = &VfdCache[file];
1010 
1013 
1014  DO_DB(_dump_lru());
1015 }
File lruLessRecently
Definition: fd.c:188
#define DO_DB(A)
Definition: fd.c:157
static Vfd * VfdCache
Definition: fd.c:202
#define LOG
Definition: elog.h:26
Definition: fd.c:181
#define Assert(condition)
Definition: c.h:670
File lruMoreRecently
Definition: fd.c:187
#define elog
Definition: elog.h:219

◆ durable_link_or_rename()

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

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

718 {
719  /*
720  * Ensure that, if we crash directly after the rename/link, a file with
721  * valid contents is moved into place.
722  */
723  if (fsync_fname_ext(oldfile, false, false, elevel) != 0)
724  return -1;
725 
726 #if HAVE_WORKING_LINK
727  if (link(oldfile, newfile) < 0)
728  {
729  ereport(elevel,
731  errmsg("could not link file \"%s\" to \"%s\": %m",
732  oldfile, newfile)));
733  return -1;
734  }
735  unlink(oldfile);
736 #else
737  /* XXX: Add racy file existence check? */
738  if (rename(oldfile, newfile) < 0)
739  {
740  ereport(elevel,
742  errmsg("could not rename file \"%s\" to \"%s\": %m",
743  oldfile, newfile)));
744  return -1;
745  }
746 #endif
747 
748  /*
749  * Make change persistent in case of an OS crash, both the new entry and
750  * its parent directory need to be flushed.
751  */
752  if (fsync_fname_ext(newfile, false, false, elevel) != 0)
753  return -1;
754 
755  /* Same for parent directory */
756  if (fsync_parent_path(newfile, elevel) != 0)
757  return -1;
758 
759  return 0;
760 }
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
int link(const char *fromname, const char *toname)
static int elevel
Definition: vacuumlazy.c:136
int errmsg(const char *fmt,...)
Definition: elog.c:797
static int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3164
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3234

◆ durable_rename()

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

Definition at line 598 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(), exitArchiveRecovery(), KeepFileRestoredFromArchive(), pgarch_archiveDone(), pgss_shmem_shutdown(), StartupXLOG(), and XLogArchiveForceDone().

599 {
600  int fd;
601 
602  /*
603  * First fsync the old and target path (if it exists), to ensure that they
604  * are properly persistent on disk. Syncing the target file is not
605  * strictly necessary, but it makes it easier to reason about crashes;
606  * because it's then guaranteed that either source or target file exists
607  * after a crash.
608  */
609  if (fsync_fname_ext(oldfile, false, false, elevel) != 0)
610  return -1;
611 
612  fd = OpenTransientFile(newfile, PG_BINARY | O_RDWR);
613  if (fd < 0)
614  {
615  if (errno != ENOENT)
616  {
617  ereport(elevel,
619  errmsg("could not open file \"%s\": %m", newfile)));
620  return -1;
621  }
622  }
623  else
624  {
625  if (pg_fsync(fd) != 0)
626  {
627  int save_errno;
628 
629  /* close file upon error, might not be in transaction context */
630  save_errno = errno;
631  CloseTransientFile(fd);
632  errno = save_errno;
633 
634  ereport(elevel,
636  errmsg("could not fsync file \"%s\": %m", newfile)));
637  return -1;
638  }
639  CloseTransientFile(fd);
640  }
641 
642  /* Time to do the real deal... */
643  if (rename(oldfile, newfile) < 0)
644  {
645  ereport(elevel,
647  errmsg("could not rename file \"%s\" to \"%s\": %m",
648  oldfile, newfile)));
649  return -1;
650  }
651 
652  /*
653  * To guarantee renaming the file is persistent, fsync the file with its
654  * new name, and its containing directory.
655  */
656  if (fsync_fname_ext(newfile, false, false, elevel) != 0)
657  return -1;
658 
659  if (fsync_parent_path(newfile, elevel) != 0)
660  return -1;
661 
662  return 0;
663 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1025
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2173
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
int CloseTransientFile(int fd)
Definition: fd.c:2343
static int elevel
Definition: vacuumlazy.c:136
int errmsg(const char *fmt,...)
Definition: elog.c:797
static int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3164
int pg_fsync(int fd)
Definition: fd.c:338
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3234

◆ durable_unlink()

int durable_unlink ( const char *  fname,
int  elevel 
)

Definition at line 681 of file fd.c.

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

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

682 {
683  if (unlink(fname) < 0)
684  {
685  ereport(elevel,
687  errmsg("could not remove file \"%s\": %m",
688  fname)));
689  return -1;
690  }
691 
692  /*
693  * To guarantee that the removal of the file is persistent, fsync its
694  * parent directory.
695  */
696  if (fsync_parent_path(fname, elevel) != 0)
697  return -1;
698 
699  return 0;
700 }
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
static int elevel
Definition: vacuumlazy.c:136
int errmsg(const char *fmt,...)
Definition: elog.c:797
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3234

◆ FileAccess()

static int FileAccess ( File  file)
static

Definition at line 1265 of file fd.c.

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

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

1266 {
1267  int returnValue;
1268 
1269  DO_DB(elog(LOG, "FileAccess %d (%s)",
1270  file, VfdCache[file].fileName));
1271 
1272  /*
1273  * Is the file open? If not, open it and put it at the head of the LRU
1274  * ring (possibly closing the least recently used file to get an FD).
1275  */
1276 
1277  if (FileIsNotOpen(file))
1278  {
1279  returnValue = LruInsert(file);
1280  if (returnValue != 0)
1281  return returnValue;
1282  }
1283  else if (VfdCache[0].lruLessRecently != file)
1284  {
1285  /*
1286  * We now know that the file is open and that it is not the last one
1287  * accessed, so we need to move it to the head of the Lru ring.
1288  */
1289 
1290  Delete(file);
1291  Insert(file);
1292  }
1293 
1294  return 0;
1295 }
#define DO_DB(A)
Definition: fd.c:157
static Vfd * VfdCache
Definition: fd.c:202
static void Delete(File file)
Definition: fd.c:999
#define LOG
Definition: elog.h:26
static int LruInsert(File file)
Definition: fd.c:1081
static void Insert(File file)
Definition: fd.c:1059
#define FileIsNotOpen(file)
Definition: fd.c:166
#define elog
Definition: elog.h:219

◆ FileClose()

void FileClose ( File  file)

Definition at line 1522 of file fd.c.

References Assert, close, Delete(), DO_DB, elog, ereport, errmsg(), vfd::fd, FD_TEMPORARY, vfd::fdstate, FileIsNotOpen, FileIsValid, vfd::fileName, vfd::fileSize, FreeVfd(), LOG, log_temp_files, nfile, pgstat_report_tempfile(), ResourceOwnerForgetFile(), vfd::resowner, stat, temporary_files_size, and VFD_CLOSED.

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

1523 {
1524  Vfd *vfdP;
1525 
1526  Assert(FileIsValid(file));
1527 
1528  DO_DB(elog(LOG, "FileClose: %d (%s)",
1529  file, VfdCache[file].fileName));
1530 
1531  vfdP = &VfdCache[file];
1532 
1533  if (!FileIsNotOpen(file))
1534  {
1535  /* close the file */
1536  if (close(vfdP->fd))
1537  elog(LOG, "could not close file \"%s\": %m", vfdP->fileName);
1538 
1539  --nfile;
1540  vfdP->fd = VFD_CLOSED;
1541 
1542  /* remove the file from the lru ring */
1543  Delete(file);
1544  }
1545 
1546  /*
1547  * Delete the file if it was temporary, and make a log entry if wanted
1548  */
1549  if (vfdP->fdstate & FD_TEMPORARY)
1550  {
1551  struct stat filestats;
1552  int stat_errno;
1553 
1554  /*
1555  * If we get an error, as could happen within the ereport/elog calls,
1556  * we'll come right back here during transaction abort. Reset the
1557  * flag to ensure that we can't get into an infinite loop. This code
1558  * is arranged to ensure that the worst-case consequence is failing to
1559  * emit log message(s), not failing to attempt the unlink.
1560  */
1561  vfdP->fdstate &= ~FD_TEMPORARY;
1562 
1563  /* Subtract its size from current usage (do first in case of error) */
1564  temporary_files_size -= vfdP->fileSize;
1565  vfdP->fileSize = 0;
1566 
1567  /* first try the stat() */
1568  if (stat(vfdP->fileName, &filestats))
1569  stat_errno = errno;
1570  else
1571  stat_errno = 0;
1572 
1573  /* in any case do the unlink */
1574  if (unlink(vfdP->fileName))
1575  elog(LOG, "could not unlink file \"%s\": %m", vfdP->fileName);
1576 
1577  /* and last report the stat results */
1578  if (stat_errno == 0)
1579  {
1580  pgstat_report_tempfile(filestats.st_size);
1581 
1582  if (log_temp_files >= 0)
1583  {
1584  if ((filestats.st_size / 1024) >= log_temp_files)
1585  ereport(LOG,
1586  (errmsg("temporary file: path \"%s\", size %lu",
1587  vfdP->fileName,
1588  (unsigned long) filestats.st_size)));
1589  }
1590  }
1591  else
1592  {
1593  errno = stat_errno;
1594  elog(LOG, "could not stat file \"%s\": %m", vfdP->fileName);
1595  }
1596  }
1597 
1598  /* Unregister it from the resource owner */
1599  if (vfdP->resowner)
1600  ResourceOwnerForgetFile(vfdP->resowner, file);
1601 
1602  /*
1603  * Return the Vfd slot to the free list
1604  */
1605  FreeVfd(file);
1606 }
#define DO_DB(A)
Definition: fd.c:157
int log_temp_files
Definition: guc.c:455
static Vfd * VfdCache
Definition: fd.c:202
static void Delete(File file)
Definition: fd.c:999
void pgstat_report_tempfile(size_t filesize)
Definition: pgstat.c:1525
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:191
static int nfile
Definition: fd.c:208
unsigned short fdstate
Definition: fd.c:184
Definition: fd.c:181
off_t fileSize
Definition: fd.c:190
int fd
Definition: fd.c:183
#define ereport(elevel, rest)
Definition: elog.h:122
ResourceOwner resowner
Definition: fd.c:185
#define stat(a, b)
Definition: win32_port.h:266
#define FileIsNotOpen(file)
Definition: fd.c:166
#define FD_TEMPORARY
Definition: fd.c:178
#define FileIsValid(file)
Definition: fd.c:163
#define VFD_CLOSED
Definition: fd.c:161
static uint64 temporary_files_size
Definition: fd.c:222
#define Assert(condition)
Definition: c.h:670
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void FreeVfd(File file)
Definition: fd.c:1245
#define elog
Definition: elog.h:219
#define close(a)
Definition: win32.h:12
void ResourceOwnerForgetFile(ResourceOwner owner, File file)
Definition: resowner.c:1195

◆ FileGetRawDesc()

int FileGetRawDesc ( File  file)

Definition at line 2019 of file fd.c.

References Assert, vfd::fd, and FileIsValid.

2020 {
2021  Assert(FileIsValid(file));
2022  return VfdCache[file].fd;
2023 }
static Vfd * VfdCache
Definition: fd.c:202
int fd
Definition: fd.c:183
#define FileIsValid(file)
Definition: fd.c:163
#define Assert(condition)
Definition: c.h:670

◆ FileGetRawFlags()

int FileGetRawFlags ( File  file)

Definition at line 2029 of file fd.c.

References Assert, vfd::fileFlags, and FileIsValid.

2030 {
2031  Assert(FileIsValid(file));
2032  return VfdCache[file].fileFlags;
2033 }
static Vfd * VfdCache
Definition: fd.c:202
#define FileIsValid(file)
Definition: fd.c:163
#define Assert(condition)
Definition: c.h:670
int fileFlags
Definition: fd.c:193

◆ FileGetRawMode()

mode_t FileGetRawMode ( File  file)

Definition at line 2039 of file fd.c.

References Assert, FileIsValid, and vfd::fileMode.

2040 {
2041  Assert(FileIsValid(file));
2042  return VfdCache[file].fileMode;
2043 }
static Vfd * VfdCache
Definition: fd.c:202
mode_t fileMode
Definition: fd.c:194
#define FileIsValid(file)
Definition: fd.c:163
#define Assert(condition)
Definition: c.h:670

◆ FilePathName()

char* FilePathName ( File  file)

Definition at line 2003 of file fd.c.

References Assert, FileIsValid, and vfd::fileName.

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

2004 {
2005  Assert(FileIsValid(file));
2006 
2007  return VfdCache[file].fileName;
2008 }
static Vfd * VfdCache
Definition: fd.c:202
char * fileName
Definition: fd.c:191
#define FileIsValid(file)
Definition: fd.c:163
#define Assert(condition)
Definition: c.h:670

◆ FilePrefetch()

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

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

1620 {
1621 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
1622  int returnCode;
1623 
1624  Assert(FileIsValid(file));
1625 
1626  DO_DB(elog(LOG, "FilePrefetch: %d (%s) " INT64_FORMAT " %d",
1627  file, VfdCache[file].fileName,
1628  (int64) offset, amount));
1629 
1630  returnCode = FileAccess(file);
1631  if (returnCode < 0)
1632  return returnCode;
1633 
1634  pgstat_report_wait_start(wait_event_info);
1635  returnCode = posix_fadvise(VfdCache[file].fd, offset, amount,
1636  POSIX_FADV_WILLNEED);
1638 
1639  return returnCode;
1640 #else
1641  Assert(FileIsValid(file));
1642  return 0;
1643 #endif
1644 }
#define DO_DB(A)
Definition: fd.c:157
static Vfd * VfdCache
Definition: fd.c:202
#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:1244
#define FileIsValid(file)
Definition: fd.c:163
static int FileAccess(File file)
Definition: fd.c:1265
#define Assert(condition)
Definition: c.h:670
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1220
#define INT64_FORMAT
Definition: c.h:338
#define elog
Definition: elog.h:219

◆ FileRead()

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

Definition at line 1674 of file fd.c.

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

Referenced by BufFileLoadBuffer(), and mdread().

1675 {
1676  int returnCode;
1677  Vfd *vfdP;
1678 
1679  Assert(FileIsValid(file));
1680 
1681  DO_DB(elog(LOG, "FileRead: %d (%s) " INT64_FORMAT " %d %p",
1682  file, VfdCache[file].fileName,
1683  (int64) VfdCache[file].seekPos,
1684  amount, buffer));
1685 
1686  returnCode = FileAccess(file);
1687  if (returnCode < 0)
1688  return returnCode;
1689 
1690  vfdP = &VfdCache[file];
1691 
1692 retry:
1693  pgstat_report_wait_start(wait_event_info);
1694  returnCode = read(vfdP->fd, buffer, amount);
1696 
1697  if (returnCode >= 0)
1698  {
1699  /* if seekPos is unknown, leave it that way */
1700  if (!FilePosIsUnknown(vfdP->seekPos))
1701  vfdP->seekPos += returnCode;
1702  }
1703  else
1704  {
1705  /*
1706  * Windows may run out of kernel buffers and return "Insufficient
1707  * system resources" error. Wait a bit and retry to solve it.
1708  *
1709  * It is rumored that EINTR is also possible on some Unix filesystems,
1710  * in which case immediate retry is indicated.
1711  */
1712 #ifdef WIN32
1713  DWORD error = GetLastError();
1714 
1715  switch (error)
1716  {
1717  case ERROR_NO_SYSTEM_RESOURCES:
1718  pg_usleep(1000L);
1719  errno = EINTR;
1720  break;
1721  default:
1722  _dosmaperr(error);
1723  break;
1724  }
1725 #endif
1726  /* OK to retry if interrupted */
1727  if (errno == EINTR)
1728  goto retry;
1729 
1730  /* Trouble, so assume we don't know the file position anymore */
1731  vfdP->seekPos = FileUnknownPos;
1732  }
1733 
1734  return returnCode;
1735 }
static void error(void)
Definition: sql-dyntest.c:147
#define DO_DB(A)
Definition: fd.c:157
void _dosmaperr(unsigned long)
Definition: win32error.c:171
static Vfd * VfdCache
Definition: fd.c:202
#define LOG
Definition: elog.h:26
#define FilePosIsUnknown(pos)
Definition: fd.c:175
void pg_usleep(long microsec)
Definition: signal.c:53
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1244
off_t seekPos
Definition: fd.c:189
Definition: fd.c:181
int fd
Definition: fd.c:183
#define FileIsValid(file)
Definition: fd.c:163
static int FileAccess(File file)
Definition: fd.c:1265
#define Assert(condition)
Definition: c.h:670
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1220
#define INT64_FORMAT
Definition: c.h:338
#define elog
Definition: elog.h:219
#define EINTR
Definition: win32_port.h:334
#define FileUnknownPos
Definition: fd.c:174
#define read(a, b, c)
Definition: win32.h:13

◆ FileSeek()

off_t FileSeek ( File  file,
off_t  offset,
int  whence 
)

Definition at line 1880 of file fd.c.

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

Referenced by _mdnblocks(), BufFileDumpBuffer(), BufFileLoadBuffer(), mdextend(), mdread(), and mdwrite().

1881 {
1882  Vfd *vfdP;
1883 
1884  Assert(FileIsValid(file));
1885 
1886  DO_DB(elog(LOG, "FileSeek: %d (%s) " INT64_FORMAT " " INT64_FORMAT " %d",
1887  file, VfdCache[file].fileName,
1888  (int64) VfdCache[file].seekPos,
1889  (int64) offset, whence));
1890 
1891  vfdP = &VfdCache[file];
1892 
1893  if (FileIsNotOpen(file))
1894  {
1895  switch (whence)
1896  {
1897  case SEEK_SET:
1898  if (offset < 0)
1899  {
1900  errno = EINVAL;
1901  return (off_t) -1;
1902  }
1903  vfdP->seekPos = offset;
1904  break;
1905  case SEEK_CUR:
1906  if (FilePosIsUnknown(vfdP->seekPos) ||
1907  vfdP->seekPos + offset < 0)
1908  {
1909  errno = EINVAL;
1910  return (off_t) -1;
1911  }
1912  vfdP->seekPos += offset;
1913  break;
1914  case SEEK_END:
1915  if (FileAccess(file) < 0)
1916  return (off_t) -1;
1917  vfdP->seekPos = lseek(vfdP->fd, offset, whence);
1918  break;
1919  default:
1920  elog(ERROR, "invalid whence: %d", whence);
1921  break;
1922  }
1923  }
1924  else
1925  {
1926  switch (whence)
1927  {
1928  case SEEK_SET:
1929  if (offset < 0)
1930  {
1931  errno = EINVAL;
1932  return (off_t) -1;
1933  }
1934  if (vfdP->seekPos != offset)
1935  vfdP->seekPos = lseek(vfdP->fd, offset, whence);
1936  break;
1937  case SEEK_CUR:
1938  if (offset != 0 || FilePosIsUnknown(vfdP->seekPos))
1939  vfdP->seekPos = lseek(vfdP->fd, offset, whence);
1940  break;
1941  case SEEK_END:
1942  vfdP->seekPos = lseek(vfdP->fd, offset, whence);
1943  break;
1944  default:
1945  elog(ERROR, "invalid whence: %d", whence);
1946  break;
1947  }
1948  }
1949 
1950  return vfdP->seekPos;
1951 }
#define DO_DB(A)
Definition: fd.c:157
static Vfd * VfdCache
Definition: fd.c:202
#define LOG
Definition: elog.h:26
#define FilePosIsUnknown(pos)
Definition: fd.c:175
#define ERROR
Definition: elog.h:43
off_t seekPos
Definition: fd.c:189
Definition: fd.c:181
int fd
Definition: fd.c:183
#define FileIsNotOpen(file)
Definition: fd.c:166
#define FileIsValid(file)
Definition: fd.c:163
static int FileAccess(File file)
Definition: fd.c:1265
#define Assert(condition)
Definition: c.h:670
#define INT64_FORMAT
Definition: c.h:338
#define elog
Definition: elog.h:219

◆ FileSync()

int FileSync ( File  file,
uint32  wait_event_info 
)

Definition at line 1859 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(), mdsync(), and register_dirty_segment().

1860 {
1861  int returnCode;
1862 
1863  Assert(FileIsValid(file));
1864 
1865  DO_DB(elog(LOG, "FileSync: %d (%s)",
1866  file, VfdCache[file].fileName));
1867 
1868  returnCode = FileAccess(file);
1869  if (returnCode < 0)
1870  return returnCode;
1871 
1872  pgstat_report_wait_start(wait_event_info);
1873  returnCode = pg_fsync(VfdCache[file].fd);
1875 
1876  return returnCode;
1877 }
#define DO_DB(A)
Definition: fd.c:157
static Vfd * VfdCache
Definition: fd.c:202
#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:1244
#define FileIsValid(file)
Definition: fd.c:163
static int FileAccess(File file)
Definition: fd.c:1265
#define Assert(condition)
Definition: c.h:670
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1220
int pg_fsync(int fd)
Definition: fd.c:338
#define elog
Definition: elog.h:219

◆ FileTruncate()

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

Definition at line 1968 of file fd.c.

References Assert, DO_DB, elog, vfd::fd, FD_TEMPORARY, 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().

1969 {
1970  int returnCode;
1971 
1972  Assert(FileIsValid(file));
1973 
1974  DO_DB(elog(LOG, "FileTruncate %d (%s)",
1975  file, VfdCache[file].fileName));
1976 
1977  returnCode = FileAccess(file);
1978  if (returnCode < 0)
1979  return returnCode;
1980 
1981  pgstat_report_wait_start(wait_event_info);
1982  returnCode = ftruncate(VfdCache[file].fd, offset);
1984 
1985  if (returnCode == 0 && VfdCache[file].fileSize > offset)
1986  {
1987  /* adjust our state for truncation of a temp file */
1988  Assert(VfdCache[file].fdstate & FD_TEMPORARY);
1989  temporary_files_size -= VfdCache[file].fileSize - offset;
1990  VfdCache[file].fileSize = offset;
1991  }
1992 
1993  return returnCode;
1994 }
#define DO_DB(A)
Definition: fd.c:157
static Vfd * VfdCache
Definition: fd.c:202
#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:1244
off_t fileSize
Definition: fd.c:190
#define FD_TEMPORARY
Definition: fd.c:178
#define FileIsValid(file)
Definition: fd.c:163
static uint64 temporary_files_size
Definition: fd.c:222
static int FileAccess(File file)
Definition: fd.c:1265
#define Assert(condition)
Definition: c.h:670
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1220
#define elog
Definition: elog.h:219
#define ftruncate(a, b)
Definition: win32_port.h:60

◆ FileWrite()

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

Definition at line 1738 of file fd.c.

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

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

1739 {
1740  int returnCode;
1741  Vfd *vfdP;
1742 
1743  Assert(FileIsValid(file));
1744 
1745  DO_DB(elog(LOG, "FileWrite: %d (%s) " INT64_FORMAT " %d %p",
1746  file, VfdCache[file].fileName,
1747  (int64) VfdCache[file].seekPos,
1748  amount, buffer));
1749 
1750  returnCode = FileAccess(file);
1751  if (returnCode < 0)
1752  return returnCode;
1753 
1754  vfdP = &VfdCache[file];
1755 
1756  /*
1757  * If enforcing temp_file_limit and it's a temp file, check to see if the
1758  * write would overrun temp_file_limit, and throw error if so. Note: it's
1759  * really a modularity violation to throw error here; we should set errno
1760  * and return -1. However, there's no way to report a suitable error
1761  * message if we do that. All current callers would just throw error
1762  * immediately anyway, so this is safe at present.
1763  */
1764  if (temp_file_limit >= 0 && (vfdP->fdstate & FD_TEMPORARY))
1765  {
1766  off_t newPos;
1767 
1768  /*
1769  * Normally we should know the seek position, but if for some reason
1770  * we have lost track of it, try again to get it. Here, it's fine to
1771  * throw an error if we still can't get it.
1772  */
1773  if (FilePosIsUnknown(vfdP->seekPos))
1774  {
1775  vfdP->seekPos = lseek(vfdP->fd, (off_t) 0, SEEK_CUR);
1776  if (FilePosIsUnknown(vfdP->seekPos))
1777  elog(ERROR, "could not seek file \"%s\": %m", vfdP->fileName);
1778  }
1779 
1780  newPos = vfdP->seekPos + amount;
1781  if (newPos > vfdP->fileSize)
1782  {
1783  uint64 newTotal = temporary_files_size;
1784 
1785  newTotal += newPos - vfdP->fileSize;
1786  if (newTotal > (uint64) temp_file_limit * (uint64) 1024)
1787  ereport(ERROR,
1788  (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
1789  errmsg("temporary file size exceeds temp_file_limit (%dkB)",
1790  temp_file_limit)));
1791  }
1792  }
1793 
1794 retry:
1795  errno = 0;
1796  pgstat_report_wait_start(wait_event_info);
1797  returnCode = write(vfdP->fd, buffer, amount);
1799 
1800  /* if write didn't set errno, assume problem is no disk space */
1801  if (returnCode != amount && errno == 0)
1802  errno = ENOSPC;
1803 
1804  if (returnCode >= 0)
1805  {
1806  /* if seekPos is unknown, leave it that way */
1807  if (!FilePosIsUnknown(vfdP->seekPos))
1808  vfdP->seekPos += returnCode;
1809 
1810  /*
1811  * Maintain fileSize and temporary_files_size if it's a temp file.
1812  *
1813  * If seekPos is -1 (unknown), this will do nothing; but we could only
1814  * get here in that state if we're not enforcing temporary_files_size,
1815  * so we don't care.
1816  */
1817  if (vfdP->fdstate & FD_TEMPORARY)
1818  {
1819  off_t newPos = vfdP->seekPos;
1820 
1821  if (newPos > vfdP->fileSize)
1822  {
1823  temporary_files_size += newPos - vfdP->fileSize;
1824  vfdP->fileSize = newPos;
1825  }
1826  }
1827  }
1828  else
1829  {
1830  /*
1831  * See comments in FileRead()
1832  */
1833 #ifdef WIN32
1834  DWORD error = GetLastError();
1835 
1836  switch (error)
1837  {
1838  case ERROR_NO_SYSTEM_RESOURCES:
1839  pg_usleep(1000L);
1840  errno = EINTR;
1841  break;
1842  default:
1843  _dosmaperr(error);
1844  break;
1845  }
1846 #endif
1847  /* OK to retry if interrupted */
1848  if (errno == EINTR)
1849  goto retry;
1850 
1851  /* Trouble, so assume we don't know the file position anymore */
1852  vfdP->seekPos = FileUnknownPos;
1853  }
1854 
1855  return returnCode;
1856 }
static void error(void)
Definition: sql-dyntest.c:147
#define write(a, b, c)
Definition: win32.h:14
#define DO_DB(A)
Definition: fd.c:157
void _dosmaperr(unsigned long)
Definition: win32error.c:171
static Vfd * VfdCache
Definition: fd.c:202
int errcode(int sqlerrcode)
Definition: elog.c:575
#define LOG
Definition: elog.h:26
#define FilePosIsUnknown(pos)
Definition: fd.c:175
void pg_usleep(long microsec)
Definition: signal.c:53
#define ERROR
Definition: elog.h:43
char * fileName
Definition: fd.c:191
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1244
off_t seekPos
Definition: fd.c:189
unsigned short fdstate
Definition: fd.c:184
Definition: fd.c:181
off_t fileSize
Definition: fd.c:190
int fd
Definition: fd.c:183
#define ereport(elevel, rest)
Definition: elog.h:122
#define FD_TEMPORARY
Definition: fd.c:178
#define FileIsValid(file)
Definition: fd.c:163
static uint64 temporary_files_size
Definition: fd.c:222
static int FileAccess(File file)
Definition: fd.c:1265
#define Assert(condition)
Definition: c.h:670
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1220
#define INT64_FORMAT
Definition: c.h:338
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
#define EINTR
Definition: win32_port.h:334
#define FileUnknownPos
Definition: fd.c:174
int temp_file_limit
Definition: guc.c:458

◆ FileWriteback()

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

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

1648 {
1649  int returnCode;
1650 
1651  Assert(FileIsValid(file));
1652 
1653  DO_DB(elog(LOG, "FileWriteback: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
1654  file, VfdCache[file].fileName,
1655  (int64) offset, (int64) nbytes));
1656 
1657  /*
1658  * Caution: do not call pg_flush_data with nbytes = 0, it could trash the
1659  * file's seek position. We prefer to define that as a no-op here.
1660  */
1661  if (nbytes <= 0)
1662  return;
1663 
1664  returnCode = FileAccess(file);
1665  if (returnCode < 0)
1666  return;
1667 
1668  pgstat_report_wait_start(wait_event_info);
1669  pg_flush_data(VfdCache[file].fd, offset, nbytes);
1671 }
#define DO_DB(A)
Definition: fd.c:157
static Vfd * VfdCache
Definition: fd.c:202
#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:1244
void pg_flush_data(int fd, off_t offset, off_t nbytes)
Definition: fd.c:412
#define FileIsValid(file)
Definition: fd.c:163
static int FileAccess(File file)
Definition: fd.c:1265
#define Assert(condition)
Definition: c.h:670
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1220
#define INT64_FORMAT
Definition: c.h:338
#define elog
Definition: elog.h:219

◆ FreeDesc()

static int FreeDesc ( AllocateDesc desc)
static

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

2277 {
2278  int result;
2279 
2280  /* Close the underlying object */
2281  switch (desc->kind)
2282  {
2283  case AllocateDescFile:
2284  result = fclose(desc->desc.file);
2285  break;
2286  case AllocateDescPipe:
2287  result = pclose(desc->desc.file);
2288  break;
2289  case AllocateDescDir:
2290  result = closedir(desc->desc.dir);
2291  break;
2292  case AllocateDescRawFD:
2293  result = close(desc->desc.fd);
2294  break;
2295  default:
2296  elog(ERROR, "AllocateDesc kind not recognized");
2297  result = 0; /* keep compiler quiet */
2298  break;
2299  }
2300 
2301  /* Compact storage in the allocatedDescs array */
2304 
2305  return result;
2306 }
static AllocateDesc * allocatedDescs
Definition: fd.c:250
DIR * dir
Definition: fd.c:243
int closedir(DIR *)
Definition: dirent.c:111
AllocateDescKind kind
Definition: fd.c:238
#define ERROR
Definition: elog.h:43
FILE * file
Definition: fd.c:242
int fd
Definition: fd.c:244
union AllocateDesc::@27 desc
#define elog
Definition: elog.h:219
#define close(a)
Definition: win32.h:12
static int numAllocatedDescs
Definition: fd.c:248

◆ FreeDir()

int FreeDir ( DIR dir)

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

2483 {
2484  int i;
2485 
2486  DO_DB(elog(LOG, "FreeDir: Allocated %d", numAllocatedDescs));
2487 
2488  /* Remove dir from list of allocated dirs, if it's present */
2489  for (i = numAllocatedDescs; --i >= 0;)
2490  {
2491  AllocateDesc *desc = &allocatedDescs[i];
2492 
2493  if (desc->kind == AllocateDescDir && desc->desc.dir == dir)
2494  return FreeDesc(desc);
2495  }
2496 
2497  /* Only get here if someone passes us a dir not in allocatedDescs */
2498  elog(WARNING, "dir passed to FreeDir was not obtained from AllocateDir");
2499 
2500  return closedir(dir);
2501 }
static AllocateDesc * allocatedDescs
Definition: fd.c:250
DIR * dir
Definition: fd.c:243
#define DO_DB(A)
Definition: fd.c:157
int closedir(DIR *)
Definition: dirent.c:111
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:238
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2276
#define WARNING
Definition: elog.h:40
union AllocateDesc::@27 desc
int i
#define elog
Definition: elog.h:219
static int numAllocatedDescs
Definition: fd.c:248

◆ FreeFile()

int FreeFile ( FILE *  file)

Definition at line 2315 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(), checkDataDir(), 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(), PGSharedMemoryIsInUse(), 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(), readRecoveryCommandFile(), readTimeLineHistory(), sendFile(), tokenize_inc_file(), tsearch_readline_end(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

2316 {
2317  int i;
2318 
2319  DO_DB(elog(LOG, "FreeFile: Allocated %d", numAllocatedDescs));
2320 
2321  /* Remove file from list of allocated files, if it's present */
2322  for (i = numAllocatedDescs; --i >= 0;)
2323  {
2324  AllocateDesc *desc = &allocatedDescs[i];
2325 
2326  if (desc->kind == AllocateDescFile && desc->desc.file == file)
2327  return FreeDesc(desc);
2328  }
2329 
2330  /* Only get here if someone passes us a file not in allocatedDescs */
2331  elog(WARNING, "file passed to FreeFile was not obtained from AllocateFile");
2332 
2333  return fclose(file);
2334 }
static AllocateDesc * allocatedDescs
Definition: fd.c:250
#define DO_DB(A)
Definition: fd.c:157
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:238
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2276
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:242
union AllocateDesc::@27 desc
int i
#define elog
Definition: elog.h:219
static int numAllocatedDescs
Definition: fd.c:248

◆ FreeVfd()

static void FreeVfd ( File  file)
static

Definition at line 1245 of file fd.c.

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

Referenced by FileClose(), and PathNameOpenFilePerm().

1246 {
1247  Vfd *vfdP = &VfdCache[file];
1248 
1249  DO_DB(elog(LOG, "FreeVfd: %d (%s)",
1250  file, vfdP->fileName ? vfdP->fileName : ""));
1251 
1252  if (vfdP->fileName != NULL)
1253  {
1254  free(vfdP->fileName);
1255  vfdP->fileName = NULL;
1256  }
1257  vfdP->fdstate = 0x0;
1258 
1259  vfdP->nextFree = VfdCache[0].nextFree;
1260  VfdCache[0].nextFree = file;
1261 }
File nextFree
Definition: fd.c:186
#define DO_DB(A)
Definition: fd.c:157
static Vfd * VfdCache
Definition: fd.c:202
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:191
unsigned short fdstate
Definition: fd.c:184
Definition: fd.c:181
#define free(a)
Definition: header.h:65
#define elog
Definition: elog.h:219

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

3165 {
3166  int fd;
3167  int flags;
3168  int returncode;
3169 
3170  /*
3171  * Some OSs require directories to be opened read-only whereas other
3172  * systems don't allow us to fsync files opened read-only; so we need both
3173  * cases here. Using O_RDWR will cause us to fail to fsync files that are
3174  * not writable by our userid, but we assume that's OK.
3175  */
3176  flags = PG_BINARY;
3177  if (!isdir)
3178  flags |= O_RDWR;
3179  else
3180  flags |= O_RDONLY;
3181 
3182  fd = OpenTransientFile(fname, flags);
3183 
3184  /*
3185  * Some OSs don't allow us to open directories at all (Windows returns
3186  * EACCES), just ignore the error in that case. If desired also silently
3187  * ignoring errors about unreadable files. Log others.
3188  */
3189  if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES))
3190  return 0;
3191  else if (fd < 0 && ignore_perm && errno == EACCES)
3192  return 0;
3193  else if (fd < 0)
3194  {
3195  ereport(elevel,
3197  errmsg("could not open file \"%s\": %m", fname)));
3198  return -1;
3199  }
3200 
3201  returncode = pg_fsync(fd);
3202 
3203  /*
3204  * Some OSes don't allow us to fsync directories at all, so we can ignore
3205  * those errors. Anything else needs to be logged.
3206  */
3207  if (returncode != 0 && !(isdir && errno == EBADF))
3208  {
3209  int save_errno;
3210 
3211  /* close file upon error, might not be in transaction context */
3212  save_errno = errno;
3213  (void) CloseTransientFile(fd);
3214  errno = save_errno;
3215 
3216  ereport(elevel,
3218  errmsg("could not fsync file \"%s\": %m", fname)));
3219  return -1;
3220  }
3221 
3222  (void) CloseTransientFile(fd);
3223 
3224  return 0;
3225 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1025
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2173
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
int CloseTransientFile(int fd)
Definition: fd.c:2343
static int elevel
Definition: vacuumlazy.c:136
int errmsg(const char *fmt,...)
Definition: elog.c:797
int pg_fsync(int fd)
Definition: fd.c:338

◆ fsync_parent_path()

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

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

3235 {
3236  char parentpath[MAXPGPATH];
3237 
3238  strlcpy(parentpath, fname, MAXPGPATH);
3239  get_parent_directory(parentpath);
3240 
3241  /*
3242  * get_parent_directory() returns an empty string if the input argument is
3243  * just a file name (see comments in path.c), so handle that as being the
3244  * current directory.
3245  */
3246  if (strlen(parentpath) == 0)
3247  strlcpy(parentpath, ".", MAXPGPATH);
3248 
3249  if (fsync_fname_ext(parentpath, true, false, elevel) != 0)
3250  return -1;
3251 
3252  return 0;
3253 }
#define MAXPGPATH
void get_parent_directory(char *path)
Definition: path.c:854
static int elevel
Definition: vacuumlazy.c:136
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:3164

◆ GetNextTempTableSpace()

Oid GetNextTempTableSpace ( void  )

Definition at line 2603 of file fd.c.

References InvalidOid, nextTempTableSpace, numTempTableSpaces, and tempTableSpaces.

Referenced by GetDefaultTablespace(), and OpenTemporaryFile().

2604 {
2605  if (numTempTableSpaces > 0)
2606  {
2607  /* Advance nextTempTableSpace counter with wraparound */
2609  nextTempTableSpace = 0;
2611  }
2612  return InvalidOid;
2613 }
static int numTempTableSpaces
Definition: fd.c:263
static int nextTempTableSpace
Definition: fd.c:264
#define InvalidOid
Definition: postgres_ext.h:36
static Oid * tempTableSpaces
Definition: fd.c:262

◆ InitFileAccess()

void InitFileAccess ( void  )

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

770 {
771  Assert(SizeVfdCache == 0); /* call me only once */
772 
773  /* initialize cache header entry */
774  VfdCache = (Vfd *) malloc(sizeof(Vfd));
775  if (VfdCache == NULL)
776  ereport(FATAL,
777  (errcode(ERRCODE_OUT_OF_MEMORY),
778  errmsg("out of memory")));
779 
780  MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));
782 
783  SizeVfdCache = 1;
784 
785  /* register proc-exit hook to ensure temp files are dropped at exit */
787 }
static void AtProcExit_Files(int code, Datum arg)
Definition: fd.c:2669
static Size SizeVfdCache
Definition: fd.c:203
void on_proc_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:292
static Vfd * VfdCache
Definition: fd.c:202
int errcode(int sqlerrcode)
Definition: elog.c:575
#define MemSet(start, val, len)
Definition: c.h:853
#define malloc(a)
Definition: header.h:50
#define FATAL
Definition: elog.h:52
Definition: fd.c:181
int fd
Definition: fd.c:183
#define ereport(elevel, rest)
Definition: elog.h:122
#define VFD_CLOSED
Definition: fd.c:161
#define Assert(condition)
Definition: c.h:670
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ Insert()

static void Insert ( File  file)
static

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

1060 {
1061  Vfd *vfdP;
1062 
1063  Assert(file != 0);
1064 
1065  DO_DB(elog(LOG, "Insert %d (%s)",
1066  file, VfdCache[file].fileName));
1067  DO_DB(_dump_lru());
1068 
1069  vfdP = &VfdCache[file];
1070 
1071  vfdP->lruMoreRecently = 0;
1073  VfdCache[0].lruLessRecently = file;
1075 
1076  DO_DB(_dump_lru());
1077 }
File lruLessRecently
Definition: fd.c:188
#define DO_DB(A)
Definition: fd.c:157
static Vfd * VfdCache
Definition: fd.c:202
#define LOG
Definition: elog.h:26
Definition: fd.c:181
#define Assert(condition)
Definition: c.h:670
File lruMoreRecently
Definition: fd.c:187
#define elog
Definition: elog.h:219

◆ looks_like_temp_rel_name()

static bool looks_like_temp_rel_name ( const char *  name)
static

Definition at line 2904 of file fd.c.

References forkname_chars().

Referenced by RemovePgTempRelationFilesInDbspace().

2905 {
2906  int pos;
2907  int savepos;
2908 
2909  /* Must start with "t". */
2910  if (name[0] != 't')
2911  return false;
2912 
2913  /* Followed by a non-empty string of digits and then an underscore. */
2914  for (pos = 1; isdigit((unsigned char) name[pos]); ++pos)
2915  ;
2916  if (pos == 1 || name[pos] != '_')
2917  return false;
2918 
2919  /* Followed by another nonempty string of digits. */
2920  for (savepos = ++pos; isdigit((unsigned char) name[pos]); ++pos)
2921  ;
2922  if (savepos == pos)
2923  return false;
2924 
2925  /* We might have _forkname or .segment or both. */
2926  if (name[pos] == '_')
2927  {
2928  int forkchar = forkname_chars(&name[pos + 1], NULL);
2929 
2930  if (forkchar <= 0)
2931  return false;
2932  pos += forkchar + 1;
2933  }
2934  if (name[pos] == '.')
2935  {
2936  int segchar;
2937 
2938  for (segchar = 1; isdigit((unsigned char) name[pos + segchar]); ++segchar)
2939  ;
2940  if (segchar <= 1)
2941  return false;
2942  pos += segchar;
2943  }
2944 
2945  /* Now we should be at the end. */
2946  if (name[pos] != '\0')
2947  return false;
2948  return true;
2949 }
int forkname_chars(const char *str, ForkNumber *fork)
Definition: relpath.c:79
const char * name
Definition: encode.c:521

◆ LruDelete()

static void LruDelete ( File  file)
static

Definition at line 1018 of file fd.c.

References Assert, close, Delete(), DO_DB, elog, vfd::fd, vfd::fileName, FilePosIsUnknown, LOG, nfile, vfd::seekPos, and VFD_CLOSED.

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

1019 {
1020  Vfd *vfdP;
1021 
1022  Assert(file != 0);
1023 
1024  DO_DB(elog(LOG, "LruDelete %d (%s)",
1025  file, VfdCache[file].fileName));
1026 
1027  vfdP = &VfdCache[file];
1028 
1029  /*
1030  * Normally we should know the seek position, but if for some reason we
1031  * have lost track of it, try again to get it. If we still can't get it,
1032  * we have a problem: we will be unable to restore the file seek position
1033  * when and if the file is re-opened. But we can't really throw an error
1034  * and refuse to close the file, or activities such as transaction cleanup
1035  * will be broken.
1036  */
1037  if (FilePosIsUnknown(vfdP->seekPos))
1038  {
1039  vfdP->seekPos = lseek(vfdP->fd, (off_t) 0, SEEK_CUR);
1040  if (FilePosIsUnknown(vfdP->seekPos))
1041  elog(LOG, "could not seek file \"%s\" before closing: %m",
1042  vfdP->fileName);
1043  }
1044 
1045  /*
1046  * Close the file. We aren't expecting this to fail; if it does, better
1047  * to leak the FD than to mess up our internal state.
1048  */
1049  if (close(vfdP->fd))
1050  elog(LOG, "could not close file \"%s\": %m", vfdP->fileName);
1051  vfdP->fd = VFD_CLOSED;
1052  --nfile;
1053 
1054  /* delete the vfd record from the LRU ring */
1055  Delete(file);
1056 }
#define DO_DB(A)
Definition: fd.c:157
static Vfd * VfdCache
Definition: fd.c:202
static void Delete(File file)
Definition: fd.c:999
#define LOG
Definition: elog.h:26
#define FilePosIsUnknown(pos)
Definition: fd.c:175
char * fileName
Definition: fd.c:191
static int nfile
Definition: fd.c:208
off_t seekPos
Definition: fd.c:189
Definition: fd.c:181
int fd
Definition: fd.c:183
#define VFD_CLOSED
Definition: fd.c:161
#define Assert(condition)
Definition: c.h:670
#define elog
Definition: elog.h:219
#define close(a)
Definition: win32.h:12

◆ LruInsert()

static int LruInsert ( File  file)
static

Definition at line 1081 of file fd.c.

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

Referenced by FileAccess().

1082 {
1083  Vfd *vfdP;
1084 
1085  Assert(file != 0);
1086 
1087  DO_DB(elog(LOG, "LruInsert %d (%s)",
1088  file, VfdCache[file].fileName));
1089 
1090  vfdP = &VfdCache[file];
1091 
1092  if (FileIsNotOpen(file))
1093  {
1094  /* Close excess kernel FDs. */
1095  ReleaseLruFiles();
1096 
1097  /*
1098  * The open could still fail for lack of file descriptors, eg due to
1099  * overall system file table being full. So, be prepared to release
1100  * another FD if necessary...
1101  */
1102  vfdP->fd = BasicOpenFilePerm(vfdP->fileName, vfdP->fileFlags,
1103  vfdP->fileMode);
1104  if (vfdP->fd < 0)
1105  {
1106  DO_DB(elog(LOG, "re-open failed: %m"));
1107  return -1;
1108  }
1109  else
1110  {
1111  ++nfile;
1112  }
1113 
1114  /*
1115  * Seek to the right position. We need no special case for seekPos
1116  * equal to FileUnknownPos, as lseek() will certainly reject that
1117  * (thus completing the logic noted in LruDelete() that we will fail
1118  * to re-open a file if we couldn't get its seek position before
1119  * closing).
1120  */
1121  if (vfdP->seekPos != (off_t) 0)
1122  {
1123  if (lseek(vfdP->fd, vfdP->seekPos, SEEK_SET) < 0)
1124  {
1125  /*
1126  * If we fail to restore the seek position, treat it like an
1127  * open() failure.
1128  */
1129  int save_errno = errno;
1130 
1131  elog(LOG, "could not seek file \"%s\" after re-opening: %m",
1132  vfdP->fileName);
1133  (void) close(vfdP->fd);
1134  vfdP->fd = VFD_CLOSED;
1135  --nfile;
1136  errno = save_errno;
1137  return -1;
1138  }
1139  }
1140  }
1141 
1142  /*
1143  * put it at the head of the Lru ring
1144  */
1145 
1146  Insert(file);
1147 
1148  return 0;
1149 }
#define DO_DB(A)
Definition: fd.c:157
static Vfd * VfdCache
Definition: fd.c:202
#define LOG
Definition: elog.h:26
mode_t fileMode
Definition: fd.c:194
char * fileName
Definition: fd.c:191
static int nfile
Definition: fd.c:208
off_t seekPos
Definition: fd.c:189
Definition: fd.c:181
int fd
Definition: fd.c:183
static void Insert(File file)
Definition: fd.c:1059
static void ReleaseLruFiles(void)
Definition: fd.c:1177
#define FileIsNotOpen(file)
Definition: fd.c:166
#define VFD_CLOSED
Definition: fd.c:161
#define Assert(condition)
Definition: c.h:670
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:951
#define elog
Definition: elog.h:219
#define close(a)
Definition: win32.h:12
int fileFlags
Definition: fd.c:193

◆ OpenPipeStream()

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

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

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

2223 {
2224  FILE *file;
2225 
2226  DO_DB(elog(LOG, "OpenPipeStream: Allocated %d (%s)",
2227  numAllocatedDescs, command));
2228 
2229  /* Can we allocate another non-virtual FD? */
2230  if (!reserveAllocatedDesc())
2231  ereport(ERROR,
2232  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2233  errmsg("exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"",
2234  maxAllocatedDescs, command)));
2235 
2236  /* Close excess kernel FDs. */
2237  ReleaseLruFiles();
2238 
2239 TryAgain:
2240  fflush(stdout);
2241  fflush(stderr);
2242  errno = 0;
2243  if ((file = popen(command, mode)) != NULL)
2244  {
2246 
2247  desc->kind = AllocateDescPipe;
2248  desc->desc.file = file;
2251  return desc->desc.file;
2252  }
2253 
2254  if (errno == EMFILE || errno == ENFILE)
2255  {
2256  int save_errno = errno;
2257 
2258  ereport(LOG,
2259  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2260  errmsg("out of file descriptors: %m; release and retry")));
2261  errno = 0;
2262  if (ReleaseLruFile())
2263  goto TryAgain;
2264  errno = save_errno;
2265  }
2266 
2267  return NULL;
2268 }
static AllocateDesc * allocatedDescs
Definition: fd.c:250
#define DO_DB(A)
Definition: fd.c:157
int errcode(int sqlerrcode)
Definition: elog.c:575
static bool reserveAllocatedDesc(void)
Definition: fd.c:2050
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:238
static bool ReleaseLruFile(void)
Definition: fd.c:1155
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static void ReleaseLruFiles(void)
Definition: fd.c:1177
FILE * file
Definition: fd.c:242
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:642
SubTransactionId create_subid
Definition: fd.c:239
int errmsg(const char *fmt,...)
Definition: elog.c:797
union AllocateDesc::@27 desc
#define elog
Definition: elog.h:219
static int maxAllocatedDescs
Definition: fd.c:249
static int numAllocatedDescs
Definition: fd.c:248

◆ OpenTemporaryFile()

File OpenTemporaryFile ( bool  interXact)

Definition at line 1396 of file fd.c.

References CurrentResourceOwner, DEFAULTTABLESPACE_OID, FD_TEMPORARY, FD_XACT_TEMPORARY, vfd::fdstate, GetNextTempTableSpace(), have_xact_temporary_files, MyDatabaseTableSpace, numTempTableSpaces, OidIsValid, OpenTemporaryFileInTablespace(), ResourceOwnerEnlargeFiles(), ResourceOwnerRememberFile(), and vfd::resowner.

Referenced by BufFileCreateTemp(), and extendBufFile().

1397 {
1398  File file = 0;
1399 
1400  /*
1401  * Make sure the current resource owner has space for this File before we
1402  * open it, if we'll be registering it below.
1403  */
1404  if (!interXact)
1406 
1407  /*
1408  * If some temp tablespace(s) have been given to us, try to use the next
1409  * one. If a given tablespace can't be found, we silently fall back to
1410  * the database's default tablespace.
1411  *
1412  * BUT: if the temp file is slated to outlive the current transaction,
1413  * force it into the database's default tablespace, so that it will not
1414  * pose a threat to possible tablespace drop attempts.
1415  */
1416  if (numTempTableSpaces > 0 && !interXact)
1417  {
1418  Oid tblspcOid = GetNextTempTableSpace();
1419 
1420  if (OidIsValid(tblspcOid))
1421  file = OpenTemporaryFileInTablespace(tblspcOid, false);
1422  }
1423 
1424  /*
1425  * If not, or if tablespace is bad, create in database's default
1426  * tablespace. MyDatabaseTableSpace should normally be set before we get
1427  * here, but just in case it isn't, fall back to pg_default tablespace.
1428  */
1429  if (file <= 0)
1433  true);
1434 
1435  /* Mark it for deletion at close */
1436  VfdCache[file].fdstate |= FD_TEMPORARY;
1437 
1438  /* Register it with the current resource owner */
1439  if (!interXact)
1440  {
1442 
1445 
1446  /* ensure cleanup happens at eoxact */
1448  }
1449 
1450  return file;
1451 }
static File OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError)
Definition: fd.c:1458
ResourceOwner CurrentResourceOwner
Definition: resowner.c:138
static Vfd * VfdCache
Definition: fd.c:202
static int numTempTableSpaces
Definition: fd.c:263
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:576
Oid MyDatabaseTableSpace
Definition: globals.c:79
static bool have_xact_temporary_files
Definition: fd.c:214
Oid GetNextTempTableSpace(void)
Definition: fd.c:2603
void ResourceOwnerRememberFile(ResourceOwner owner, File file)
Definition: resowner.c:1186
#define DEFAULTTABLESPACE_OID
Definition: pg_tablespace.h:63
unsigned short fdstate
Definition: fd.c:184
ResourceOwner resowner
Definition: fd.c:185
#define FD_TEMPORARY
Definition: fd.c:178
#define FD_XACT_TEMPORARY
Definition: fd.c:179
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1175
int File
Definition: fd.h:49

◆ OpenTemporaryFileInTablespace()

static File OpenTemporaryFileInTablespace ( Oid  tblspcOid,
bool  rejectError 
)
static

Definition at line 1458 of file fd.c.

References DEFAULTTABLESPACE_OID, elog, ERROR, GLOBALTABLESPACE_OID, MAXPGPATH, mkdir, MyProcPid, PathNameOpenFile(), PG_BINARY, PG_TEMP_FILE_PREFIX, PG_TEMP_FILES_DIR, S_IRWXU, snprintf(), TABLESPACE_VERSION_DIRECTORY, and tempFileCounter.

Referenced by OpenTemporaryFile().

1459 {
1460  char tempdirpath[MAXPGPATH];
1461  char tempfilepath[MAXPGPATH];
1462  File file;
1463 
1464  /*
1465  * Identify the tempfile directory for this tablespace.
1466  *
1467  * If someone tries to specify pg_global, use pg_default instead.
1468  */
1469  if (tblspcOid == DEFAULTTABLESPACE_OID ||
1470  tblspcOid == GLOBALTABLESPACE_OID)
1471  {
1472  /* The default tablespace is {datadir}/base */
1473  snprintf(tempdirpath, sizeof(tempdirpath), "base/%s",
1475  }
1476  else
1477  {
1478  /* All other tablespaces are accessed via symlinks */
1479  snprintf(tempdirpath, sizeof(tempdirpath), "pg_tblspc/%u/%s/%s",
1481  }
1482 
1483  /*
1484  * Generate a tempfile name that should be unique within the current
1485  * database instance.
1486  */
1487  snprintf(tempfilepath, sizeof(tempfilepath), "%s/%s%d.%ld",
1488  tempdirpath, PG_TEMP_FILE_PREFIX, MyProcPid, tempFileCounter++);
1489 
1490  /*
1491  * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1492  * temp file that can be reused.
1493  */
1494  file = PathNameOpenFile(tempfilepath,
1495  O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1496  if (file <= 0)
1497  {
1498  /*
1499  * We might need to create the tablespace's tempfile directory, if no
1500  * one has yet done so.
1501  *
1502  * Don't check for error from mkdir; it could fail if someone else
1503  * just did the same thing. If it doesn't work then we'll bomb out on
1504  * the second create attempt, instead.
1505  */
1506  mkdir(tempdirpath, S_IRWXU);
1507 
1508  file = PathNameOpenFile(tempfilepath,
1509  O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1510  if (file <= 0 && rejectError)
1511  elog(ERROR, "could not create temporary file \"%s\": %m",
1512  tempfilepath);
1513  }
1514 
1515  return file;
1516 }
int MyProcPid
Definition: globals.c:39
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1315
#define GLOBALTABLESPACE_OID
Definition: pg_tablespace.h:64
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define PG_TEMP_FILE_PREFIX
Definition: fd.h:129
#define PG_BINARY
Definition: c.h:1025
#define ERROR
Definition: elog.h:43
#define MAXPGPATH
#define DEFAULTTABLESPACE_OID
Definition: pg_tablespace.h:63
#define PG_TEMP_FILES_DIR
Definition: fd.h:128
#define TABLESPACE_VERSION_DIRECTORY
Definition: catalog.h:26
static long tempFileCounter
Definition: fd.c:256
#define S_IRWXU
Definition: win32_port.h:280
#define elog
Definition: elog.h:219
#define mkdir(a, b)
Definition: win32_port.h:58
int File
Definition: fd.h:49

◆ OpenTransientFile()

◆ OpenTransientFilePerm()

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

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

2183 {
2184  int fd;
2185 
2186  DO_DB(elog(LOG, "OpenTransientFile: Allocated %d (%s)",
2187  numAllocatedDescs, fileName));
2188 
2189  /* Can we allocate another non-virtual FD? */
2190  if (!reserveAllocatedDesc())
2191  ereport(ERROR,
2192  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2193  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2194  maxAllocatedDescs, fileName)));
2195 
2196  /* Close excess kernel FDs. */
2197  ReleaseLruFiles();
2198 
2199  fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
2200 
2201  if (fd >= 0)
2202  {
2204 
2205  desc->kind = AllocateDescRawFD;
2206  desc->desc.fd = fd;
2209 
2210  return fd;
2211  }
2212 
2213  return -1; /* failure */
2214 }
static AllocateDesc * allocatedDescs
Definition: fd.c:250
#define DO_DB(A)
Definition: fd.c:157
int errcode(int sqlerrcode)
Definition: elog.c:575
static bool reserveAllocatedDesc(void)
Definition: fd.c:2050
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:238
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:122
static void ReleaseLruFiles(void)
Definition: fd.c:1177
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:642
SubTransactionId create_subid
Definition: fd.c:239
int fd
Definition: fd.c:244
int errmsg(const char *fmt,...)
Definition: elog.c:797
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:951
union AllocateDesc::@27 desc
#define elog
Definition: elog.h:219
static int maxAllocatedDescs
Definition: fd.c:249
static int numAllocatedDescs
Definition: fd.c:248

◆ PathNameOpenFile()

File PathNameOpenFile ( const char *  fileName,
int  fileFlags 
)

Definition at line 1315 of file fd.c.

References PathNameOpenFilePerm(), and PG_FILE_MODE_DEFAULT.

Referenced by _mdfd_openseg(), logical_rewrite_log_mapping(), mdcreate(), mdopen(), and OpenTemporaryFileInTablespace().

1316 {
1317  return PathNameOpenFilePerm(fileName, fileFlags, PG_FILE_MODE_DEFAULT);
1318 }
File PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1328
#define PG_FILE_MODE_DEFAULT
Definition: fd.c:123

◆ PathNameOpenFilePerm()

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

Definition at line 1328 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(), vfd::resowner, and vfd::seekPos.

Referenced by PathNameOpenFile().

1329 {
1330  char *fnamecopy;
1331  File file;
1332  Vfd *vfdP;
1333 
1334  DO_DB(elog(LOG, "PathNameOpenFilePerm: %s %x %o",
1335  fileName, fileFlags, fileMode));
1336 
1337  /*
1338  * We need a malloc'd copy of the file name; fail cleanly if no room.
1339  */
1340  fnamecopy = strdup(fileName);
1341  if (fnamecopy == NULL)
1342  ereport(ERROR,
1343  (errcode(ERRCODE_OUT_OF_MEMORY),
1344  errmsg("out of memory")));
1345 
1346  file = AllocateVfd();
1347  vfdP = &VfdCache[file];
1348 
1349  /* Close excess kernel FDs. */
1350  ReleaseLruFiles();
1351 
1352  vfdP->fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
1353 
1354  if (vfdP->fd < 0)
1355  {
1356  int save_errno = errno;
1357 
1358  FreeVfd(file);
1359  free(fnamecopy);
1360  errno = save_errno;
1361  return -1;
1362  }
1363  ++nfile;
1364  DO_DB(elog(LOG, "PathNameOpenFile: success %d",
1365  vfdP->fd));
1366 
1367  Insert(file);
1368 
1369  vfdP->fileName = fnamecopy;
1370  /* Saved flags are adjusted to be OK for re-opening file */
1371  vfdP->fileFlags = fileFlags & ~(O_CREAT | O_TRUNC | O_EXCL);
1372  vfdP->fileMode = fileMode;
1373  vfdP->seekPos = 0;
1374  vfdP->fileSize = 0;
1375  vfdP->fdstate = 0x0;
1376  vfdP->resowner = NULL;
1377 
1378  return file;
1379 }
#define DO_DB(A)
Definition: fd.c:157
static Vfd * VfdCache
Definition: fd.c:202
int errcode(int sqlerrcode)
Definition: elog.c:575
#define LOG
Definition: elog.h:26
mode_t fileMode
Definition: fd.c:194
#define ERROR
Definition: elog.h:43
char * fileName
Definition: fd.c:191
static int nfile
Definition: fd.c:208
static File AllocateVfd(void)
Definition: fd.c:1187
off_t seekPos
Definition: fd.c:189
unsigned short fdstate
Definition: fd.c:184
Definition: fd.c:181
off_t fileSize
Definition: fd.c:190
int fd
Definition: fd.c:183
#define ereport(elevel, rest)
Definition: elog.h:122
static void Insert(File file)
Definition: fd.c:1059
ResourceOwner resowner
Definition: fd.c:185
static void ReleaseLruFiles(void)
Definition: fd.c:1177
#define free(a)
Definition: header.h:65
int errmsg(const char *fmt,...)
Definition: elog.c:797
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:951
static void FreeVfd(File file)
Definition: fd.c:1245
#define elog
Definition: elog.h:219
int fileFlags
Definition: fd.c:193
int File
Definition: fd.h:49

◆ pg_fdatasync()

int pg_fdatasync ( int  fd)

Definition at line 390 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync().

391 {
392  if (enableFsync)
393  {
394 #ifdef HAVE_FDATASYNC
395  return fdatasync(fd);
396 #else
397  return fsync(fd);
398 #endif
399  }
400  else
401  return 0;
402 }
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:111

◆ pg_flush_data()

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

Definition at line 412 of file fd.c.

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

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

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

◆ pg_fsync()

int pg_fsync ( int  fd)

Definition at line 338 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(), RecreateTwoPhaseFile(), RestoreSlotFromDisk(), SaveSlotToPath(), SimpleLruFlush(), SlruPhysicalWritePage(), SnapBuildSerialize(), UpdateControlFile(), write_auto_conf_file(), write_relmap_file(), WriteControlFile(), writeTimeLineHistory(), writeTimeLineHistoryFile(), XLogFileCopy(), and XLogFileInit().

339 {
340  /* #if is to skip the sync_method test if there's no need for it */
341 #if defined(HAVE_FSYNC_WRITETHROUGH) && !defined(FSYNC_WRITETHROUGH_IS_FSYNC)
343  return pg_fsync_writethrough(fd);
344  else
345 #endif
347 }
#define SYNC_METHOD_FSYNC_WRITETHROUGH
Definition: xlog.h:28
int pg_fsync_writethrough(int fd)
Definition: fd.c:367
int pg_fsync_no_writethrough(int fd)
Definition: fd.c:355
static int fd(const char *x, int i)
Definition: preproc-init.c:105
int sync_method
Definition: xlog.c:103

◆ pg_fsync_no_writethrough()

int pg_fsync_no_writethrough ( int  fd)

Definition at line 355 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync(), and pg_fsync().

356 {
357  if (enableFsync)
358  return fsync(fd);
359  else
360  return 0;
361 }
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:111

◆ pg_fsync_writethrough()

int pg_fsync_writethrough ( int  fd)

Definition at line 367 of file fd.c.

References enableFsync.

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

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

◆ ReadDir()

◆ ReadDirExtended()

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

Definition at line 2449 of file fd.c.

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

Referenced by ReadDir(), and walkdir().

2450 {
2451  struct dirent *dent;
2452 
2453  /* Give a generic message for AllocateDir failure, if caller didn't */
2454  if (dir == NULL)
2455  {
2456  ereport(elevel,
2458  errmsg("could not open directory \"%s\": %m",
2459  dirname)));
2460  return NULL;
2461  }
2462 
2463  errno = 0;
2464  if ((dent = readdir(dir)) != NULL)
2465  return dent;
2466 
2467  if (errno)
2468  ereport(elevel,
2470  errmsg("could not read directory \"%s\": %m",
2471  dirname)));
2472  return NULL;
2473 }
Definition: dirent.h:9
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
static int elevel
Definition: vacuumlazy.c:136
struct dirent * readdir(DIR *)
Definition: dirent.c:77
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ ReleaseLruFile()

static bool ReleaseLruFile ( void  )
static

Definition at line 1155 of file fd.c.

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

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

1156 {
1157  DO_DB(elog(LOG, "ReleaseLruFile. Opened %d", nfile));
1158 
1159  if (nfile > 0)
1160  {
1161  /*
1162  * There are opened files and so there should be at least one used vfd
1163  * in the ring.
1164  */
1165  Assert(VfdCache[0].lruMoreRecently != 0);
1166  LruDelete(VfdCache[0].lruMoreRecently);
1167  return true; /* freed a file */
1168  }
1169  return false; /* no files available to free */
1170 }
#define DO_DB(A)
Definition: fd.c:157
static Vfd * VfdCache
Definition: fd.c:202
#define LOG
Definition: elog.h:26
static void LruDelete(File file)
Definition: fd.c:1018
static int nfile
Definition: fd.c:208
#define Assert(condition)
Definition: c.h:670
#define elog
Definition: elog.h:219

◆ ReleaseLruFiles()

static void ReleaseLruFiles ( void  )
static

Definition at line 1177 of file fd.c.

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

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

1178 {
1179  while (nfile + numAllocatedDescs >= max_safe_fds)
1180  {
1181  if (!ReleaseLruFile())
1182  break;
1183  }
1184 }
int max_safe_fds
Definition: fd.c:144
static bool ReleaseLruFile(void)
Definition: fd.c:1155
static int nfile
Definition: fd.c:208
static int numAllocatedDescs
Definition: fd.c:248

◆ RemovePgTempFiles()

void RemovePgTempFiles ( void  )

Definition at line 2744 of file fd.c.

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

Referenced by PostmasterMain().

2745 {
2746  char temp_path[MAXPGPATH + 10 + sizeof(TABLESPACE_VERSION_DIRECTORY) + sizeof(PG_TEMP_FILES_DIR)];
2747  DIR *spc_dir;
2748  struct dirent *spc_de;
2749 
2750  /*
2751  * First process temp files in pg_default ($PGDATA/base)
2752  */
2753  snprintf(temp_path, sizeof(temp_path), "base/%s", PG_TEMP_FILES_DIR);
2754  RemovePgTempFilesInDir(temp_path);
2755  RemovePgTempRelationFiles("base");
2756 
2757  /*
2758  * Cycle through temp directories for all non-default tablespaces.
2759  */
2760  spc_dir = AllocateDir("pg_tblspc");
2761 
2762  while ((spc_de = ReadDir(spc_dir, "pg_tblspc")) != NULL)
2763  {
2764  if (strcmp(spc_de->d_name, ".") == 0 ||
2765  strcmp(spc_de->d_name, "..") == 0)
2766  continue;
2767 
2768  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s/%s",
2770  RemovePgTempFilesInDir(temp_path);
2771 
2772  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s",
2774  RemovePgTempRelationFiles(temp_path);
2775  }
2776 
2777  FreeDir(spc_dir);
2778 
2779  /*
2780  * In EXEC_BACKEND case there is a pgsql_tmp directory at the top level of
2781  * DataDir as well.
2782  */
2783 #ifdef EXEC_BACKEND
2785 #endif
2786 }
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
static void RemovePgTempFilesInDir(const char *tmpdirname)
Definition: fd.c:2790
Definition: dirent.h:9
static void RemovePgTempRelationFiles(const char *tsdirname)
Definition: fd.c:2831
Definition: dirent.c:25
#define MAXPGPATH
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2373
#define PG_TEMP_FILES_DIR
Definition: fd.h:128
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2439
#define TABLESPACE_VERSION_DIRECTORY
Definition: catalog.h:26
char d_name[MAX_PATH]
Definition: dirent.h:14
int FreeDir(DIR *dir)
Definition: fd.c:2482

◆ RemovePgTempFilesInDir()

static void RemovePgTempFilesInDir ( const char *  tmpdirname)
static

Definition at line 2790 of file fd.c.

References AllocateDir(), dirent::d_name, elog, FreeDir(), LOG, MAXPGPATH, PG_TEMP_FILE_PREFIX, ReadDir(), and snprintf().

Referenced by RemovePgTempFiles().

2791 {
2792  DIR *temp_dir;
2793  struct dirent *temp_de;
2794  char rm_path[MAXPGPATH * 2];
2795 
2796  temp_dir = AllocateDir(tmpdirname);
2797  if (temp_dir == NULL)
2798  {
2799  /* anything except ENOENT is fishy */
2800  if (errno != ENOENT)
2801  elog(LOG,
2802  "could not open temporary-files directory \"%s\": %m",
2803  tmpdirname);
2804  return;
2805  }
2806 
2807  while ((temp_de = ReadDir(temp_dir, tmpdirname)) != NULL)
2808  {
2809  if (strcmp(temp_de->d_name, ".") == 0 ||
2810  strcmp(temp_de->d_name, "..") == 0)
2811  continue;
2812 
2813  snprintf(rm_path, sizeof(rm_path), "%s/%s",
2814  tmpdirname, temp_de->d_name);
2815 
2816  if (strncmp(temp_de->d_name,
2818  strlen(PG_TEMP_FILE_PREFIX)) == 0)
2819  unlink(rm_path); /* note we ignore any error */
2820  else
2821  elog(LOG,
2822  "unexpected file found in temporary-files directory: \"%s\"",
2823  rm_path);
2824  }
2825 
2826  FreeDir(temp_dir);
2827 }
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define PG_TEMP_FILE_PREFIX
Definition: fd.h:129
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2373
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2439
char d_name[MAX_PATH]
Definition: dirent.h:14
#define elog
Definition: elog.h:219
int FreeDir(DIR *dir)
Definition: fd.c:2482

◆ RemovePgTempRelationFiles()

static void RemovePgTempRelationFiles ( const char *  tsdirname)
static

Definition at line 2831 of file fd.c.

References AllocateDir(), dirent::d_name, elog, FreeDir(), i, LOG, MAXPGPATH, ReadDir(), RemovePgTempRelationFilesInDbspace(), and snprintf().

Referenced by RemovePgTempFiles().

2832 {
2833  DIR *ts_dir;
2834  struct dirent *de;
2835  char dbspace_path[MAXPGPATH * 2];
2836 
2837  ts_dir = AllocateDir(tsdirname);
2838  if (ts_dir == NULL)
2839  {
2840  /* anything except ENOENT is fishy */
2841  if (errno != ENOENT)
2842  elog(LOG,
2843  "could not open tablespace directory \"%s\": %m",
2844  tsdirname);
2845  return;
2846  }
2847 
2848  while ((de = ReadDir(ts_dir, tsdirname)) != NULL)
2849  {
2850  int i = 0;
2851 
2852  /*
2853  * We're only interested in the per-database directories, which have
2854  * numeric names. Note that this code will also (properly) ignore "."
2855  * and "..".
2856  */
2857  while (isdigit((unsigned char) de->d_name[i]))
2858  ++i;
2859  if (de->d_name[i] != '\0' || i == 0)
2860  continue;
2861 
2862  snprintf(dbspace_path, sizeof(dbspace_path), "%s/%s",
2863  tsdirname, de->d_name);
2864  RemovePgTempRelationFilesInDbspace(dbspace_path);
2865  }
2866 
2867  FreeDir(ts_dir);
2868 }
static void RemovePgTempRelationFilesInDbspace(const char *dbspacedirname)
Definition: fd.c:2872
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2373
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2439
int i
char d_name[MAX_PATH]
Definition: dirent.h:14
#define elog
Definition: elog.h:219
int FreeDir(DIR *dir)
Definition: fd.c:2482

◆ RemovePgTempRelationFilesInDbspace()

static void RemovePgTempRelationFilesInDbspace ( const char *  dbspacedirname)
static

Definition at line 2872 of file fd.c.

References AllocateDir(), dirent::d_name, elog, FreeDir(), LOG, looks_like_temp_rel_name(), MAXPGPATH, ReadDir(), and snprintf().

Referenced by RemovePgTempRelationFiles().

2873 {
2874  DIR *dbspace_dir;
2875  struct dirent *de;
2876  char rm_path[MAXPGPATH * 2];
2877 
2878  dbspace_dir = AllocateDir(dbspacedirname);
2879  if (dbspace_dir == NULL)
2880  {
2881  /* we just saw this directory, so it really ought to be there */
2882  elog(LOG,
2883  "could not open dbspace directory \"%s\": %m",
2884  dbspacedirname);
2885  return;
2886  }
2887 
2888  while ((de = ReadDir(dbspace_dir, dbspacedirname)) != NULL)
2889  {
2890  if (!looks_like_temp_rel_name(de->d_name))
2891  continue;
2892 
2893  snprintf(rm_path, sizeof(rm_path), "%s/%s",
2894  dbspacedirname, de->d_name);
2895 
2896  unlink(rm_path); /* note we ignore any error */
2897  }
2898 
2899  FreeDir(dbspace_dir);
2900 }
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2373
static bool looks_like_temp_rel_name(const char *name)
Definition: fd.c:2904
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2439
char d_name[MAX_PATH]
Definition: dirent.h:14
#define elog
Definition: elog.h:219
int FreeDir(DIR *dir)
Definition: fd.c:2482

◆ reserveAllocatedDesc()

static bool reserveAllocatedDesc ( void  )
static

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

2051 {
2052  AllocateDesc *newDescs;
2053  int newMax;
2054 
2055  /* Quick out if array already has a free slot. */
2057  return true;
2058 
2059  /*
2060  * If the array hasn't yet been created in the current process, initialize
2061  * it with FD_MINFREE / 2 elements. In many scenarios this is as many as
2062  * we will ever need, anyway. We don't want to look at max_safe_fds
2063  * immediately because set_max_safe_fds() may not have run yet.
2064  */
2065  if (allocatedDescs == NULL)
2066  {
2067  newMax = FD_MINFREE / 2;
2068  newDescs = (AllocateDesc *) malloc(newMax * sizeof(AllocateDesc));
2069  /* Out of memory already? Treat as fatal error. */
2070  if (newDescs == NULL)
2071  ereport(ERROR,
2072  (errcode(ERRCODE_OUT_OF_MEMORY),
2073  errmsg("out of memory")));
2074  allocatedDescs = newDescs;
2075  maxAllocatedDescs = newMax;
2076  return true;
2077  }
2078 
2079  /*
2080  * Consider enlarging the array beyond the initial allocation used above.
2081  * By the time this happens, max_safe_fds should be known accurately.
2082  *
2083  * We mustn't let allocated descriptors hog all the available FDs, and in
2084  * practice we'd better leave a reasonable number of FDs for VFD use. So
2085  * set the maximum to max_safe_fds / 2. (This should certainly be at
2086  * least as large as the initial size, FD_MINFREE / 2.)
2087  */
2088  newMax = max_safe_fds / 2;
2089  if (newMax > maxAllocatedDescs)
2090  {
2091  newDescs = (AllocateDesc *) realloc(allocatedDescs,
2092  newMax * sizeof(AllocateDesc));
2093  /* Treat out-of-memory as a non-fatal error. */
2094  if (newDescs == NULL)
2095  return false;
2096  allocatedDescs = newDescs;
2097  maxAllocatedDescs = newMax;
2098  return true;
2099  }
2100 
2101  /* Can't enlarge allocatedDescs[] any more. */
2102  return false;
2103 }
static AllocateDesc * allocatedDescs
Definition: fd.c:250
int max_safe_fds
Definition: fd.c:144
int errcode(int sqlerrcode)
Definition: elog.c:575
#define malloc(a)
Definition: header.h:50
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
#define FD_MINFREE
Definition: fd.c:117
#define realloc(a, b)
Definition: header.h:60
int errmsg(const char *fmt,...)
Definition: elog.c:797
static int maxAllocatedDescs
Definition: fd.c:249
static int numAllocatedDescs
Definition: fd.c:248

◆ set_max_safe_fds()

void set_max_safe_fds ( void  )

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

887 {
888  int usable_fds;
889  int already_open;
890 
891  /*----------
892  * We want to set max_safe_fds to
893  * MIN(usable_fds, max_files_per_process - already_open)
894  * less the slop factor for files that are opened without consulting
895  * fd.c. This ensures that we won't exceed either max_files_per_process
896  * or the experimentally-determined EMFILE limit.
897  *----------
898  */
900  &usable_fds, &already_open);
901 
902  max_safe_fds = Min(usable_fds, max_files_per_process - already_open);
903 
904  /*
905  * Take off the FDs reserved for system() etc.
906  */
908 
909  /*
910  * Make sure we still have enough to get by.
911  */
912  if (max_safe_fds < FD_MINFREE)
913  ereport(FATAL,
914  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
915  errmsg("insufficient file descriptors available to start server process"),
916  errdetail("System allows %d, we need at least %d.",
919 
920  elog(DEBUG2, "max_safe_fds = %d, usable_fds = %d, already_open = %d",
921  max_safe_fds, usable_fds, already_open);
922 }
static void count_usable_fds(int max_to_probe, int *usable_fds, int *already_open)
Definition: fd.c:802
#define NUM_RESERVED_FDS
Definition: fd.c:111
int max_safe_fds
Definition: fd.c:144
#define Min(x, y)
Definition: c.h:802
int errcode(int sqlerrcode)
Definition: elog.c:575
#define FATAL
Definition: elog.h:52
#define DEBUG2
Definition: elog.h:24
int errdetail(const char *fmt,...)
Definition: elog.c:873
int max_files_per_process
Definition: fd.c:131
#define ereport(elevel, rest)
Definition: elog.h:122
#define FD_MINFREE
Definition: fd.c:117
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219

◆ SetTempTablespaces()

void SetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 2563 of file fd.c.

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

Referenced by assign_temp_tablespaces(), and PrepareTempTablespaces().

2564 {
2565  Assert(numSpaces >= 0);
2566  tempTableSpaces = tableSpaces;
2567  numTempTableSpaces = numSpaces;
2568 
2569  /*
2570  * Select a random starting point in the list. This is to minimize
2571  * conflicts between backends that are most likely sharing the same list
2572  * of temp tablespaces. Note that if we create multiple temp files in the
2573  * same transaction, we'll advance circularly through the list --- this
2574  * ensures that large temporary sort files are nicely spread across all
2575  * available tablespaces.
2576  */
2577  if (numSpaces > 1)
2578  nextTempTableSpace = random() % numSpaces;
2579  else
2580  nextTempTableSpace = 0;
2581 }
long random(void)
Definition: random.c:22
static int numTempTableSpaces
Definition: fd.c:263
static int nextTempTableSpace
Definition: fd.c:264
#define Assert(condition)
Definition: c.h:670
static Oid * tempTableSpaces
Definition: fd.c:262

◆ SyncDataDirectory()

void SyncDataDirectory ( void  )

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

2972 {
2973  bool xlog_is_symlink;
2974 
2975  /* We can skip this whole thing if fsync is disabled. */
2976  if (!enableFsync)
2977  return;
2978 
2979  /*
2980  * If pg_wal is a symlink, we'll need to recurse into it separately,
2981  * because the first walkdir below will ignore it.
2982  */
2983  xlog_is_symlink = false;
2984 
2985 #ifndef WIN32
2986  {
2987  struct stat st;
2988 
2989  if (lstat("pg_wal", &st) < 0)
2990  ereport(LOG,
2992  errmsg("could not stat file \"%s\": %m",
2993  "pg_wal")));
2994  else if (S_ISLNK(st.st_mode))
2995  xlog_is_symlink = true;
2996  }
2997 #else
2998  if (pgwin32_is_junction("pg_wal"))
2999  xlog_is_symlink = true;
3000 #endif
3001 
3002  /*
3003  * If possible, hint to the kernel that we're soon going to fsync the data
3004  * directory and its contents. Errors in this step are even less
3005  * interesting than normal, so log them only at DEBUG1.
3006  */
3007 #ifdef PG_FLUSH_DATA_WORKS
3008  walkdir(".", pre_sync_fname, false, DEBUG1);
3009  if (xlog_is_symlink)
3010  walkdir("pg_wal", pre_sync_fname, false, DEBUG1);
3011  walkdir("pg_tblspc", pre_sync_fname, true, DEBUG1);
3012 #endif
3013 
3014  /*
3015  * Now we do the fsync()s in the same order.
3016  *
3017  * The main call ignores symlinks, so in addition to specially processing
3018  * pg_wal if it's a symlink, pg_tblspc has to be visited separately with
3019  * process_symlinks = true. Note that if there are any plain directories
3020  * in pg_tblspc, they'll get fsync'd twice. That's not an expected case
3021  * so we don't worry about optimizing it.
3022  */
3023  walkdir(".", datadir_fsync_fname, false, LOG);
3024  if (xlog_is_symlink)
3025  walkdir("pg_wal", datadir_fsync_fname, false, LOG);
3026  walkdir("pg_tblspc", datadir_fsync_fname, true, LOG);
3027 }
#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:3044
#define LOG
Definition: elog.h:26
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
static void datadir_fsync_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3146
#define stat(a, b)
Definition: win32_port.h:266
#define lstat(path, sb)
Definition: win32_port.h:255
bool enableFsync
Definition: globals.c:111
int errmsg(const char *fmt,...)
Definition: elog.c:797
bool pgwin32_is_junction(const char *path)

◆ TempTablespacesAreSet()

bool TempTablespacesAreSet ( void  )

Definition at line 2591 of file fd.c.

References numTempTableSpaces.

Referenced by PrepareTempTablespaces().

2592 {
2593  return (numTempTableSpaces >= 0);
2594 }
static int numTempTableSpaces
Definition: fd.c:263

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

3048 {
3049  DIR *dir;
3050  struct dirent *de;
3051 
3052  dir = AllocateDir(path);
3053  if (dir == NULL)
3054  {
3055  ereport(elevel,
3057  errmsg("could not open directory \"%s\": %m", path)));
3058  return;
3059  }
3060 
3061  while ((de = ReadDirExtended(dir, path, elevel)) != NULL)
3062  {
3063  char subpath[MAXPGPATH * 2];
3064  struct stat fst;
3065  int sret;
3066 
3068 
3069  if (strcmp(de->d_name, ".") == 0 ||
3070  strcmp(de->d_name, "..") == 0)
3071  continue;
3072 
3073  snprintf(subpath, sizeof(subpath), "%s/%s", path, de->d_name);
3074 
3075  if (process_symlinks)
3076  sret = stat(subpath, &fst);
3077  else
3078  sret = lstat(subpath, &fst);
3079 
3080  if (sret < 0)
3081  {
3082  ereport(elevel,
3084  errmsg("could not stat file \"%s\": %m", subpath)));
3085  continue;
3086  }
3087 
3088  if (S_ISREG(fst.st_mode))
3089  (*action) (subpath, false, elevel);
3090  else if (S_ISDIR(fst.st_mode))
3091  walkdir(subpath, action, false, elevel);
3092  }
3093 
3094  FreeDir(dir); /* we ignore any error here */
3095 
3096  /*
3097  * It's important to fsync the destination directory itself as individual
3098  * file fsyncs don't guarantee that the directory entry for the file is
3099  * synced.
3100  */
3101  (*action) (path, true, elevel);
3102 }
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
Definition: fd.c:3044
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
static struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2449
int errcode_for_file_access(void)
Definition: elog.c:598
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2373
#define ereport(elevel, rest)
Definition: elog.h:122
#define S_ISREG(m)
Definition: win32_port.h:310
#define stat(a, b)
Definition: win32_port.h:266
static int elevel
Definition: vacuumlazy.c:136
#define S_ISDIR(m)
Definition: win32_port.h:307
#define lstat(path, sb)
Definition: win32_port.h:255
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:98
char d_name[MAX_PATH]
Definition: dirent.h:14
int FreeDir(DIR *dir)
Definition: fd.c:2482
Datum subpath(PG_FUNCTION_ARGS)
Definition: ltree_op.c:234

Variable Documentation

◆ allocatedDescs

AllocateDesc* allocatedDescs = NULL
static

Definition at line 250 of file fd.c.

◆ have_xact_temporary_files

bool have_xact_temporary_files = false
static

Definition at line 214 of file fd.c.

Referenced by CleanupTempFiles(), and OpenTemporaryFile().

◆ max_files_per_process

int max_files_per_process = 1000

Definition at line 131 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 264 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 203 of file fd.c.

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

◆ tempFileCounter

long tempFileCounter = 0
static

Definition at line 256 of file fd.c.

Referenced by OpenTemporaryFileInTablespace().

◆ temporary_files_size

uint64 temporary_files_size = 0
static

Definition at line 222 of file fd.c.

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

◆ tempTableSpaces

Oid* tempTableSpaces = NULL
static

Definition at line 262 of file fd.c.

Referenced by AtEOXact_Files(), GetNextTempTableSpace(), and SetTempTablespaces().

◆ VfdCache

Vfd* VfdCache
static

Definition at line 202 of file fd.c.