From 662022325393b96c50e4f4e1c9c0a15ce19ec70f Mon Sep 17 00:00:00 2001 From: Tomas Vondra Date: Sat, 23 Mar 2024 18:26:21 +0100 Subject: [PATCH v20240401 4/7] use copy_file_range in write_reconstructed_file Use copy_file_range when reconstructing file without having to calculate checksums. --- src/bin/pg_combinebackup/reconstruct.c | 33 +++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/bin/pg_combinebackup/reconstruct.c b/src/bin/pg_combinebackup/reconstruct.c index f2c6101c6de..f02c91a5d4e 100644 --- a/src/bin/pg_combinebackup/reconstruct.c +++ b/src/bin/pg_combinebackup/reconstruct.c @@ -59,7 +59,8 @@ static void write_reconstructed_file(char *input_filename, off_t *offsetmap, pg_checksum_context *checksum_ctx, bool debug, - bool dry_run); + bool dry_run, + CopyMethod copy_method); static void read_bytes(rfile *rf, void *buffer, unsigned length); /* @@ -325,7 +326,8 @@ reconstruct_from_incremental_file(char *input_filename, { write_reconstructed_file(input_filename, output_filename, block_length, sourcemap, offsetmap, - &checksum_ctx, debug, dry_run); + &checksum_ctx, debug, dry_run, + copy_method); debug_reconstruction(n_prior_backups + 1, source, dry_run); } @@ -534,7 +536,8 @@ write_reconstructed_file(char *input_filename, off_t *offsetmap, pg_checksum_context *checksum_ctx, bool debug, - bool dry_run) + bool dry_run, + CopyMethod copy_method) { int wfd = -1; unsigned i; @@ -640,6 +643,30 @@ write_reconstructed_file(char *input_filename, if (dry_run) continue; + /* + * If requested, copy the block using copy_file_range. + * + * We can'd do this if the block needs to be zero-filled or when we + * need to update checksum. + */ + if ((copy_method == COPY_METHOD_COPY_FILE_RANGE) && + (s != NULL) && (checksum_ctx->type == CHECKSUM_TYPE_NONE)) + { +#if defined(HAVE_COPY_FILE_RANGE) + wb = copy_file_range(s->fd, &offsetmap[i], wfd, NULL, BLCKSZ, 0); + + if (wb < 0) + pg_fatal("error while copying file range from \"%s\" to \"%s\": %m", + input_filename, output_filename); + else if (wb != BLCKSZ) + pg_fatal("could not write file \"%s\": wrote only %d of %d bytes", + output_filename, wb, BLCKSZ); +#else + pg_fatal("copy_file_range not supported on this platform"); +#endif + continue; + } + /* Read or zero-fill the block as appropriate. */ if (s == NULL) { -- 2.44.0