37#if defined(HAVE_SYNC_FILE_RANGE)
38#define PG_FLUSH_DATA_WORKS 1
39#elif defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
40#define PG_FLUSH_DATA_WORKS 1
46#define MINIMUM_VERSION_FOR_PG_WAL 100000
48static void walkdir(
const char *path,
49 int (*
action) (
const char *fname,
bool isdir),
50 bool process_symlinks,
51 const char *exclude_dir);
61do_syncfs(
const char *path)
65 fd = open(path, O_RDONLY, 0);
75 pg_log_error(
"could not synchronize file system for file \"%s\": %m", path);
104 bool xlog_is_symlink;
117 xlog_is_symlink =
false;
122 if (
lstat(pg_wal, &st) < 0)
125 xlog_is_symlink =
true;
133 pg_log_error(
"this build does not support sync method \"%s\"",
160 while (errno = 0, (de =
readdir(dir)) != NULL)
164 if (strcmp(de->
d_name,
".") == 0 ||
165 strcmp(de->
d_name,
"..") == 0)
190 char *exclude_dir = NULL;
199#ifdef PG_FLUSH_DATA_WORKS
202 walkdir(pg_wal, pre_sync_fname,
false, NULL);
204 walkdir(pg_tblspc, pre_sync_fname,
true, NULL);
243 pg_log_error(
"this build does not support sync method \"%s\"",
262#ifdef PG_FLUSH_DATA_WORKS
263 walkdir(dir, pre_sync_fname,
false, NULL);
291 int (*
action) (
const char *fname,
bool isdir),
292 bool process_symlinks,
293 const char *exclude_dir)
298 if (exclude_dir && strcmp(exclude_dir, path) == 0)
304 pg_log_error(
"could not open directory \"%s\": %m", path);
308 while (errno = 0, (de =
readdir(dir)) != NULL)
312 if (strcmp(de->
d_name,
".") == 0 ||
313 strcmp(de->
d_name,
"..") == 0)
338 pg_log_error(
"could not read directory \"%s\": %m", path);
348 (*action) (path,
true);
359pre_sync_fname(
const char *fname,
bool isdir)
361#ifdef PG_FLUSH_DATA_WORKS
368 if (errno == EACCES || (isdir && errno == EISDIR))
379#if defined(HAVE_SYNC_FILE_RANGE)
380 (void) sync_file_range(
fd, 0, 0, SYNC_FILE_RANGE_WRITE);
381#elif defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
382 (void) posix_fadvise(
fd, 0, 0, POSIX_FADV_DONTNEED);
384#error PG_FLUSH_DATA_WORKS should not have been defined
423 fd = open(fname, flags, 0);
426 if (errno == EACCES || (isdir && errno == EISDIR))
438 if (returncode != 0 && !(isdir && (errno == EBADF || errno == EINVAL)))
468 if (strlen(parentpath) == 0)
502 pg_log_error(
"could not open file \"%s\": %m", newfile);
510 pg_log_error(
"could not fsync file \"%s\": %m", newfile);
518 if (rename(oldfile, newfile) != 0)
520 pg_log_error(
"could not rename file \"%s\" to \"%s\": %m",
549 bool look_through_symlinks,
560#if defined(DT_REG) && defined(DT_DIR) && defined(DT_LNK)
565 else if (de->
d_type ==
DT_LNK && !look_through_symlinks)
579 if (look_through_symlinks)
580 sret =
stat(path, &fst);
582 sret =
lstat(path, &fst);
592 errmsg(
"could not stat file \"%s\": %m", path)));
615 const struct iovec *
source,
622 while (
source->iov_len <= transferred)
624 transferred -=
source->iov_len;
641 if (
source != destination)
645 Assert(destination->iov_len > transferred);
646 destination->iov_base = (
char *) destination->iov_base + transferred;
647 destination->iov_len -= transferred;
679#ifdef SIMULATE_SHORT_WRITE
680 part =
Min(part, 4096);
694 }
while (iovcnt > 0);
714 size_t remaining_size = size;
715 ssize_t total_written = 0;
718 while (remaining_size > 0)
723 for (; iovcnt < PG_IOV_MAX && remaining_size > 0; iovcnt++)
725 size_t this_iov_size;
727 iov[iovcnt].iov_base = zerobuf_addr;
729 if (remaining_size < BLCKSZ)
730 this_iov_size = remaining_size;
732 this_iov_size = BLCKSZ;
734 iov[iovcnt].iov_len = this_iov_size;
735 remaining_size -= this_iov_size;
744 total_written += written;
747 Assert(total_written == size);
749 return total_written;
#define unconstify(underlying_type, expr)
struct dirent * readdir(DIR *)
DIR * opendir(const char *)
int errcode_for_file_access(void)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
int durable_rename(const char *oldfile, const char *newfile, int elevel)
void fsync_fname(const char *fname, bool isdir)
static int fsync_parent_path(const char *fname, int elevel)
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
int compute_remaining_iovec(struct iovec *destination, const struct iovec *source, int iovcnt, size_t transferred)
ssize_t pg_pwrite_zeros(int fd, size_t size, off_t offset)
ssize_t pg_pwritev_with_retry(int fd, const struct iovec *iov, int iovcnt, off_t offset)
PGFileType get_dirent_type(const char *path, const struct dirent *de, bool look_through_symlinks, int elevel)
@ DATA_DIR_SYNC_METHOD_SYNCFS
@ DATA_DIR_SYNC_METHOD_FSYNC
Assert(PointerIsAligned(start, uint64))
static bool sync_data_files
static DataDirSyncMethod sync_method
void pg_log_generic(enum pg_log_level level, enum pg_log_part part, const char *pg_restrict fmt,...)
#define pg_log_error(...)
Datum subpath(PG_FUNCTION_ARGS)
void pfree(void *pointer)
#define MINIMUM_VERSION_FOR_PG_WAL
static ssize_t pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
static rewind_source * source
void get_parent_directory(char *path)
size_t strlcpy(char *dst, const char *src, size_t siz)
static int fd(const char *x, int i)
char * psprintf(const char *fmt,...)