diff --git a/src/uu/cp/src/platform/linux.rs b/src/uu/cp/src/platform/linux.rs index 4af897d3c..f0b2af752 100644 --- a/src/uu/cp/src/platform/linux.rs +++ b/src/uu/cp/src/platform/linux.rs @@ -113,6 +113,7 @@ pub(crate) fn copy_on_write( source_is_fifo: bool, ) -> CopyResult<()> { let result = match (reflink_mode, sparse_mode) { + (ReflinkMode::Never, SparseMode::Always) => sparse_copy(source, dest), (ReflinkMode::Never, _) => std::fs::copy(source, dest).map(|_| ()), (ReflinkMode::Auto, SparseMode::Always) => sparse_copy(source, dest), diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 14cc00ca0..39af0c295 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -2318,3 +2318,30 @@ fn test_copy_contents_fifo() { assert!(output.stderr.is_empty()); assert_eq!(at.read("outfile"), "foo"); } + +#[cfg(target_os = "linux")] +#[test] +fn test_reflink_never_sparse_always() { + let (at, mut ucmd) = at_and_ucmd!(); + + // Create a file and make it a large sparse file. + // + // On common Linux filesystems, setting the length to one megabyte + // should cause the file to become a sparse file, but it depends + // on the system. + std::fs::File::create(at.plus("src")) + .unwrap() + .set_len(1024 * 1024) + .unwrap(); + + ucmd.args(&["--reflink=never", "--sparse=always", "src", "dest"]) + .succeeds() + .no_stdout() + .no_stderr(); + at.file_exists("dest"); + + let src_metadata = std::fs::metadata(at.plus("src")).unwrap(); + let dest_metadata = std::fs::metadata(at.plus("dest")).unwrap(); + assert_eq!(src_metadata.blocks(), dest_metadata.blocks()); + assert_eq!(dest_metadata.len(), 1024 * 1024); +}