13 #ifdef HAVE_COPYFILE_H
17 #include <sys/ioctl.h>
39 static void copy_file_copyfile(
const char *src,
const char *dst,
53 char *strategy_name = NULL;
54 void (*strategy_implementation) (
const char *,
const char *,
66 pg_fatal(
"could not open file \"%s\": %m", src);
68 pg_fatal(
"could not close file \"%s\": %m", src);
72 copy_method = COPY_METHOD_COPYFILE;
79 strategy_name =
"clone";
87 strategy_name =
"copy_file_range";
91 case COPY_METHOD_COPYFILE:
92 strategy_name =
"CopyFile";
93 strategy_implementation = copy_file_copyfile;
101 pg_log_debug(
"would copy \"%s\" to \"%s\" using strategy %s",
102 src, dst, strategy_name);
110 pg_log_debug(
"copying \"%s\" to \"%s\" using strategy %s",
111 src, dst, strategy_name);
116 pg_log_debug(
"copying \"%s\" to \"%s\" and checksumming with %s",
119 strategy_implementation(src, dst, checksum_ctx);
131 const int buffer_size = 50 * BLCKSZ;
138 if ((src_fd = open(src, O_RDONLY |
PG_BINARY, 0)) < 0)
139 pg_fatal(
"could not open file \"%s\": %m", src);
143 while ((rb =
read(src_fd, buffer, buffer_size)) > 0)
146 pg_fatal(
"could not update checksum of file \"%s\"", src);
150 pg_fatal(
"could not read file \"%s\": %m", src);
166 const int buffer_size = 50 * BLCKSZ;
170 if ((src_fd = open(src, O_RDONLY |
PG_BINARY, 0)) < 0)
171 pg_fatal(
"could not open file \"%s\": %m", src);
173 if ((dest_fd = open(dst, O_WRONLY | O_CREAT | O_EXCL |
PG_BINARY,
175 pg_fatal(
"could not open file \"%s\": %m", dst);
179 while ((rb =
read(src_fd, buffer, buffer_size)) > 0)
183 if ((wb =
write(dest_fd, buffer, rb)) != rb)
186 pg_fatal(
"could not write to file \"%s\": %m", dst);
188 pg_fatal(
"could not write to file \"%s\", offset %u: wrote %d of %d",
189 dst, offset, (
int) wb, (
int) rb);
193 pg_fatal(
"could not update checksum of file \"%s\"", dst);
199 pg_fatal(
"could not read from file \"%s\": %m", dst);
216 #if defined(HAVE_COPYFILE) && defined(COPYFILE_CLONE_FORCE)
217 if (copyfile(src,
dest, NULL, COPYFILE_CLONE_FORCE) < 0)
218 pg_fatal(
"error while cloning file \"%s\" to \"%s\": %m", src,
dest);
219 #elif defined(__linux__) && defined(FICLONE)
224 if ((src_fd = open(src, O_RDONLY |
PG_BINARY, 0)) < 0)
225 pg_fatal(
"could not open file \"%s\": %m", src);
227 if ((dest_fd = open(
dest, O_RDWR | O_CREAT | O_EXCL |
PG_BINARY,
231 if (ioctl(dest_fd, FICLONE, src_fd) < 0)
233 int save_errno = errno;
237 pg_fatal(
"error while cloning file \"%s\" to \"%s\": %s",
245 pg_fatal(
"file cloning not supported on this platform");
262 #if defined(HAVE_COPY_FILE_RANGE)
267 if ((src_fd = open(src, O_RDONLY |
PG_BINARY, 0)) < 0)
268 pg_fatal(
"could not open file \"%s\": %m", src);
270 if ((dest_fd = open(
dest, O_RDWR | O_CREAT | O_EXCL |
PG_BINARY,
276 nbytes = copy_file_range(src_fd, NULL, dest_fd, NULL, SSIZE_MAX, 0);
278 pg_fatal(
"error while copying file range from \"%s\" to \"%s\": %m",
280 }
while (nbytes > 0);
285 pg_fatal(
"copy_file_range not supported on this platform");
294 copy_file_copyfile(
const char *src,
const char *dst,
297 if (CopyFile(src, dst,
true) == 0)
300 pg_fatal(
"could not copy file \"%s\" to \"%s\": %m", src, dst);
char * pg_checksum_type_name(pg_checksum_type type)
int pg_checksum_update(pg_checksum_context *context, const uint8 *input, size_t len)
static void copy_file_blocks(const char *src, const char *dst, pg_checksum_context *checksum_ctx)
static void copy_file_clone(const char *src, const char *dest, pg_checksum_context *checksum_ctx)
void copy_file(const char *src, const char *dst, pg_checksum_context *checksum_ctx, CopyMethod copy_method, bool dry_run)
static void checksum_file(const char *src, pg_checksum_context *checksum_ctx)
static void copy_file_by_range(const char *src, const char *dest, pg_checksum_context *checksum_ctx)
@ COPY_METHOD_COPY_FILE_RANGE
void * pg_malloc(size_t size)
#define pg_log_debug(...)
static int fd(const char *x, int i)
void _dosmaperr(unsigned long)