| 677 | Return FALSE if it's a terminal failure for this file. */ |
| 678 | |
| 679 | static bool |
| 680 | handle_clone_fail (int dst_dirfd, char const *dst_relname, |
| 681 | char const *src_name, char const *dst_name, |
| 682 | int dest_desc, bool new_dst, enum Reflink_type reflink_mode) |
| 683 | { |
| 684 | /* When the clone operation fails, report failure only with errno values |
| 685 | known to mean trouble when the clone is supported and called properly. |
| 686 | Do not report failure merely because !is_CLONENOTSUP (errno), |
| 687 | as systems may yield oddball errno values here with FICLONE, |
| 688 | and is_CLONENOTSUP is not appropriate for fclonefileat. */ |
| 689 | bool report_failure = is_terminal_error (errno); |
| 690 | |
| 691 | if (reflink_mode == REFLINK_ALWAYS || report_failure) |
| 692 | error (0, errno, _("failed to clone %s from %s"), |
| 693 | quoteaf_n (0, dst_name), quoteaf_n (1, src_name)); |
| 694 | |
| 695 | /* Remove the destination if cp --reflink=always created it |
| 696 | but cloned no data. */ |
| 697 | if (new_dst /* currently not for fclonefileat(). */ |
| 698 | && reflink_mode == REFLINK_ALWAYS |
| 699 | && ((! report_failure) || lseek (dest_desc, 0, SEEK_END) == 0) |
| 700 | && unlinkat (dst_dirfd, dst_relname, 0) != 0 && errno != ENOENT) |
| 701 | error (0, errno, _("cannot remove %s"), quoteaf (dst_name)); |
| 702 | |
| 703 | if (! report_failure) |
| 704 | copy_debug.reflink = COPY_DEBUG_UNSUPPORTED; |
| 705 | |
| 706 | if (reflink_mode == REFLINK_ALWAYS || report_failure) |
| 707 | return false; |
| 708 | |
| 709 | return true; |
| 710 | } |
| 711 | |
| 712 | /* Copy a regular file from SRC_NAME to DST_NAME aka DST_DIRFD+DST_RELNAME. |
| 713 | If the source file contains holes, copies holes and blocks of zeros |
no test coverage detected