Add progress callback to clone function
This commit is contained in:
+20
-8
@@ -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);
|
||||
}
|
||||
|
||||
+22
-7
@@ -10,12 +10,13 @@ fn syscall_err(err: syscall::Error) -> io::Error {
|
||||
}
|
||||
|
||||
//TODO: handle hard links
|
||||
pub fn clone_at<D: Disk, E: Disk>(
|
||||
pub fn clone_at<D: Disk, E: Disk, F: Fn(u64)>(
|
||||
tx_old: &mut Transaction<D>,
|
||||
parent_ptr_old: TreePtr<Node>,
|
||||
fs: &mut FileSystem<E>,
|
||||
parent_ptr: TreePtr<Node>,
|
||||
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<D: Disk, E: Disk>(
|
||||
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<D: Disk, E: Disk>(
|
||||
pub fn clone<D: Disk, E: Disk, F: Fn(u64)>(
|
||||
fs_old: &mut FileSystem<D>,
|
||||
fs: &mut FileSystem<E>,
|
||||
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(())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user