From f37afb04bb45d989807ebf991fbbdde22a483c0d Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Fri, 26 Sep 2025 10:08:54 -0600 Subject: [PATCH] Add progress callback to clone function --- src/bin/clone.rs | 28 ++++++++++++++++++++-------- src/clone.rs | 29 ++++++++++++++++++++++------- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/src/bin/clone.rs b/src/bin/clone.rs index 13a6cdca73..4ef8a299b3 100644 --- a/src/bin/clone.rs +++ b/src/bin/clone.rs @@ -112,7 +112,17 @@ fn main() { } }; - match clone(&mut fs_old, &mut fs) { + let size_old = fs_old.header.size(); + let free_old = fs_old.allocator().free() * redoxfs::BLOCK_SIZE; + let used_old = size_old - free_old; + match clone(&mut fs_old, &mut fs, |used| { + eprint!( + "{}%: {}/{}\r", + (used * 100) / used_old, + used / 1000 / 1000, + used_old / 1000 / 1000 + ); + }) { Ok(()) => (), Err(err) => { println!( @@ -124,11 +134,13 @@ fn main() { } let uuid = Uuid::from_bytes(fs.header.uuid()); - println!( - "redoxfs-clone: created filesystem on {}, reserved {} blocks, size {} MB, uuid {}", - disk_path, - fs.block, - fs.header.size() / 1000 / 1000, - uuid.hyphenated() - ); + let size = fs.header.size(); + let free = fs.allocator().free() * redoxfs::BLOCK_SIZE; + let used = size - free; + println!("redoxfs-clone: created filesystem on {}", disk_path,); + println!("\treserved: {} blocks", fs.block); + println!("\tuuid: {}", uuid.hyphenated()); + println!("\tsize: {} MB", size / 1000 / 1000); + println!("\tused: {} MB", used / 1000 / 1000); + println!("\tfree: {} MB", free / 1000 / 1000); } diff --git a/src/clone.rs b/src/clone.rs index 67eeb9a99c..5d3c85ea28 100644 --- a/src/clone.rs +++ b/src/clone.rs @@ -10,12 +10,13 @@ fn syscall_err(err: syscall::Error) -> io::Error { } //TODO: handle hard links -pub fn clone_at( +pub fn clone_at( tx_old: &mut Transaction, parent_ptr_old: TreePtr, fs: &mut FileSystem, parent_ptr: TreePtr, buf: &mut [u8], + progress: &F, ) -> syscall::Result<()> { let mut entries = Vec::new(); tx_old.child_nodes(parent_ptr_old, &mut entries)?; @@ -53,26 +54,40 @@ pub fn clone_at( Ok(node_ptr) })?; + let size = fs.header.size(); + let free = fs.allocator().free() * BLOCK_SIZE; + progress(size - free); + if node_old.data().is_dir() { - clone_at(tx_old, node_ptr_old, fs, node_ptr, buf)?; + clone_at(tx_old, node_ptr_old, fs, node_ptr, buf, progress)?; } } Ok(()) } -pub fn clone( +pub fn clone( fs_old: &mut FileSystem, fs: &mut FileSystem, + progress: F, ) -> syscall::Result<()> { fs_old.tx(|tx_old| { // Clone at root node let mut buf = vec![0; 4 * 1024 * 1024]; - clone_at(tx_old, TreePtr::root(), fs, TreePtr::root(), &mut buf)?; + clone_at( + tx_old, + TreePtr::root(), + fs, + TreePtr::root(), + &mut buf, + &progress, + )?; - // Squash alloc log - fs.tx(|tx| tx.sync(true))?; + fs.tx(|tx| { + // Squash alloc log + tx.sync(true)?; - Ok(()) + Ok(()) + }) }) }