LCOV - code coverage report
Current view: top level - src/include/storage - fd.h (source / functions) Hit Total Coverage
Test: PostgreSQL 19devel Lines: 6 6 100.0 %
Date: 2026-02-07 15:18:00 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * fd.h
       4             :  *    Virtual file descriptor definitions.
       5             :  *
       6             :  *
       7             :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       8             :  * Portions Copyright (c) 1994, Regents of the University of California
       9             :  *
      10             :  * src/include/storage/fd.h
      11             :  *
      12             :  *-------------------------------------------------------------------------
      13             :  */
      14             : 
      15             : /*
      16             :  * calls:
      17             :  *
      18             :  *  File {Close, Read, ReadV, Write, WriteV, Size, Sync}
      19             :  *  {Path Name Open, Allocate, Free} File
      20             :  *
      21             :  * These are NOT JUST RENAMINGS OF THE UNIX ROUTINES.
      22             :  * Use them for all file activity...
      23             :  *
      24             :  *  File fd;
      25             :  *  fd = PathNameOpenFile("foo", O_RDONLY);
      26             :  *
      27             :  *  AllocateFile();
      28             :  *  FreeFile();
      29             :  *
      30             :  * Use AllocateFile, not fopen, if you need a stdio file (FILE*); then
      31             :  * use FreeFile, not fclose, to close it.  AVOID using stdio for files
      32             :  * that you intend to hold open for any length of time, since there is
      33             :  * no way for them to share kernel file descriptors with other files.
      34             :  *
      35             :  * Likewise, use AllocateDir/FreeDir, not opendir/closedir, to allocate
      36             :  * open directories (DIR*), and OpenTransientFile/CloseTransientFile for an
      37             :  * unbuffered file descriptor.
      38             :  *
      39             :  * If you really can't use any of the above, at least call AcquireExternalFD
      40             :  * or ReserveExternalFD to report any file descriptors that are held for any
      41             :  * length of time.  Failure to do so risks unnecessary EMFILE errors.
      42             :  */
      43             : #ifndef FD_H
      44             : #define FD_H
      45             : 
      46             : #include "port/pg_iovec.h"
      47             : 
      48             : #include <dirent.h>
      49             : #include <fcntl.h>
      50             : 
      51             : typedef int File;
      52             : 
      53             : 
      54             : #define IO_DIRECT_DATA          0x01
      55             : #define IO_DIRECT_WAL           0x02
      56             : #define IO_DIRECT_WAL_INIT      0x04
      57             : 
      58             : enum FileExtendMethod
      59             : {
      60             : #ifdef HAVE_POSIX_FALLOCATE
      61             :     FILE_EXTEND_METHOD_POSIX_FALLOCATE,
      62             : #endif
      63             :     FILE_EXTEND_METHOD_WRITE_ZEROS,
      64             : };
      65             : 
      66             : /* Default to the first available file_extend_method. */
      67             : #define DEFAULT_FILE_EXTEND_METHOD 0
      68             : 
      69             : /* GUC parameter */
      70             : extern PGDLLIMPORT int max_files_per_process;
      71             : extern PGDLLIMPORT bool data_sync_retry;
      72             : extern PGDLLIMPORT int recovery_init_sync_method;
      73             : extern PGDLLIMPORT int io_direct_flags;
      74             : extern PGDLLIMPORT int file_extend_method;
      75             : 
      76             : /*
      77             :  * This is private to fd.c, but exported for save/restore_backend_variables()
      78             :  */
      79             : extern PGDLLIMPORT int max_safe_fds;
      80             : 
      81             : /*
      82             :  * On Windows, we have to interpret EACCES as possibly meaning the same as
      83             :  * ENOENT, because if a file is unlinked-but-not-yet-gone on that platform,
      84             :  * that's what you get.  Ugh.  This code is designed so that we don't
      85             :  * actually believe these cases are okay without further evidence (namely,
      86             :  * a pending fsync request getting canceled ... see ProcessSyncRequests).
      87             :  */
      88             : #ifndef WIN32
      89             : #define FILE_POSSIBLY_DELETED(err)  ((err) == ENOENT)
      90             : #else
      91             : #define FILE_POSSIBLY_DELETED(err)  ((err) == ENOENT || (err) == EACCES)
      92             : #endif
      93             : 
      94             : /*
      95             :  * O_DIRECT is not standard, but almost every Unix has it.  We translate it
      96             :  * to the appropriate Windows flag in src/port/open.c.  We simulate it with
      97             :  * fcntl(F_NOCACHE) on macOS inside fd.c's open() wrapper.  We use the name
      98             :  * PG_O_DIRECT rather than defining O_DIRECT in that case (probably not a good
      99             :  * idea on a Unix).
     100             :  */
     101             : #if defined(O_DIRECT)
     102             : #define     PG_O_DIRECT O_DIRECT
     103             : #elif defined(F_NOCACHE)
     104             : #define     PG_O_DIRECT 0x80000000
     105             : #define     PG_O_DIRECT_USE_F_NOCACHE
     106             : /*
     107             :  * The value we defined to stand in for O_DIRECT when simulating it with
     108             :  * F_NOCACHE had better not collide with any of the standard flags.
     109             :  */
     110             : StaticAssertDecl((PG_O_DIRECT &
     111             :                   (O_APPEND |
     112             :                    O_CLOEXEC |
     113             :                    O_CREAT |
     114             :                    O_DSYNC |
     115             :                    O_EXCL |
     116             :                    O_RDWR |
     117             :                    O_RDONLY |
     118             :                    O_SYNC |
     119             :                    O_TRUNC |
     120             :                    O_WRONLY)) == 0,
     121             :                  "PG_O_DIRECT value collides with standard flag");
     122             : #else
     123             : #define     PG_O_DIRECT 0
     124             : #endif
     125             : 
     126             : /*
     127             :  * prototypes for functions in fd.c
     128             :  */
     129             : 
     130             : struct PgAioHandle;
     131             : 
     132             : /* Operations on virtual Files --- equivalent to Unix kernel file ops */
     133             : extern File PathNameOpenFile(const char *fileName, int fileFlags);
     134             : extern File PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode);
     135             : extern File OpenTemporaryFile(bool interXact);
     136             : extern void FileClose(File file);
     137             : extern int  FilePrefetch(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info);
     138             : extern ssize_t FileReadV(File file, const struct iovec *iov, int iovcnt, pgoff_t offset, uint32 wait_event_info);
     139             : extern ssize_t FileWriteV(File file, const struct iovec *iov, int iovcnt, pgoff_t offset, uint32 wait_event_info);
     140             : extern int  FileStartReadV(struct PgAioHandle *ioh, File file, int iovcnt, pgoff_t offset, uint32 wait_event_info);
     141             : extern int  FileSync(File file, uint32 wait_event_info);
     142             : extern int  FileZero(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info);
     143             : extern int  FileFallocate(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info);
     144             : 
     145             : extern pgoff_t FileSize(File file);
     146             : extern int  FileTruncate(File file, pgoff_t offset, uint32 wait_event_info);
     147             : extern void FileWriteback(File file, pgoff_t offset, pgoff_t nbytes, uint32 wait_event_info);
     148             : extern char *FilePathName(File file);
     149             : extern int  FileGetRawDesc(File file);
     150             : extern int  FileGetRawFlags(File file);
     151             : extern mode_t FileGetRawMode(File file);
     152             : 
     153             : /* Operations used for sharing named temporary files */
     154             : extern File PathNameCreateTemporaryFile(const char *path, bool error_on_failure);
     155             : extern File PathNameOpenTemporaryFile(const char *path, int mode);
     156             : extern bool PathNameDeleteTemporaryFile(const char *path, bool error_on_failure);
     157             : extern void PathNameCreateTemporaryDir(const char *basedir, const char *directory);
     158             : extern void PathNameDeleteTemporaryDir(const char *dirname);
     159             : extern void TempTablespacePath(char *path, Oid tablespace);
     160             : 
     161             : /* Operations that allow use of regular stdio --- USE WITH CAUTION */
     162             : extern FILE *AllocateFile(const char *name, const char *mode);
     163             : extern int  FreeFile(FILE *file);
     164             : 
     165             : /* Operations that allow use of pipe streams (popen/pclose) */
     166             : extern FILE *OpenPipeStream(const char *command, const char *mode);
     167             : extern int  ClosePipeStream(FILE *file);
     168             : 
     169             : /* Operations to allow use of the <dirent.h> library routines */
     170             : extern DIR *AllocateDir(const char *dirname);
     171             : extern struct dirent *ReadDir(DIR *dir, const char *dirname);
     172             : extern struct dirent *ReadDirExtended(DIR *dir, const char *dirname,
     173             :                                       int elevel);
     174             : extern int  FreeDir(DIR *dir);
     175             : 
     176             : /* Operations to allow use of a plain kernel FD, with automatic cleanup */
     177             : extern int  OpenTransientFile(const char *fileName, int fileFlags);
     178             : extern int  OpenTransientFilePerm(const char *fileName, int fileFlags, mode_t fileMode);
     179             : extern int  CloseTransientFile(int fd);
     180             : 
     181             : /* If you've really really gotta have a plain kernel FD, use this */
     182             : extern int  BasicOpenFile(const char *fileName, int fileFlags);
     183             : extern int  BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode);
     184             : 
     185             : /* Use these for other cases, and also for long-lived BasicOpenFile FDs */
     186             : extern bool AcquireExternalFD(void);
     187             : extern void ReserveExternalFD(void);
     188             : extern void ReleaseExternalFD(void);
     189             : 
     190             : /* Make a directory with default permissions */
     191             : extern int  MakePGDirectory(const char *directoryName);
     192             : 
     193             : /* Miscellaneous support routines */
     194             : extern void InitFileAccess(void);
     195             : extern void InitTemporaryFileAccess(void);
     196             : extern void set_max_safe_fds(void);
     197             : extern void closeAllVfds(void);
     198             : extern void SetTempTablespaces(Oid *tableSpaces, int numSpaces);
     199             : extern bool TempTablespacesAreSet(void);
     200             : extern int  GetTempTablespaces(Oid *tableSpaces, int numSpaces);
     201             : extern Oid  GetNextTempTableSpace(void);
     202             : extern void AtEOXact_Files(bool isCommit);
     203             : extern void AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid,
     204             :                               SubTransactionId parentSubid);
     205             : extern void RemovePgTempFiles(void);
     206             : extern void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok,
     207             :                                    bool unlink_all);
     208             : extern bool looks_like_temp_rel_name(const char *name);
     209             : 
     210             : extern int  pg_fsync(int fd);
     211             : extern int  pg_fsync_no_writethrough(int fd);
     212             : extern int  pg_fsync_writethrough(int fd);
     213             : extern int  pg_fdatasync(int fd);
     214             : extern bool pg_file_exists(const char *name);
     215             : extern void pg_flush_data(int fd, pgoff_t offset, pgoff_t nbytes);
     216             : extern int  pg_truncate(const char *path, pgoff_t length);
     217             : extern void fsync_fname(const char *fname, bool isdir);
     218             : extern int  fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel);
     219             : extern int  durable_rename(const char *oldfile, const char *newfile, int elevel);
     220             : extern int  durable_unlink(const char *fname, int elevel);
     221             : extern void SyncDataDirectory(void);
     222             : extern int  data_sync_elevel(int elevel);
     223             : 
     224             : static inline ssize_t
     225      811178 : FileRead(File file, void *buffer, size_t amount, pgoff_t offset,
     226             :          uint32 wait_event_info)
     227             : {
     228      811178 :     struct iovec iov = {
     229             :         .iov_base = buffer,
     230             :         .iov_len = amount
     231             :     };
     232             : 
     233      811178 :     return FileReadV(file, &iov, 1, offset, wait_event_info);
     234             : }
     235             : 
     236             : static inline ssize_t
     237      371246 : FileWrite(File file, const void *buffer, size_t amount, pgoff_t offset,
     238             :           uint32 wait_event_info)
     239             : {
     240      371246 :     struct iovec iov = {
     241             :         .iov_base = unconstify(void *, buffer),
     242             :         .iov_len = amount
     243             :     };
     244             : 
     245      371246 :     return FileWriteV(file, &iov, 1, offset, wait_event_info);
     246             : }
     247             : 
     248             : #endif                          /* FD_H */

Generated by: LCOV version 1.16