From 41bec08d7a8727d56cf982c3a75255576c8cef4f Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 21 Nov 2021 12:31:07 -0800 Subject: [PATCH] cp: streamline cloning by skipping fstat * src/copy.c (copy_reg): Attempt clone_file before fstat of dest, so that if clone_file succeeds we can skip the fstat. --- src/copy.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/src/copy.c b/src/copy.c index 9f20a34b91..97cc20d296 100644 --- a/src/copy.c +++ b/src/copy.c @@ -1093,7 +1093,7 @@ union scan_inference }; /* Return how to scan a file with descriptor FD and stat buffer SB. - Store any information gathered into *SCAN. */ + Store any information gathered into *SCAN_INFERENCE. */ static enum scantype infer_scantype (int fd, struct stat const *sb, union scan_inference *scan_inference) @@ -1307,7 +1307,23 @@ copy_reg (char const *src_name, char const *dst_name, goto close_src_desc; } - if (fstat (dest_desc, &sb) != 0) + /* --attributes-only overrides --reflink. */ + if (data_copy_required && x->reflink_mode) + { + if (clone_file (dest_desc, source_desc) == 0) + data_copy_required = false; + else if (x->reflink_mode == REFLINK_ALWAYS) + { + error (0, errno, _("failed to clone %s from %s"), + quoteaf_n (0, dst_name), quoteaf_n (1, src_name)); + return_val = false; + goto close_src_and_dst_desc; + } + } + + if (! (data_copy_required | x->preserve_ownership | extra_permissions)) + sb.st_mode = 0; + else if (fstat (dest_desc, &sb) != 0) { error (0, errno, _("cannot fstat %s"), quoteaf (dst_name)); return_val = false; @@ -1322,23 +1338,6 @@ copy_reg (char const *src_name, char const *dst_name, && fchmod_or_lchmod (dest_desc, dst_name, temporary_mode) != 0) extra_permissions = 0; - /* --attributes-only overrides --reflink. */ - if (data_copy_required && x->reflink_mode) - { - bool clone_ok = clone_file (dest_desc, source_desc) == 0; - if (clone_ok || x->reflink_mode == REFLINK_ALWAYS) - { - if (!clone_ok) - { - error (0, errno, _("failed to clone %s from %s"), - quoteaf_n (0, dst_name), quoteaf_n (1, src_name)); - return_val = false; - goto close_src_and_dst_desc; - } - data_copy_required = false; - } - } - if (data_copy_required) { /* Choose a suitable buffer size; it may be adjusted later. */ -- 2.47.2