36 #if defined(HAVE_SYNC_FILE_RANGE)
37 #define PG_FLUSH_DATA_WORKS 1
38 #elif defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
39 #define PG_FLUSH_DATA_WORKS 1
45 #define MINIMUM_VERSION_FOR_PG_WAL 100000
47 #ifdef PG_FLUSH_DATA_WORKS
48 static int pre_sync_fname(
const char *fname,
bool isdir);
50 static void walkdir(
const char *path,
51 int (*
action) (
const char *fname,
bool isdir),
52 bool process_symlinks);
62 do_syncfs(
const char *path)
66 fd = open(path, O_RDONLY, 0);
76 pg_log_error(
"could not synchronize file system for file \"%s\": %m", path);
97 sync_pgdata(
const char *
pg_data,
101 bool xlog_is_symlink;
114 xlog_is_symlink =
false;
119 if (
lstat(pg_wal, &st) < 0)
122 xlog_is_symlink =
true;
130 pg_log_error(
"this build does not support sync method \"%s\"",
155 while (errno = 0, (de =
readdir(dir)) != NULL)
159 if (strcmp(de->
d_name,
".") == 0 ||
160 strcmp(de->
d_name,
"..") == 0)
188 #ifdef PG_FLUSH_DATA_WORKS
191 walkdir(pg_wal, pre_sync_fname,
false);
192 walkdir(pg_tblspc, pre_sync_fname,
true);
227 pg_log_error(
"this build does not support sync method \"%s\"",
246 #ifdef PG_FLUSH_DATA_WORKS
247 walkdir(dir, pre_sync_fname,
false);
272 int (*
action) (
const char *fname,
bool isdir),
273 bool process_symlinks)
281 pg_log_error(
"could not open directory \"%s\": %m", path);
285 while (errno = 0, (de =
readdir(dir)) != NULL)
289 if (strcmp(de->
d_name,
".") == 0 ||
290 strcmp(de->
d_name,
"..") == 0)
315 pg_log_error(
"could not read directory \"%s\": %m", path);
325 (*action) (path,
true);
334 #ifdef PG_FLUSH_DATA_WORKS
337 pre_sync_fname(
const char *fname,
bool isdir)
345 if (errno == EACCES || (isdir && errno == EISDIR))
356 #if defined(HAVE_SYNC_FILE_RANGE)
357 (void) sync_file_range(
fd, 0, 0, SYNC_FILE_RANGE_WRITE);
358 #elif defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
359 (void) posix_fadvise(
fd, 0, 0, POSIX_FADV_DONTNEED);
361 #error PG_FLUSH_DATA_WORKS should not have been defined
401 fd = open(fname, flags, 0);
404 if (errno == EACCES || (isdir && errno == EISDIR))
416 if (returncode != 0 && !(isdir && (errno == EBADF || errno == EINVAL)))
446 if (strlen(parentpath) == 0)
480 pg_log_error(
"could not open file \"%s\": %m", newfile);
488 pg_log_error(
"could not fsync file \"%s\": %m", newfile);
496 if (rename(oldfile, newfile) != 0)
498 pg_log_error(
"could not rename file \"%s\" to \"%s\": %m",
527 bool look_through_symlinks,
538 #if defined(DT_REG) && defined(DT_DIR) && defined(DT_LNK)
543 else if (de->
d_type ==
DT_LNK && !look_through_symlinks)
557 if (look_through_symlinks)
558 sret =
stat(path, &fst);
560 sret =
lstat(path, &fst);
570 errmsg(
"could not stat file \"%s\": %m", path)));
611 #ifdef SIMULATE_SHORT_WRITE
612 part =
Min(part, 4096);
620 while (iovcnt > 0 && iov->iov_len <= part)
622 part -= iov->iov_len;
640 memmove(iov_copy, iov,
sizeof(*iov) * iovcnt);
641 Assert(iov->iov_len > part);
642 iov_copy[0].iov_base = (
char *) iov_copy[0].iov_base + part;
643 iov_copy[0].iov_len -= part;
665 size_t remaining_size = size;
666 ssize_t total_written = 0;
669 while (remaining_size > 0)
674 for (; iovcnt < PG_IOV_MAX && remaining_size > 0; iovcnt++)
676 size_t this_iov_size;
678 iov[iovcnt].iov_base = zerobuf_addr;
680 if (remaining_size < BLCKSZ)
681 this_iov_size = remaining_size;
683 this_iov_size = BLCKSZ;
685 iov[iovcnt].iov_len = this_iov_size;
686 remaining_size -= this_iov_size;
695 total_written += written;
698 Assert(total_written == size);
700 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)
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(fmt[strlen(fmt) - 1] !='\n')
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)
#define MINIMUM_VERSION_FOR_PG_WAL
ssize_t pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
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)