Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix cp --sparse=auto not creating sparse-files. #6130

Closed
Closed
Changes from 2 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
fd5140f
Fix clone doing standard copy on sparse=auto
AnirbanHalder654322 Mar 25, 2024
2f29570
bug fix
AnirbanHalder654322 Mar 25, 2024
08a44bb
Making code more idiomatic
AnirbanHalder654322 Mar 25, 2024
15686cd
Added handling for destination fifo files
AnirbanHalder654322 Mar 26, 2024
1c9ed4e
Trying a fix
AnirbanHalder654322 Mar 26, 2024
9b00609
Trying fix
AnirbanHalder654322 Mar 26, 2024
2c52070
Empty
AnirbanHalder654322 Mar 26, 2024
1b9135c
Switching to old behaviour for non-sparse_files
AnirbanHalder654322 Mar 26, 2024
aef3dcc
Removed a bug
AnirbanHalder654322 Mar 26, 2024
ad9a907
Removed uncessary unwrap and added comments
AnirbanHalder654322 Mar 27, 2024
0fe9c55
Merge branch 'main' into fix_clone_behaviour
AnirbanHalder654322 Mar 27, 2024
2e80b71
Added os flags
AnirbanHalder654322 Mar 27, 2024
bd09b7a
Merge branch 'fix_clone_behaviour' of https://github.com/AnirbanHalde…
AnirbanHalder654322 Mar 27, 2024
0b7ddc8
Merge branch 'main' into fix_clone_behaviour
AnirbanHalder654322 Mar 27, 2024
cee93a4
Added tests
AnirbanHalder654322 Mar 27, 2024
3c869ca
Changed tests so they don't use du
AnirbanHalder654322 Mar 28, 2024
4137db0
Fix clone doing standard copy on sparse=auto
AnirbanHalder654322 Mar 25, 2024
bc20543
bug fix
AnirbanHalder654322 Mar 25, 2024
c1b2479
Making code more idiomatic
AnirbanHalder654322 Mar 25, 2024
6b7f79f
Added handling for destination fifo files
AnirbanHalder654322 Mar 26, 2024
dddd35f
Trying a fix
AnirbanHalder654322 Mar 26, 2024
0dc5772
Trying fix
AnirbanHalder654322 Mar 26, 2024
66de26c
Empty
AnirbanHalder654322 Mar 26, 2024
c8762be
Switching to old behaviour for non-sparse_files
AnirbanHalder654322 Mar 26, 2024
c5a2df3
Removed a bug
AnirbanHalder654322 Mar 26, 2024
7fc74fa
Removed uncessary unwrap and added comments
AnirbanHalder654322 Mar 27, 2024
2e03c4c
Added os flags
AnirbanHalder654322 Mar 27, 2024
34e3a2d
Added tests
AnirbanHalder654322 Mar 27, 2024
a82de20
Changed tests so they don't use du
AnirbanHalder654322 Mar 28, 2024
66552df
Fixed a bug where files without any data and disk allocation wouldn't…
AnirbanHalder654322 Mar 31, 2024
dd402b4
Merge branch 'uutils:main' into fix_clone_behaviour
AnirbanHalder654322 Mar 31, 2024
6a227b7
Fixing conflict
AnirbanHalder654322 Mar 31, 2024
4a2228c
Merge branch 'fix_clone_behaviour' of https://github.com/AnirbanHalde…
AnirbanHalder654322 Mar 31, 2024
b9bf4c1
Merge branch 'uutils:main' into fix_clone_behaviour
AnirbanHalder654322 Mar 31, 2024
211002e
simplified logic and added suggestions
AnirbanHalder654322 Mar 31, 2024
65213d4
Lint change
AnirbanHalder654322 Mar 31, 2024
7a14d33
Apply suggestions from code review
AnirbanHalder654322 Apr 1, 2024
d48b98f
Added testing for virtual files
AnirbanHalder654322 Apr 1, 2024
89382ef
Merge branch 'fix_clone_behaviour' of https://github.com/AnirbanHalde…
AnirbanHalder654322 Apr 1, 2024
d219243
simplified logic and added suggestions
AnirbanHalder654322 Mar 31, 2024
9503a26
Added testing for virtual files
AnirbanHalder654322 Apr 1, 2024
450c6ea
Merge conf
AnirbanHalder654322 Apr 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 52 additions & 2 deletions src/uu/cp/src/platform/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@

/// Use [`std::fs::copy`].
FSCopy,

/// Use sparse_copy
SparseCopy,
}

/// Use the Linux `ioctl_ficlone` API to do a copy-on-write clone.
Expand All @@ -53,6 +56,7 @@
match fallback {
CloneFallback::Error => Err(std::io::Error::last_os_error()),
CloneFallback::FSCopy => std::fs::copy(source, dest).map(|_| ()),
CloneFallback::SparseCopy => sparse_copy(source, dest),
}
}

Expand Down Expand Up @@ -132,6 +136,18 @@
Ok(num_bytes_copied)
}

fn check_sparse_detection(source: &Path, sparse_flag: &mut bool) -> std::io::Result<()> {
AnirbanHalder654322 marked this conversation as resolved.
Show resolved Hide resolved
let src_file = File::open(source)?;

use std::os::unix::prelude::MetadataExt;
AnirbanHalder654322 marked this conversation as resolved.
Show resolved Hide resolved

let size: usize = src_file.metadata()?.size().try_into().unwrap();
AnirbanHalder654322 marked this conversation as resolved.
Show resolved Hide resolved
let blocks: usize = src_file.metadata()?.blocks().try_into().unwrap();
if blocks < size / 512 {
*sparse_flag = true;
}
Ok(())
}
/// Copies `source` to `dest` using copy-on-write if possible.
///
/// The `source_is_fifo` flag must be set to `true` if and only if
Expand Down Expand Up @@ -159,19 +175,53 @@
copy_debug.reflink = OffloadReflinkDebug::No;
sparse_copy(source, dest)
}
(ReflinkMode::Never, _) => {
(ReflinkMode::Never, SparseMode::Never) => {
copy_debug.sparse_detection = SparseDebug::No;
copy_debug.reflink = OffloadReflinkDebug::No;
std::fs::copy(source, dest).map(|_| ())
}
(ReflinkMode::Never, SparseMode::Auto) => {
copy_debug.sparse_detection = SparseDebug::No;
copy_debug.reflink = OffloadReflinkDebug::No;
let mut sparse_flag = false;
let res = check_sparse_detection(source, &mut sparse_flag);
if res.is_ok() {
if sparse_flag {
sparse_copy(source, dest)
} else {
std::fs::copy(source, dest).map(|_| ())
}
} else {
res

Check warning on line 195 in src/uu/cp/src/platform/linux.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/cp/src/platform/linux.rs#L195

Added line #L195 was not covered by tests
}
}
AnirbanHalder654322 marked this conversation as resolved.
Show resolved Hide resolved
(ReflinkMode::Auto, SparseMode::Always) => {
copy_debug.offload = OffloadReflinkDebug::Avoided;
copy_debug.sparse_detection = SparseDebug::Zeros;
copy_debug.reflink = OffloadReflinkDebug::Unsupported;
sparse_copy(source, dest)
}

(ReflinkMode::Auto, _) => {
(ReflinkMode::Auto, SparseMode::Auto) => {
copy_debug.sparse_detection = SparseDebug::No;
copy_debug.reflink = OffloadReflinkDebug::Unsupported;
if source_is_fifo {
copy_fifo_contents(source, dest).map(|_| ())
} else {
let mut sparse_flag = false;
let res = check_sparse_detection(source, &mut sparse_flag);
if res.is_ok() {
if sparse_flag {
clone(source, dest, CloneFallback::SparseCopy)
} else {
clone(source, dest, CloneFallback::FSCopy)
}
} else {
res
}
AnirbanHalder654322 marked this conversation as resolved.
Show resolved Hide resolved
}
}
(ReflinkMode::Auto, SparseMode::Never) => {
copy_debug.sparse_detection = SparseDebug::No;
copy_debug.reflink = OffloadReflinkDebug::Unsupported;
if source_is_fifo {
Expand Down
Loading