From e2ee6784a92d84fa6418b7becdd9f0f75e35e6cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BCdiger=20Klaehn?= Date: Thu, 5 Oct 2023 22:57:41 +0300 Subject: [PATCH] feat(iroh): use reflink if possible (#1581) reflink-copy is a clone of the abandoned reflink crate. Last time there were some failures on android, so let's see if it works now... ## Description ## Notes & open questions ## Change checklist - [ ] Self-review. - [ ] Documentation updates if relevant. - [ ] Tests if relevant. --- Cargo.lock | 18 ++++++++++++++++++ iroh/Cargo.toml | 3 ++- iroh/src/baomap/flat.rs | 12 ++++++++++-- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c4a965067b..cd26159303 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1909,6 +1909,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "ioctl-sys" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bd11f3a29434026f5ff98c730b668ba74b1033637b8817940b54d040696133c" + [[package]] name = "ipconfig" version = "0.3.2" @@ -1970,6 +1976,7 @@ dependencies = [ "quinn", "rand", "range-collections", + "reflink-copy", "regex", "rustyline", "serde", @@ -3587,6 +3594,17 @@ dependencies = [ "syn 2.0.37", ] +[[package]] +name = "reflink-copy" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9e3947399fd46f412918bafde71ec68f9b3505f11ef082eeb80bc7fdf4d7caf" +dependencies = [ + "cfg-if", + "ioctl-sys", + "windows 0.51.1", +] + [[package]] name = "regex" version = "1.9.5" diff --git a/iroh/Cargo.toml b/iroh/Cargo.toml index dcad064451..11130733b9 100644 --- a/iroh/Cargo.toml +++ b/iroh/Cargo.toml @@ -67,13 +67,14 @@ colored = { version = "2.0.4", optional = true } # Examples ed25519-dalek = { version = "2.0.0", features = ["serde", "rand_core"], optional = true } +reflink-copy = { version = "0.1.8", optional = true } [features] default = ["cli", "metrics"] cli = ["clap", "config", "console", "dirs-next", "indicatif", "multibase", "quic-rpc/quinn-transport", "tokio/rt-multi-thread", "tracing-subscriber", "flat-db", "mem-db", "iroh-collection", "shell-words", "shellexpand", "rustyline", "colored", "toml", "human-time", "comfy-table"] metrics = ["iroh-metrics"] mem-db = [] -flat-db = [] +flat-db = ["reflink-copy"] iroh-collection = [] test = [] example-sync = ["cli"] diff --git a/iroh/src/baomap/flat.rs b/iroh/src/baomap/flat.rs index 184a80b429..ebf36116f4 100644 --- a/iroh/src/baomap/flat.rs +++ b/iroh/src/baomap/flat.rs @@ -883,7 +883,11 @@ impl Store { let temp_path = self.temp_path(); // copy the data, since it is not stable progress.try_send(ImportProgress::CopyProgress { id, offset: 0 })?; - std::fs::copy(&path, &temp_path)?; + if reflink_copy::reflink_or_copy(&path, &temp_path)?.is_none() { + tracing::debug!("reflinked {} to {}", path.display(), temp_path.display()); + } else { + tracing::debug!("copied {} to {}", path.display(), temp_path.display()); + } ImportFile::TempFile(temp_path) } }; @@ -1165,7 +1169,11 @@ impl Store { tracing::debug!("copying {} to {}", source.display(), target.display()); progress(0)?; // todo: progress - std::fs::copy(&source, &target)?; + if reflink_copy::reflink_or_copy(&source, &target)?.is_none() { + tracing::debug!("reflinked {} to {}", source.display(), target.display()); + } else { + tracing::debug!("copied {} to {}", source.display(), target.display()); + } progress(size)?; let mut state = self.0.state.write().unwrap(); let Some(entry) = state.complete.get_mut(&hash) else {