diff --git a/crudd/src/main.rs b/crudd/src/main.rs index f99d79c89..1b3ae3f51 100644 --- a/crudd/src/main.rs +++ b/crudd/src/main.rs @@ -171,7 +171,7 @@ async fn cmd_read( cmp::min(num_bytes, native_block_size - offset_misalignment); if offset_misalignment != 0 { // Read the full block - let mut buffer = Buffer::new(native_block_size as usize); + let mut buffer = Buffer::new(1, native_block_size as usize); let block_idx = opt.byte_offset / native_block_size; let offset = Block::new(block_idx, native_block_size.trailing_zeros()); crucible.read(offset, &mut buffer).await?; @@ -207,9 +207,13 @@ async fn cmd_read( let cmd_count = num_bytes / (opt.iocmd_block_count * native_block_size); let remainder = num_bytes % (opt.iocmd_block_count * native_block_size); - let buffer_size = (opt.iocmd_block_count * native_block_size) as usize; let mut buffers: Vec = (0..opt.pipeline_length) - .map(|_| Buffer::new(buffer_size)) + .map(|_| { + Buffer::new( + opt.iocmd_block_count as usize, + native_block_size as usize, + ) + }) .collect(); // Issue all of our read commands @@ -255,7 +259,8 @@ async fn cmd_read( // let block_remainder = remainder % native_block_size; // round up let blocks = (remainder + native_block_size - 1) / native_block_size; - let mut buffer = Buffer::new((blocks * native_block_size) as usize); + let mut buffer = + Buffer::new(blocks as usize, native_block_size as usize); let block_idx = (cmd_count * opt.iocmd_block_count) + block_offset; let offset = Block::new(block_idx, native_block_size.trailing_zeros()); crucible.read(offset, &mut buffer).await?; @@ -309,7 +314,7 @@ async fn write_remainder_and_finalize<'a, T: BlockIO>( offset.value + uflow_blocks, native_block_size.trailing_zeros(), ); - let mut uflow_r_buf = Buffer::new(native_block_size as usize); + let mut uflow_r_buf = Buffer::new(1, native_block_size as usize); crucible.read(uflow_offset, &mut uflow_r_buf).await?; // Copy it into w_buf @@ -394,7 +399,7 @@ async fn cmd_write( // We need to read-modify-write here. // Read the full block - let mut buffer = Buffer::new(native_block_size as usize); + let mut buffer = Buffer::new(1, native_block_size as usize); let block_idx = opt.byte_offset / native_block_size; let offset = Block::new(block_idx, native_block_size.trailing_zeros()); crucible.read(offset, &mut buffer).await?; diff --git a/crutest/src/cli.rs b/crutest/src/cli.rs index 1834cf72f..35ebbee2e 100644 --- a/crutest/src/cli.rs +++ b/crutest/src/cli.rs @@ -224,9 +224,7 @@ async fn cli_read( * Convert offset to its byte value. */ let offset = Block::new(block_index as u64, ri.block_size.trailing_zeros()); - let length: usize = size * ri.block_size as usize; - - let mut data = crucible::Buffer::from_vec(vec![255; length]); + let mut data = crucible::Buffer::repeat(255, size, ri.block_size as usize); println!("Read at block {:5}, len:{:7}", offset.value, data.len()); guest.read(offset, &mut data).await?; diff --git a/crutest/src/main.rs b/crutest/src/main.rs index cc40fe5ce..77578ec46 100644 --- a/crutest/src/main.rs +++ b/crutest/src/main.rs @@ -1120,8 +1120,11 @@ async fn verify_volume( io_sz }; - let length: usize = next_io_blocks * ri.block_size as usize; - let mut data = crucible::Buffer::from_vec(vec![255; length]); + let mut data = crucible::Buffer::repeat( + 255, + next_io_blocks, + ri.block_size as usize, + ); guest.read(offset, &mut data).await?; let dl = data.into_vec(); @@ -1359,8 +1362,8 @@ async fn balloon_workload( guest.write(offset, data).await?; guest.flush(None).await?; - let length: usize = size * ri.block_size as usize; - let mut data = crucible::Buffer::from_vec(vec![255; length]); + let mut data = + crucible::Buffer::repeat(255, size, ri.block_size as usize); guest.read(offset, &mut data).await?; let dl = data.into_vec(); @@ -1576,8 +1579,8 @@ async fn generic_workload( guest.write(offset, data).await?; } else { // Read (+ verify) - let length: usize = size * ri.block_size as usize; - let mut data = crucible::Buffer::from_vec(vec![255; length]); + let mut data = + crucible::Buffer::repeat(255, size, ri.block_size as usize); if !quiet { match wtq { WhenToQuit::Count { count } => { @@ -1602,6 +1605,7 @@ async fn generic_workload( } guest.read(offset, &mut data).await?; + let data_len = data.len(); let dl = data.into_vec(); match validate_vec( dl, @@ -1611,7 +1615,7 @@ async fn generic_workload( false, ) { ValidateStatus::Bad | ValidateStatus::InRange => { - bail!("Verify Error at {} len:{}", block_index, length); + bail!("Verify Error at {block_index} len:{data_len}") } ValidateStatus::Good => {} } @@ -2065,8 +2069,9 @@ async fn perf_workload( }) .collect(); - let mut read_buffers: Vec = - (0..io_depth).map(|_| Buffer::new(io_size)).collect(); + let mut read_buffers: Vec = (0..io_depth) + .map(|_| Buffer::new(blocks_per_io, ri.block_size as usize)) + .collect(); let es = ri.extent_size.value; let ec = ri.total_blocks as u64 / es; @@ -2229,8 +2234,7 @@ async fn one_workload(guest: &Arc, ri: &mut RegionInfo) -> Result<()> { guest.write(offset, data).await?; - let length: usize = size * ri.block_size as usize; - let mut data = crucible::Buffer::from_vec(vec![255; length]); + let mut data = crucible::Buffer::repeat(255, size, ri.block_size as usize); println!("Read at block {:5}, len:{:7}", offset.value, data.len()); guest.read(offset, &mut data).await?; @@ -2383,8 +2387,8 @@ async fn write_flush_read_workload( guest.flush(None).await?; - let length: usize = size * ri.block_size as usize; - let mut data = crucible::Buffer::from_vec(vec![255; length]); + let mut data = + crucible::Buffer::repeat(255, size, ri.block_size as usize); guest.read(offset, &mut data).await?; let dl = data.into_vec(); @@ -2544,8 +2548,8 @@ async fn repair_workload( guest.write(offset, data).await?; } else { // Read - let length: usize = size * ri.block_size as usize; - let mut data = crucible::Buffer::from_vec(vec![255; length]); + let mut data = + crucible::Buffer::repeat(255, size, ri.block_size as usize); println!( "{:>0width$}/{:>0width$} Read \ block {:>bw$} len {:>sw$}", @@ -2626,13 +2630,12 @@ async fn demo_workload( futures.push(future); } else { // Read - let length: usize = size * ri.block_size as usize; - + let block_size = ri.block_size as usize; let future = { let guest = guest.clone(); tokio::spawn(async move { let mut data = - crucible::Buffer::from_vec(vec![255; length]); + crucible::Buffer::repeat(255, size, block_size); guest.read(offset, &mut data).await?; Ok(data) }) @@ -2699,8 +2702,7 @@ async fn span_workload(guest: &Arc, ri: &mut RegionInfo) -> Result<()> { println!("Sending a flush"); guest.flush(None).await?; - let length: usize = 2 * ri.block_size as usize; - let mut data = crucible::Buffer::from_vec(vec![99; length]); + let mut data = crucible::Buffer::repeat(99, 2, ri.block_size as usize); println!("Sending a read spanning two extents"); guest.read(offset, &mut data).await?; @@ -2739,8 +2741,7 @@ async fn big_workload(guest: &Arc, ri: &mut RegionInfo) -> Result<()> { guest.flush(None).await?; - let length: usize = ri.block_size as usize; - let mut data = crucible::Buffer::from_vec(vec![255; length]); + let mut data = crucible::Buffer::repeat(255, 1, ri.block_size as usize); guest.read(offset, &mut data).await?; let dl = data.into_vec(); @@ -2871,7 +2872,7 @@ async fn dep_workload(guest: &Arc, ri: &mut RegionInfo) -> Result<()> { futures.push(future); } else { let mut data = - crucible::Buffer::from_vec(vec![0; ri.block_size as usize]); + crucible::Buffer::repeat(0, 1, ri.block_size as usize); println!( "Loop:{} send read {} @ offset:{} len:{}", diff --git a/integration_tests/src/lib.rs b/integration_tests/src/lib.rs index 8c0053a34..6728f07ae 100644 --- a/integration_tests/src/lib.rs +++ b/integration_tests/src/lib.rs @@ -397,7 +397,7 @@ mod test { volume.activate().await?; // Verify contents are zero on init - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -413,7 +413,7 @@ mod test { .await?; // Read parent, verify contents - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -449,7 +449,7 @@ mod test { volume.activate().await?; // A read of zero length does not error. - let mut buffer = Buffer::new(0); + let mut buffer = Buffer::new(0, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -499,7 +499,7 @@ mod test { ) .await?; - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); in_memory_data .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -524,7 +524,7 @@ mod test { volume.activate().await?; // Verify contents are 11 on init - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -549,7 +549,7 @@ mod test { } // Verify parent wasn't written to - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); in_memory_data .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -557,7 +557,7 @@ mod test { assert_eq!(vec![11; BLOCK_SIZE * 10], &buffer[..]); // Read and verify contents - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -588,7 +588,7 @@ mod test { ) .await?; - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); in_memory_data .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -624,7 +624,7 @@ mod test { volume.activate().await?; // Verify contents are 11 on init - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -640,7 +640,7 @@ mod test { .await?; // Verify parent wasn't written to - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); in_memory_data .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -648,7 +648,7 @@ mod test { assert_eq!(vec![11; BLOCK_SIZE * 10], &buffer[..]); // Read and verify contents - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -709,7 +709,7 @@ mod test { volume.activate().await?; // Read one block: should be all 0xff - let mut buffer = Buffer::new(BLOCK_SIZE); + let mut buffer = Buffer::new(1, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -725,7 +725,7 @@ mod test { .await?; // Read one block: should be all 0x01 - let mut buffer = Buffer::new(BLOCK_SIZE); + let mut buffer = Buffer::new(1, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -762,7 +762,7 @@ mod test { volume.activate().await?; // Read one block: should be all 0x00 - let mut buffer = Buffer::new(BLOCK_SIZE); + let mut buffer = Buffer::new(1, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -818,7 +818,7 @@ mod test { .await?; // Read volume, verify contents - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -834,7 +834,7 @@ mod test { .await?; // Read volume, verify original contents - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -889,7 +889,7 @@ mod test { .await?; // Read parent, verify contents - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -905,7 +905,7 @@ mod test { .await?; // Read volume, verify original contents - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -970,7 +970,7 @@ mod test { .await?; // Read and verify - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -1035,7 +1035,8 @@ mod test { volume.activate().await?; - let full_volume_size = BLOCK_SIZE * 20; + let full_volume_blocks = 20; + let full_volume_size = BLOCK_SIZE * full_volume_blocks; // Write data in volume .write_unwritten( @@ -1045,7 +1046,7 @@ mod test { .await?; // Read parent, verify contents - let mut buffer = Buffer::new(full_volume_size); + let mut buffer = Buffer::new(full_volume_blocks, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -1061,7 +1062,7 @@ mod test { .await?; // Read volume, verify original contents - let mut buffer = Buffer::new(full_volume_size); + let mut buffer = Buffer::new(full_volume_blocks, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -1120,7 +1121,8 @@ mod test { let volume = Arc::new(Volume::construct(vcr, None, csl()).await?); volume.activate().await?; - let full_volume_size = BLOCK_SIZE * 20; + let full_volume_blocks = 20; + let full_volume_size = BLOCK_SIZE * full_volume_blocks; // Write data to last block of first vol, and first block of // second vol. @@ -1132,7 +1134,7 @@ mod test { .await?; // Read parent, verify contents - let mut buffer = Buffer::new(BLOCK_SIZE * 2); + let mut buffer = Buffer::new(2, BLOCK_SIZE); volume .read(Block::new(9, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -1151,7 +1153,7 @@ mod test { // Read full volume, verify first write_unwritten still valid, but the // other blocks of the 2nd write_unwritten are updated. - let mut buffer = Buffer::new(full_volume_size); + let mut buffer = Buffer::new(full_volume_blocks, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -1225,7 +1227,8 @@ mod test { let volume = Arc::new(Volume::construct(vcr, None, csl()).await?); volume.activate().await?; - let full_volume_size = BLOCK_SIZE * 20; + let full_volume_blocks = 20; + let full_volume_size = BLOCK_SIZE * full_volume_blocks; // Write data to last block of first vol, and first block of // second vol. @@ -1255,7 +1258,7 @@ mod test { .await?; // Read full volume - let mut buffer = Buffer::new(full_volume_size); + let mut buffer = Buffer::new(full_volume_blocks, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -1311,7 +1314,7 @@ mod test { .await?; // Read back in_memory, verify 1s - let mut buffer = Buffer::new(BLOCK_SIZE * 5); + let mut buffer = Buffer::new(5, BLOCK_SIZE); in_memory_data .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -1336,7 +1339,7 @@ mod test { volume.activate().await?; // Verify parent contents in one read - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -1355,7 +1358,7 @@ mod test { } // Verify volume contents in one read - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -1416,7 +1419,7 @@ mod test { volume.activate().await?; // Verify contents are 11 at startup - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -1437,7 +1440,7 @@ mod test { .await?; // Read and verify contents - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -1499,7 +1502,7 @@ mod test { volume.activate().await?; // Verify contents of RO parent are 1s at startup - let mut buffer = Buffer::new(BLOCK_SIZE * 5); + let mut buffer = Buffer::new(5, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -1507,7 +1510,7 @@ mod test { assert_eq!(vec![11; BLOCK_SIZE * 5], &buffer[..]); // Verify contents of blocks 5-10 are zero. - let mut buffer = Buffer::new(BLOCK_SIZE * 5); + let mut buffer = Buffer::new(5, BLOCK_SIZE); volume .read(Block::new(5, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -1528,7 +1531,7 @@ mod test { .await?; // Read and verify contents - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -1621,7 +1624,7 @@ mod test { volume.scrub(None, None).await.unwrap(); // Read and verify contents - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -1695,7 +1698,7 @@ mod test { volume.activate().await?; // Verify contents are 11 at startup - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -1714,7 +1717,7 @@ mod test { volume.scrub(None, None).await.unwrap(); // Read and verify contents - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -1811,7 +1814,7 @@ mod test { .await?; // Read and verify contents - let mut buffer = Buffer::new(BLOCK_SIZE * 2); + let mut buffer = Buffer::new(2, BLOCK_SIZE); volume .read(Block::new(9, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -1830,7 +1833,7 @@ mod test { volume.scrub(None, None).await.unwrap(); // Read full volume - let mut buffer = Buffer::new(BLOCK_SIZE * 20); + let mut buffer = Buffer::new(20, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -1938,7 +1941,7 @@ mod test { .await?; // Read and verify contents - let mut buffer = Buffer::new(BLOCK_SIZE * 2); + let mut buffer = Buffer::new(2, BLOCK_SIZE); volume .read(Block::new(9, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -1967,7 +1970,7 @@ mod test { volume.scrub(None, None).await.unwrap(); // Read full volume - let mut buffer = Buffer::new(BLOCK_SIZE * 20); + let mut buffer = Buffer::new(20, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -2041,14 +2044,14 @@ mod test { volume2.activate().await?; // Read one block: should be all 0x00 - let mut buffer = Buffer::new(BLOCK_SIZE); + let mut buffer = Buffer::new(1, BLOCK_SIZE); volume1 .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; assert_eq!(vec![0x00; BLOCK_SIZE], &buffer[..]); - let mut buffer = Buffer::new(BLOCK_SIZE); + let mut buffer = Buffer::new(1, BLOCK_SIZE); volume2 .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -2094,7 +2097,7 @@ mod test { volume.activate().await?; // Verify contents are 00 at startup - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -2113,7 +2116,7 @@ mod test { volume.scrub(None, None).await.unwrap(); // Read and verify contents - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -2194,7 +2197,9 @@ mod test { volume.activate().await?; - let mut buffer = Buffer::new(volume.total_size().await? as usize); + let volume_size = volume.total_size().await? as usize; + assert_eq!(volume_size % BLOCK_SIZE, 0); + let mut buffer = Buffer::new(volume_size / BLOCK_SIZE, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -2251,7 +2256,9 @@ mod test { // Validate that source blocks originally come from the read-only parent { - let mut buffer = Buffer::new(volume.total_size().await? as usize); + let volume_size = volume.total_size().await? as usize; + assert_eq!(volume_size % BLOCK_SIZE, 0); + let mut buffer = Buffer::new(volume_size / BLOCK_SIZE, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -2271,7 +2278,9 @@ mod test { .await?; { - let mut buffer = Buffer::new(volume.total_size().await? as usize); + let volume_size = volume.total_size().await? as usize; + assert_eq!(volume_size % BLOCK_SIZE, 0); + let mut buffer = Buffer::new(volume_size / BLOCK_SIZE, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -2368,7 +2377,9 @@ mod test { volume.activate().await?; - let mut buffer = Buffer::new(volume.total_size().await? as usize); + let volume_size = volume.total_size().await? as usize; + assert_eq!(volume_size % BLOCK_SIZE, 0); + let mut buffer = Buffer::new(volume_size / BLOCK_SIZE, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -2433,7 +2444,9 @@ mod test { // Validate that source blocks originally come from the read-only parent { - let mut buffer = Buffer::new(volume.total_size().await? as usize); + let volume_size = volume.total_size().await? as usize; + assert_eq!(volume_size % BLOCK_SIZE, 0); + let mut buffer = Buffer::new(volume_size / BLOCK_SIZE, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -2453,7 +2466,9 @@ mod test { .await?; { - let mut buffer = Buffer::new(volume.total_size().await? as usize); + let volume_size = volume.total_size().await? as usize; + assert_eq!(volume_size % BLOCK_SIZE, 0); + let mut buffer = Buffer::new(volume_size / BLOCK_SIZE, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -2543,7 +2558,9 @@ mod test { volume.activate().await?; // Validate that source blocks are the same - let mut buffer = Buffer::new(volume.total_size().await? as usize); + let volume_size = volume.total_size().await? as usize; + assert_eq!(volume_size % BLOCK_SIZE, 0); + let mut buffer = Buffer::new(volume_size / BLOCK_SIZE, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -2633,7 +2650,9 @@ mod test { } // Read back what we wrote. - let mut buffer = Buffer::new(volume.total_size().await? as usize); + let volume_size = volume.total_size().await? as usize; + assert_eq!(volume_size % BLOCK_SIZE, 0); + let mut buffer = Buffer::new(volume_size / BLOCK_SIZE, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -2941,7 +2960,9 @@ mod test { } // Read back what we wrote. - let mut buffer = Buffer::new(new_volume.total_size().await? as usize); + let volume_size = volume.total_size().await? as usize; + assert_eq!(volume_size % BLOCK_SIZE, 0); + let mut buffer = Buffer::new(volume_size / BLOCK_SIZE, BLOCK_SIZE); new_volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -3004,7 +3025,9 @@ mod test { } for (i, random_buffer) in chunks { - let mut buffer = Buffer::new(CHUNK_SIZE); + assert_eq!(CHUNK_SIZE % BLOCK_SIZE, 0); + let mut buffer = + Buffer::new(CHUNK_SIZE / BLOCK_SIZE, BLOCK_SIZE); volume .read( Block::new(i as u64, BLOCK_SIZE.trailing_zeros()), @@ -3044,7 +3067,7 @@ mod test { guest.query_work_queue().await?; // Verify contents are zero on init - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); guest .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -3060,7 +3083,7 @@ mod test { .await?; // Read parent, verify contents - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); guest .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -3088,7 +3111,7 @@ mod test { guest.query_work_queue().await?; // Read of length 0 - let mut buffer = Buffer::new(0); + let mut buffer = Buffer::new(0, BLOCK_SIZE); guest .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -3171,7 +3194,7 @@ mod test { } // Read back our block post replacement, verify contents - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); guest .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -3287,7 +3310,7 @@ mod test { .await?; // Read parent, verify contents - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); guest .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -3303,7 +3326,7 @@ mod test { .await?; // Read back the same blocks. - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); guest .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -3320,7 +3343,7 @@ mod test { .await?; // Read back the same blocks. - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); guest .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -3369,7 +3392,7 @@ mod test { .await?; // Read back the first block. - let mut buffer = Buffer::new(BLOCK_SIZE); + let mut buffer = Buffer::new(1, BLOCK_SIZE); guest .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -3378,7 +3401,7 @@ mod test { assert_eq!(vec![0x55_u8; BLOCK_SIZE], &buffer[..]); // Read back the next two blocks. - let mut buffer = Buffer::new(BLOCK_SIZE * 2); + let mut buffer = Buffer::new(2, BLOCK_SIZE); guest .read(Block::new(1, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -3427,7 +3450,7 @@ mod test { .await?; // Read back the all three blocks. - let mut buffer = Buffer::new(BLOCK_SIZE * 3); + let mut buffer = Buffer::new(3, BLOCK_SIZE); guest .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -3486,7 +3509,7 @@ mod test { .await?; // Read back the all three blocks. - let mut buffer = Buffer::new(BLOCK_SIZE * 3); + let mut buffer = Buffer::new(3, BLOCK_SIZE); guest .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -3540,7 +3563,7 @@ mod test { .await?; // Read back both blocks - let mut buffer = Buffer::new(BLOCK_SIZE * 2); + let mut buffer = Buffer::new(2, BLOCK_SIZE); guest .read(Block::new(4, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -3594,7 +3617,7 @@ mod test { .await?; // Read back both blocks - let mut buffer = Buffer::new(BLOCK_SIZE * 2); + let mut buffer = Buffer::new(2, BLOCK_SIZE); guest .read(Block::new(4, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -3638,7 +3661,7 @@ mod test { assert!(res.is_err()); // Read a block past the end of the extent - let mut buffer = Buffer::new(BLOCK_SIZE); + let mut buffer = Buffer::new(1, BLOCK_SIZE); let res = guest .read(Block::new(11, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await; @@ -3674,7 +3697,7 @@ mod test { assert!(res.is_err()); // Read a block with buffer that extends past the end of the region - let mut buffer = Buffer::new(BLOCK_SIZE * 2); + let mut buffer = Buffer::new(2, BLOCK_SIZE); let res = guest .read(Block::new(10, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await; @@ -3826,7 +3849,8 @@ mod test { let volume = Volume::construct(vcr, None, csl()).await.unwrap(); volume.activate().await.unwrap(); - let mut buffer = Buffer::new(bytes.len()); + assert_eq!(bytes.len() % BLOCK_SIZE, 0); + let mut buffer = Buffer::new(bytes.len() / BLOCK_SIZE, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await @@ -3934,7 +3958,7 @@ mod test { .unwrap(); volume.activate().await.unwrap(); - let mut buffer = Buffer::new(5120); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await @@ -3986,7 +4010,7 @@ mod test { let volume = Volume::construct(vcr, None, log.clone()).await.unwrap(); volume.activate().await.unwrap(); - let mut buffer = Buffer::new(5120); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await @@ -4064,7 +4088,7 @@ mod test { let volume = Volume::construct(vcr, None, csl()).await.unwrap(); volume.activate().await.unwrap(); - let mut buffer = Buffer::new(5120); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await @@ -4127,17 +4151,16 @@ mod test { let volume = Volume::construct(vcr, None, csl()).await.unwrap(); volume.activate().await.unwrap(); + use crucible_pantry::pantry::PantryEntry; + assert_eq!(PantryEntry::MAX_CHUNK_SIZE % BLOCK_SIZE, 0); let mut buffer = - Buffer::new(crucible_pantry::pantry::PantryEntry::MAX_CHUNK_SIZE); + Buffer::new(PantryEntry::MAX_CHUNK_SIZE / BLOCK_SIZE, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await .unwrap(); - assert_eq!( - vec![0x99; crucible_pantry::pantry::PantryEntry::MAX_CHUNK_SIZE], - &buffer[..] - ); + assert_eq!(vec![0x99; PantryEntry::MAX_CHUNK_SIZE], &buffer[..]); } /// Assert that the Pantry will fail for non-block sized writes @@ -4265,7 +4288,8 @@ mod test { let volume = Volume::construct(vcr, None, csl()).await.unwrap(); volume.activate().await.unwrap(); - let mut buffer = Buffer::new(data.len()); + assert_eq!(data.len() % BLOCK_SIZE, 0); + let mut buffer = Buffer::new(data.len() / BLOCK_SIZE, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await @@ -4360,7 +4384,8 @@ mod test { let volume = Volume::construct(vcr, None, log.clone()).await.unwrap(); volume.activate().await.unwrap(); - let mut buffer = Buffer::new(data.len()); + assert_eq!(data.len() % BLOCK_SIZE, 0); + let mut buffer = Buffer::new(data.len() / BLOCK_SIZE, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await @@ -4851,7 +4876,7 @@ mod test { .unwrap(); // Read parent, verify contents - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await @@ -4891,7 +4916,7 @@ mod test { info!(log, "Replace VCR now: {:?}", replacement); volume.target_replace(original, replacement).await.unwrap(); info!(log, "send read now"); - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await diff --git a/measure_iops/src/main.rs b/measure_iops/src/main.rs index 1443f943c..d3a0ccc05 100644 --- a/measure_iops/src/main.rs +++ b/measure_iops/src/main.rs @@ -124,7 +124,13 @@ async fn main() -> Result<()> { let total_blocks: u64 = guest.total_size().await? / bsz; let io_size = if let Some(io_size_in_bytes) = opt.io_size_in_bytes { - io_size_in_bytes + if io_size_in_bytes as u64 % bsz != 0 { + bail!( + "invalid io size: {io_size_in_bytes} is not divisible by {bsz}" + ); + } else { + io_size_in_bytes + } } else { bsz as usize }; @@ -154,7 +160,10 @@ async fn main() -> Result<()> { rng.gen::() % (total_blocks - io_size as u64 / bsz); if rng.gen::() { - ops.push(RandomOp::Read(offset, Buffer::new(io_size))); + ops.push(RandomOp::Read( + offset, + Buffer::new(io_size / bsz as usize, bsz as usize), + )); } else { let bytes = Bytes::from(if opt.all_zeroes { vec![0u8; io_size] diff --git a/pantry/src/pantry.rs b/pantry/src/pantry.rs index 425e7bbaa..60d638e8c 100644 --- a/pantry/src/pantry.rs +++ b/pantry/src/pantry.rs @@ -292,7 +292,13 @@ impl PantryEntry { ); } - let mut buffer = crucible::Buffer::new(size); + let volume_block_size = + self.volume.check_data_size(size).await? as usize; + + let mut buffer = crucible::Buffer::new( + size / volume_block_size as usize, + volume_block_size, + ); self.volume .read_from_byte_offset(offset, &mut buffer) @@ -326,8 +332,19 @@ impl PantryEntry { block_size, ); } + if Self::MAX_CHUNK_SIZE % block_size as usize != 0 { + crucible_bail!( + InvalidNumberOfBlocks, + "max chunk size {} not divisible by block size {}!", + Self::MAX_CHUNK_SIZE, + block_size, + ); + } - let mut data = crucible::Buffer::with_capacity(Self::MAX_CHUNK_SIZE); + let mut data = crucible::Buffer::with_capacity( + Self::MAX_CHUNK_SIZE / block_size as usize, + block_size as usize, + ); for chunk in (0..size_to_validate).step_by(Self::MAX_CHUNK_SIZE) { let start = chunk; @@ -335,8 +352,14 @@ impl PantryEntry { start + Self::MAX_CHUNK_SIZE as u64, size_to_validate, ); + let length = (end - start) as usize; + + // Both size_to_validate and MAX_CHUNK_SIZE are even multiples of + // block_size (checked above), so we should always be operating on + // blocks here. + assert_eq!(length % block_size as usize, 0); - data.reset((end - start) as usize); + data.reset(length / block_size as usize, block_size as usize); self.volume.read_from_byte_offset(start, &mut data).await?; diff --git a/upstairs/src/block_io.rs b/upstairs/src/block_io.rs index 835b7c075..13c86c76e 100644 --- a/upstairs/src/block_io.rs +++ b/upstairs/src/block_io.rs @@ -65,6 +65,7 @@ impl BlockIO for FileBlockIO { offset: Block, data: &mut Buffer, ) -> Result<(), CrucibleError> { + self.check_data_size(data.len()).await?; let start: usize = (offset.value * self.block_size) as usize; let mut file = self.file.lock().await; @@ -82,6 +83,7 @@ impl BlockIO for FileBlockIO { offset: Block, data: Bytes, ) -> Result<(), CrucibleError> { + self.check_data_size(data.len()).await?; let start = offset.value * self.block_size; let mut file = self.file.lock().await; @@ -207,6 +209,7 @@ impl BlockIO for ReqwestBlockIO { offset: Block, data: &mut Buffer, ) -> Result<(), CrucibleError> { + self.check_data_size(data.len()).await?; let cc = self.next_count(); cdt::reqwest__read__start!(|| (cc, self.uuid)); diff --git a/upstairs/src/block_req.rs b/upstairs/src/block_req.rs index 69f20b9b9..61216cb28 100644 --- a/upstairs/src/block_req.rs +++ b/upstairs/src/block_req.rs @@ -149,7 +149,7 @@ mod test { async fn test_blockreq_and_blockreqwaiter_with_buffer() { let (brw, res) = BlockReqWaiter::pair(); - res.send_ok_with_buffer(Buffer::with_capacity(0)); + res.send_ok_with_buffer(Buffer::with_capacity(0, 512)); let reply = brw.wait(&crucible_common::build_logger()).await; assert!(reply.buffer.is_some()); @@ -172,7 +172,7 @@ mod test { let (brw, res) = BlockReqWaiter::pair(); res.send_err_with_buffer( - Buffer::with_capacity(0), + Buffer::with_capacity(0, 512), CrucibleError::UpstairsInactive, ); diff --git a/upstairs/src/dummy_downstairs_tests.rs b/upstairs/src/dummy_downstairs_tests.rs index ff8284f3a..8e5528340 100644 --- a/upstairs/src/dummy_downstairs_tests.rs +++ b/upstairs/src/dummy_downstairs_tests.rs @@ -655,7 +655,7 @@ pub(crate) mod protocol_test { // We must tokio::spawn here because `read` will wait for the // response to come back before returning tokio::spawn(async move { - let mut buffer = Buffer::new(512); + let mut buffer = Buffer::new(1, 512); harness .guest .read(Block::new_512(0), &mut buffer) @@ -709,7 +709,7 @@ pub(crate) mod protocol_test { let harness = harness.clone(); tokio::spawn(async move { - let mut buffer = Buffer::new(512); + let mut buffer = Buffer::new(1, 512); harness .guest .read(Block::new_512(0), &mut buffer) @@ -867,7 +867,7 @@ pub(crate) mod protocol_test { // We must tokio::spawn here because `read` will wait for the // response to come back before returning tokio::spawn(async move { - let mut buffer = Buffer::new(512); + let mut buffer = Buffer::new(1, 512); harness .guest .read(Block::new_512(0), &mut buffer) @@ -951,7 +951,7 @@ pub(crate) mod protocol_test { // We must tokio::spawn here because `read` will wait for the // response to come back before returning tokio::spawn(async move { - let mut buffer = Buffer::new(512); + let mut buffer = Buffer::new(1, 512); harness .guest .read(Block::new_512(0), &mut buffer) @@ -1255,7 +1255,7 @@ pub(crate) mod protocol_test { { let harness = harness.clone(); tokio::spawn(async move { - let mut buffer = Buffer::new(512); + let mut buffer = Buffer::new(1, 512); harness .guest .read( @@ -1936,7 +1936,7 @@ pub(crate) mod protocol_test { // We must tokio::spawn here because `read` will wait for the // response to come back before returning tokio::spawn(async move { - let mut buffer = Buffer::new(512); + let mut buffer = Buffer::new(1, 512); harness .guest .read(Block::new_512(0), &mut buffer) @@ -1990,7 +1990,7 @@ pub(crate) mod protocol_test { // We must tokio::spawn here because `read` will wait for the // response to come back before returning tokio::spawn(async move { - let mut buffer = Buffer::new(512); + let mut buffer = Buffer::new(1, 512); harness .guest .read(Block::new_512(0), &mut buffer) @@ -2694,7 +2694,7 @@ pub(crate) mod protocol_test { // We must tokio::spawn here because `read` will wait for the // response to come back before returning tokio::spawn(async move { - let mut buffer = Buffer::new(512); + let mut buffer = Buffer::new(1, 512); harness .guest .read(Block::new_512(0), &mut buffer) @@ -2943,7 +2943,7 @@ pub(crate) mod protocol_test { // We must tokio::spawn here because `read` will wait for the // response to come back before returning tokio::spawn(async move { - let mut buffer = Buffer::new(512); + let mut buffer = Buffer::new(1, 512); harness .guest .read(Block::new_512(0), &mut buffer) @@ -2986,7 +2986,7 @@ pub(crate) mod protocol_test { // We must tokio::spawn here because `read` will wait for the // response to come back before returning tokio::spawn(async move { - let mut buffer = Buffer::new(512); + let mut buffer = Buffer::new(1, 512); harness .guest .read(Block::new_512(0), &mut buffer) diff --git a/upstairs/src/in_memory.rs b/upstairs/src/in_memory.rs index fd0ad6dc0..45b96520b 100644 --- a/upstairs/src/in_memory.rs +++ b/upstairs/src/in_memory.rs @@ -60,6 +60,7 @@ impl BlockIO for InMemoryBlockIO { offset: Block, data: &mut Buffer, ) -> Result<(), CrucibleError> { + self.check_data_size(data.len()).await?; let inner = self.inner.lock().await; let start = offset.value as usize * self.block_size as usize; @@ -79,6 +80,7 @@ impl BlockIO for InMemoryBlockIO { offset: Block, data: Bytes, ) -> Result<(), CrucibleError> { + self.check_data_size(data.len()).await?; let mut inner = self.inner.lock().await; let start = offset.value as usize * self.block_size as usize; @@ -96,6 +98,7 @@ impl BlockIO for InMemoryBlockIO { offset: Block, data: Bytes, ) -> Result<(), CrucibleError> { + self.check_data_size(data.len()).await?; let mut inner = self.inner.lock().await; let start = offset.value as usize * self.block_size as usize; diff --git a/upstairs/src/lib.rs b/upstairs/src/lib.rs index b1fdc1b3d..c128e7064 100644 --- a/upstairs/src/lib.rs +++ b/upstairs/src/lib.rs @@ -196,6 +196,18 @@ pub trait BlockIO: Sync { self.activate().await } + + /// Checks that the data length is a multiple of block size + /// + /// Returns block size on success, since we have to look it up anyways. + async fn check_data_size(&self, len: usize) -> Result { + let block_size = self.get_block_size().await?; + if len as u64 % block_size == 0 { + Ok(block_size) + } else { + Err(CrucibleError::DataLenUnaligned) + } + } } pub type CrucibleBlockIOFuture<'a> = Pin< @@ -1471,40 +1483,41 @@ impl fmt::Display for AckStatus { #[must_use] #[derive(Debug, PartialEq, Default)] pub struct Buffer { + block_size: usize, data: Vec, owned: Vec, } impl Buffer { - pub fn from_vec(data: Vec) -> Buffer { - let len = data.len(); + pub fn new(block_count: usize, block_size: usize) -> Buffer { + let len = block_count * block_size; Buffer { - data, + block_size, + data: vec![0; len], owned: vec![false; len], } } - pub fn new(len: usize) -> Buffer { + /// Builds a new buffer that repeats the given value + pub fn repeat(v: u8, block_count: usize, block_size: usize) -> Self { + let len = block_count * block_size; Buffer { - data: vec![0; len], + block_size, + data: vec![v; len], owned: vec![false; len], } } - pub fn with_capacity(capacity: usize) -> Buffer { - let data = Vec::with_capacity(capacity); - let owned = Vec::with_capacity(capacity); + pub fn with_capacity(block_count: usize, block_size: usize) -> Buffer { + let len = block_count * block_size; + let data = Vec::with_capacity(len); + let owned = Vec::with_capacity(len); - Buffer { data, owned } - } - - pub fn from_slice(buf: &[u8]) -> Buffer { - let mut vec = Vec::::with_capacity(buf.len()); - for item in buf { - vec.push(*item); + Buffer { + block_size, + data, + owned, } - - Buffer::from_vec(vec) } /// Extract the underlying `Vec` bearing buffered data. @@ -1580,19 +1593,21 @@ impl Buffer { } } - buffer.reset(0); + buffer.reset(0, self.block_size); } pub fn owned_ref(&self) -> &[bool] { &self.owned } - pub fn reset(&mut self, len: usize) { + pub fn reset(&mut self, block_count: usize, block_size: usize) { self.data.clear(); self.owned.clear(); + let len = block_count * block_size; self.data.resize(len, 0u8); self.owned.resize(len, false); + self.block_size = block_size; } } @@ -1607,7 +1622,7 @@ impl std::ops::Deref for Buffer { #[test] fn test_buffer_sane() { const BLOCK_SIZE: usize = 512; - let mut data = Buffer::new(1024); + let mut data = Buffer::new(2, BLOCK_SIZE); data.write(0, &[99u8; BLOCK_SIZE]); @@ -1621,21 +1636,21 @@ fn test_buffer_sane() { #[test] fn test_buffer_len() { const READ_SIZE: usize = 512; - let data = Buffer::from_slice(&[0x99; READ_SIZE]); + let data = Buffer::repeat(0x99, 1, READ_SIZE); assert_eq!(data.len(), READ_SIZE); } #[test] fn test_buffer_len_over_block_size() { - const READ_SIZE: usize = 600; - let data = Buffer::from_slice(&[0x99; READ_SIZE]); + const READ_SIZE: usize = 1024; + let data = Buffer::repeat(0x99, 2, 512); assert_eq!(data.len(), READ_SIZE); } #[test] fn test_buffer_writes() { const READ_SIZE: usize = 512; - let mut data = Buffer::new(READ_SIZE); + let mut data = Buffer::new(1, READ_SIZE); assert_eq!(&data[..], &vec![0u8; 512]); @@ -1656,16 +1671,16 @@ fn test_buffer_writes() { #[test] fn test_buffer_eats() { const READ_SIZE: usize = 512; - let mut data = Buffer::new(READ_SIZE); + let mut data = Buffer::new(1, READ_SIZE); assert_eq!(&data[..], &vec![0u8; 512]); - let mut buffer = Buffer::new(READ_SIZE); + let mut buffer = Buffer::new(1, READ_SIZE); buffer.eat(0, &mut data); assert_eq!(&buffer[..], &vec![0u8; 512]); - let mut data = Buffer::new(READ_SIZE); + let mut data = Buffer::new(1, READ_SIZE); data.write(64, &[1u8; 64]); buffer.eat(0, &mut data); @@ -1673,7 +1688,7 @@ fn test_buffer_eats() { assert_eq!(&buffer[64..128], &vec![1u8; 64]); assert_eq!(&buffer[128..], &vec![0u8; 512 - 64 - 64]); - let mut data = Buffer::new(READ_SIZE); + let mut data = Buffer::new(1, READ_SIZE); data.write(128, &[7u8; 128]); buffer.eat(0, &mut data); @@ -1802,25 +1817,25 @@ async fn test_return_iops() { let op = BlockOp::Read { offset: Block::new_512(1), - data: Buffer::new(1), + data: Buffer::new(1, 512), }; assert_eq!(op.iops(IOP_SZ).unwrap(), 1); let op = BlockOp::Read { offset: Block::new_512(1), - data: Buffer::new(8000), + data: Buffer::new(8, 512), // 4096 bytes }; assert_eq!(op.iops(IOP_SZ).unwrap(), 1); let op = BlockOp::Read { offset: Block::new_512(1), - data: Buffer::new(16000), + data: Buffer::new(31, 512), // 15872 bytes < 16000 }; assert_eq!(op.iops(IOP_SZ).unwrap(), 1); let op = BlockOp::Read { offset: Block::new_512(1), - data: Buffer::new(16001), + data: Buffer::new(32, 512), // 16384 bytes > 16000 }; assert_eq!(op.iops(IOP_SZ).unwrap(), 2); } @@ -2549,11 +2564,7 @@ impl BlockIO for Guest { offset: Block, data: &mut Buffer, ) -> Result<(), CrucibleError> { - let bs = self.get_block_size().await?; - - if (data.len() % bs as usize) != 0 { - crucible_bail!(DataLenUnaligned); - } + let bs = self.check_data_size(data.len()).await?; if offset.block_size_in_bytes() as u64 != bs { crucible_bail!(BlockSizeMismatch); @@ -2583,11 +2594,7 @@ impl BlockIO for Guest { offset: Block, data: Bytes, ) -> Result<(), CrucibleError> { - let bs = self.get_block_size().await?; - - if (data.len() % bs as usize) != 0 { - crucible_bail!(DataLenUnaligned); - } + let bs = self.check_data_size(data.len()).await?; if offset.block_size_in_bytes() as u64 != bs { crucible_bail!(BlockSizeMismatch); @@ -2610,11 +2617,7 @@ impl BlockIO for Guest { offset: Block, data: Bytes, ) -> Result<(), CrucibleError> { - let bs = self.get_block_size().await?; - - if (data.len() % bs as usize) != 0 { - crucible_bail!(DataLenUnaligned); - } + let bs = self.check_data_size(data.len()).await?; if offset.block_size_in_bytes() as u64 != bs { crucible_bail!(BlockSizeMismatch); diff --git a/upstairs/src/live_repair.rs b/upstairs/src/live_repair.rs index 28a4374b3..5f2989ed5 100644 --- a/upstairs/src/live_repair.rs +++ b/upstairs/src/live_repair.rs @@ -1172,7 +1172,7 @@ pub mod repair_test { ) .await; - up.submit_dummy_read(Block::new_512(0), Buffer::new(512)) + up.submit_dummy_read(Block::new_512(0), Buffer::new(1, 512)) .await; // WriteUnwritten @@ -1210,7 +1210,7 @@ pub mod repair_test { ) .await; - up.submit_dummy_read(Block::new_512(0), Buffer::new(512)) + up.submit_dummy_read(Block::new_512(0), Buffer::new(1, 512)) .await; // WriteUnwritten @@ -1244,7 +1244,7 @@ pub mod repair_test { ) .await; - up.submit_dummy_read(Block::new_512(3), Buffer::new(512)) + up.submit_dummy_read(Block::new_512(3), Buffer::new(1, 512)) .await; // WriteUnwritten @@ -1329,7 +1329,7 @@ pub mod repair_test { ) .await; - up.submit_dummy_read(Block::new_512(0), Buffer::new(512 * 9)) + up.submit_dummy_read(Block::new_512(0), Buffer::new(9, 512)) .await; // WriteUnwritten @@ -1392,7 +1392,7 @@ pub mod repair_test { finish_live_repair(&mut up, 1000).await; // Our default extent size is 3, so 9 blocks will span 3 extents - up.submit_dummy_read(Block::new_512(0), Buffer::new(512 * 9)) + up.submit_dummy_read(Block::new_512(0), Buffer::new(9, 512)) .await; tokio::time::sleep(std::time::Duration::from_secs(1)).await; diff --git a/upstairs/src/pseudo_file.rs b/upstairs/src/pseudo_file.rs index 7d4de9562..c98f40d2c 100644 --- a/upstairs/src/pseudo_file.rs +++ b/upstairs/src/pseudo_file.rs @@ -38,7 +38,8 @@ impl IOSpan { block_size, phase: offset % block_size, buffer: Buffer::new( - affected_block_numbers.len() * block_size as usize, + affected_block_numbers.len(), + block_size as usize, ), affected_block_numbers, } diff --git a/upstairs/src/test.rs b/upstairs/src/test.rs index 5062ce008..578d1e5e5 100644 --- a/upstairs/src/test.rs +++ b/upstairs/src/test.rs @@ -734,19 +734,19 @@ pub(crate) mod up_test { let _ = guest .send(BlockOp::Read { offset: Block::new_512(0), - data: Buffer::new(1), + data: Buffer::new(1, 512), }) .await; let _ = guest .send(BlockOp::Read { offset: Block::new_512(0), - data: Buffer::new(8000), + data: Buffer::new(8, 512), }) .await; let _ = guest .send(BlockOp::Read { offset: Block::new_512(0), - data: Buffer::new(16000), + data: Buffer::new(32, 512), }) .await; @@ -775,19 +775,19 @@ pub(crate) mod up_test { let _ = guest .send(BlockOp::Read { offset: Block::new_512(0), - data: Buffer::new(1), + data: Buffer::new(1, 512), }) .await; let _ = guest .send(BlockOp::Read { offset: Block::new_512(0), - data: Buffer::new(8000), + data: Buffer::new(8, 512), }) .await; let _ = guest .send(BlockOp::Read { offset: Block::new_512(0), - data: Buffer::new(16000), + data: Buffer::new(31, 512), }) .await; @@ -863,19 +863,19 @@ pub(crate) mod up_test { let _ = guest .send(BlockOp::Read { offset: Block::new_512(0), - data: Buffer::new(1024 * 1024 / 2), + data: Buffer::new(1024, 512), // 512 KiB }) .await; let _ = guest .send(BlockOp::Read { offset: Block::new_512(0), - data: Buffer::new(1024 * 1024 / 2), + data: Buffer::new(1024, 512), }) .await; let _ = guest .send(BlockOp::Read { offset: Block::new_512(0), - data: Buffer::new(1024 * 1024 / 2), + data: Buffer::new(1024, 512), }) .await; @@ -956,13 +956,13 @@ pub(crate) mod up_test { let _ = guest .send(BlockOp::Read { offset: Block::new_512(0), - data: Buffer::new(7000 * 1024), + data: Buffer::new(14000, 512), // 7000 KiB }) .await; let _ = guest .send(BlockOp::Read { offset: Block::new_512(0), - data: Buffer::new(7000 * 1024), + data: Buffer::new(14000, 512), // 7000 KiB }) .await; @@ -991,7 +991,7 @@ pub(crate) mod up_test { let _ = guest .send(BlockOp::Read { offset: Block::new_512(0), - data: Buffer::new(1024), + data: Buffer::new(2, 512), }) .await; assert_consumed!(&guest); @@ -1000,7 +1000,7 @@ pub(crate) mod up_test { let _ = guest .send(BlockOp::Read { offset: Block::new_512(0), - data: Buffer::new(1024), + data: Buffer::new(2, 512), }) .await; assert_none_consumed!(&guest); @@ -1031,6 +1031,9 @@ pub(crate) mod up_test { let optimal_io_size: usize = 6400 * 1024 / 500; + // Round down to the nearest size in blocks + let optimal_io_size = (optimal_io_size / 512) * 512; + // Make sure this is <= an IOP size assert!(optimal_io_size <= 16384); @@ -1039,11 +1042,12 @@ pub(crate) mod up_test { for i in 0..500 { assert_eq!(*guest.iop_tokens.lock().unwrap(), i); assert_eq!(*guest.bw_tokens.lock().unwrap(), i * optimal_io_size); + assert_eq!(optimal_io_size % 512, 0); let _ = guest .send(BlockOp::Read { offset: Block::new_512(0), - data: Buffer::new(optimal_io_size), + data: Buffer::new(optimal_io_size / 512, 512), }) .await; @@ -1065,18 +1069,18 @@ pub(crate) mod up_test { guest.set_bw_limit(1024 * 1024); // 1 KiB assert_none_consumed!(&guest); - // Sending an IO of 10 KiB is larger than the bandwidth limit and + // Sending an IO of 10 MiB is larger than the bandwidth limit and // represents 20 IOPs, larger than the IOP limit. let _ = guest .send(BlockOp::Read { offset: Block::new_512(0), - data: Buffer::new(10 * 1024 * 1024), + data: Buffer::new(20480, 512), // 10 MiB }) .await; let _ = guest .send(BlockOp::Read { offset: Block::new_512(0), - data: Buffer::new(0), + data: Buffer::new(0, 512), }) .await; diff --git a/upstairs/src/upstairs.rs b/upstairs/src/upstairs.rs index cca97f767..e42d2a4c6 100644 --- a/upstairs/src/upstairs.rs +++ b/upstairs/src/upstairs.rs @@ -2577,7 +2577,7 @@ pub(crate) mod test { // op 1 upstairs - .submit_dummy_read(Block::new_512(0), Buffer::new(512)) + .submit_dummy_read(Block::new_512(0), Buffer::new(1, 512)) .await; let jobs = upstairs.downstairs.get_all_jobs(); @@ -2615,7 +2615,7 @@ pub(crate) mod test { // op 3 upstairs - .submit_dummy_read(Block::new_512(0), Buffer::new(512 * 2)) + .submit_dummy_read(Block::new_512(0), Buffer::new(2, 512)) .await; let jobs = upstairs.downstairs.get_all_jobs(); @@ -2648,12 +2648,12 @@ pub(crate) mod test { // op 0 upstairs - .submit_dummy_read(Block::new_512(0), Buffer::new(512)) + .submit_dummy_read(Block::new_512(0), Buffer::new(1, 512)) .await; // op 1 upstairs - .submit_dummy_read(Block::new_512(0), Buffer::new(512)) + .submit_dummy_read(Block::new_512(0), Buffer::new(1, 512)) .await; let jobs = upstairs.downstairs.get_all_jobs(); @@ -2688,12 +2688,12 @@ pub(crate) mod test { // op 1 upstairs - .submit_dummy_read(Block::new_512(0), Buffer::new(512)) + .submit_dummy_read(Block::new_512(0), Buffer::new(1, 512)) .await; // op 2 upstairs - .submit_dummy_read(Block::new_512(0), Buffer::new(512)) + .submit_dummy_read(Block::new_512(0), Buffer::new(1, 512)) .await; let jobs = upstairs.downstairs.get_all_jobs(); @@ -2732,7 +2732,7 @@ pub(crate) mod test { // op 2 upstairs - .submit_dummy_read(Block::new_512(0), Buffer::new(512 * 2)) + .submit_dummy_read(Block::new_512(0), Buffer::new(2, 512)) .await; let jobs = upstairs.downstairs.get_all_jobs(); @@ -2859,7 +2859,7 @@ pub(crate) mod test { // op 0 upstairs - .submit_dummy_read(Block::new_512(0), Buffer::new(512)) + .submit_dummy_read(Block::new_512(0), Buffer::new(1, 512)) .await; // op 1 @@ -2894,7 +2894,7 @@ pub(crate) mod test { // op 0 upstairs - .submit_dummy_read(Block::new_512(0), Buffer::new(512)) + .submit_dummy_read(Block::new_512(0), Buffer::new(1, 512)) .await; // op 1 @@ -2908,7 +2908,7 @@ pub(crate) mod test { // op 2 upstairs - .submit_dummy_read(Block::new_512(0), Buffer::new(512)) + .submit_dummy_read(Block::new_512(0), Buffer::new(1, 512)) .await; let jobs = upstairs.downstairs.get_all_jobs(); @@ -2938,7 +2938,7 @@ pub(crate) mod test { // op 0 upstairs - .submit_dummy_read(Block::new_512(0), Buffer::new(512)) + .submit_dummy_read(Block::new_512(0), Buffer::new(1, 512)) .await; // op 1 @@ -2952,7 +2952,7 @@ pub(crate) mod test { // op 2 upstairs - .submit_dummy_read(Block::new_512(1), Buffer::new(512 * 2)) + .submit_dummy_read(Block::new_512(1), Buffer::new(2, 512)) .await; // op 3 @@ -2966,7 +2966,7 @@ pub(crate) mod test { // op 4 upstairs - .submit_dummy_read(Block::new_512(3), Buffer::new(512 * 2)) + .submit_dummy_read(Block::new_512(3), Buffer::new(2, 512)) .await; // op 5 @@ -3227,7 +3227,7 @@ pub(crate) mod test { // op 4 upstairs - .submit_dummy_read(Block::new_512(99), Buffer::new(512)) + .submit_dummy_read(Block::new_512(99), Buffer::new(1, 512)) .await; let ds = &upstairs.downstairs; @@ -3324,7 +3324,7 @@ pub(crate) mod test { // op 0 upstairs - .submit_dummy_read(Block::new_512(95), Buffer::new(512 * 2)) + .submit_dummy_read(Block::new_512(95), Buffer::new(2, 512)) .await; // op 1 @@ -3685,7 +3685,7 @@ pub(crate) mod test { up.force_active().unwrap(); set_all_active(&mut up.downstairs); - let data = Buffer::new(512); + let data = Buffer::new(1, 512); let offset = Block::new_512(7); let (_tx, res) = BlockReqWaiter::pair(); up.apply(UpstairsAction::Guest(BlockReq { @@ -3745,7 +3745,7 @@ pub(crate) mod test { set_all_active(&mut up.downstairs); let blocks = 16384 / 512; - let data = Buffer::new(512 * blocks); + let data = Buffer::new(blocks, 512); let offset = Block::new_512(7); let (_tx, res) = BlockReqWaiter::pair(); up.apply(UpstairsAction::Guest(BlockReq { @@ -3812,7 +3812,7 @@ pub(crate) mod test { set_all_active(&mut up.downstairs); let blocks = 16384 / 512; - let data = Buffer::new(512 * blocks); + let data = Buffer::new(blocks, 512); let offset = Block::new_512(7); let (_tx, res) = BlockReqWaiter::pair(); up.apply(UpstairsAction::Guest(BlockReq { @@ -3901,7 +3901,7 @@ pub(crate) mod test { up.force_active().unwrap(); set_all_active(&mut up.downstairs); - let data = Buffer::new(512); + let data = Buffer::new(1, 512); let offset = Block::new_512(7); let (_tx, res) = BlockReqWaiter::pair(); up.apply(UpstairsAction::Guest(BlockReq { @@ -3980,7 +3980,7 @@ pub(crate) mod test { up.force_active().unwrap(); set_all_active(&mut up.downstairs); - let data = Buffer::new(512); + let data = Buffer::new(1, 512); let offset = Block::new_512(7); let (_tx, res) = BlockReqWaiter::pair(); up.apply(UpstairsAction::Guest(BlockReq { @@ -4048,7 +4048,7 @@ pub(crate) mod test { up.force_active().unwrap(); set_all_active(&mut up.downstairs); - let data = Buffer::new(512); + let data = Buffer::new(1, 512); let offset = Block::new_512(7); let (_tx, res) = BlockReqWaiter::pair(); up.apply(UpstairsAction::Guest(BlockReq { @@ -4101,7 +4101,7 @@ pub(crate) mod test { up.force_active().unwrap(); set_all_active(&mut up.downstairs); - let data = Buffer::new(512); + let data = Buffer::new(1, 512); let offset = Block::new_512(7); let (_tx, res) = BlockReqWaiter::pair(); up.apply(UpstairsAction::Guest(BlockReq { @@ -4179,7 +4179,7 @@ pub(crate) mod test { up.force_active().unwrap(); set_all_active(&mut up.downstairs); - let data = Buffer::new(512); + let data = Buffer::new(1, 512); let offset = Block::new_512(7); let (_tx, res) = BlockReqWaiter::pair(); up.apply(UpstairsAction::Guest(BlockReq { @@ -4259,7 +4259,7 @@ pub(crate) mod test { up.force_active().unwrap(); set_all_active(&mut up.downstairs); - let data = Buffer::new(512); + let data = Buffer::new(1, 512); let offset = Block::new_512(7); let (_tx, res) = BlockReqWaiter::pair(); up.apply(UpstairsAction::Guest(BlockReq { @@ -4336,7 +4336,7 @@ pub(crate) mod test { up.force_active().unwrap(); set_all_active(&mut up.downstairs); - let data = Buffer::new(512); + let data = Buffer::new(1, 512); let offset = Block::new_512(7); let (_tx, res) = BlockReqWaiter::pair(); up.apply(UpstairsAction::Guest(BlockReq { @@ -4406,7 +4406,7 @@ pub(crate) mod test { up.force_active().unwrap(); set_all_active(&mut up.downstairs); - let data = Buffer::new(512); + let data = Buffer::new(1, 512); let offset = Block::new_512(7); let (_tx, res) = BlockReqWaiter::pair(); up.apply(UpstairsAction::Guest(BlockReq { diff --git a/upstairs/src/volume.rs b/upstairs/src/volume.rs index d861a4d15..aa1e4f5af 100644 --- a/upstairs/src/volume.rs +++ b/upstairs/src/volume.rs @@ -382,7 +382,7 @@ impl Volume { // on. If that initial connection fails, we can retry. let mut retry_count = 0; - let mut buffer = Buffer::new(block_count * bs); + let mut buffer = Buffer::new(block_count, bs); loop { match read_only_parent.read(block, &mut buffer).await { @@ -487,11 +487,7 @@ impl Volume { return Ok(()); } - let bs = self.get_block_size().await?; - - if (data.len() % bs as usize) != 0 { - crucible_bail!(DataLenUnaligned); - } + self.check_data_size(data.len()).await?; let affected_sub_volumes = self.sub_volumes_for_lba_range( offset.value, @@ -648,11 +644,7 @@ impl BlockIO for Volume { } } - let bs = self.get_block_size().await?; - - if (data.len() % bs as usize) != 0 { - crucible_bail!(DataLenUnaligned); - } + let bs = self.check_data_size(data.len()).await? as usize; let affected_sub_volumes = self.sub_volumes_for_lba_range( offset.value, @@ -665,7 +657,7 @@ impl BlockIO for Volume { // TODO parallel dispatch! let mut data_index = 0; - let mut read_buffer = Buffer::with_capacity(data.len()); + let mut read_buffer = Buffer::with_capacity(data.len() / bs, bs); for (coverage, sub_volume) in affected_sub_volumes { // When performing a read, check the parent coverage: if it's @@ -680,10 +672,10 @@ impl BlockIO for Volume { if let Some(parent_coverage) = parent_coverage { let parent_offset = Block::new(coverage.start, offset.shift); - let sub_sz = self.block_size as usize - * (parent_coverage.end - parent_coverage.start) as usize; - - read_buffer.reset(sub_sz); + read_buffer.reset( + (parent_coverage.end - parent_coverage.start) as usize, + bs, + ); self.read_only_parent .as_ref() .unwrap() @@ -697,15 +689,14 @@ impl BlockIO for Volume { sub_volume.compute_sub_volume_lba(coverage.start), offset.shift, ); - let sz = (coverage.end - coverage.start) as usize - * self.block_size as usize; - read_buffer.reset(sz); + read_buffer.reset((coverage.end - coverage.start) as usize, bs); sub_volume.read(sub_offset, &mut read_buffer).await?; data.eat(data_index, &mut read_buffer); - data_index += sz; + data_index += (coverage.end - coverage.start) as usize + * self.block_size as usize; } assert_eq!(data.len(), data_index); @@ -1761,7 +1752,7 @@ mod test { let disk = InMemoryBlockIO::new(Uuid::new_v4(), BLOCK_SIZE, 4096); // Initial read should come back all zeroes - let mut buffer = Buffer::new(4096); + let mut buffer = Buffer::new(8, BLOCK_SIZE as usize); disk.read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; assert_eq!(buffer.into_vec(), vec![0; 4096]); @@ -1782,7 +1773,7 @@ mod test { .await?; // Read and verify the data is from the first write - let mut buffer = Buffer::new(4096); + let mut buffer = Buffer::new(8, BLOCK_SIZE as usize); disk.read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -1799,7 +1790,7 @@ mod test { .await?; // Read and verify - let mut buffer = Buffer::new(4096); + let mut buffer = Buffer::new(8, BLOCK_SIZE as usize); disk.read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -1823,7 +1814,7 @@ mod test { .await?; // Read and verify - let mut buffer = Buffer::new(4096); + let mut buffer = Buffer::new(8, BLOCK_SIZE as usize); disk.read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -1864,7 +1855,7 @@ mod test { // The first 2048b of the initial read should come only from the parent // (aka read_only_parent_init_value), and the second 2048b should come // from the subvolume(s) (aka be uninitialized). - let mut buffer = Buffer::new(4096); + let mut buffer = Buffer::new(8, 512); volume .read(Block::new(0, block_size.trailing_zeros()), &mut buffer) .await?; @@ -1888,7 +1879,7 @@ mod test { .await?; // Read whole volume and verify - let mut buffer = Buffer::new(4096); + let mut buffer = Buffer::new(8, 512); volume .read(Block::new(0, block_size.trailing_zeros()), &mut buffer) .await?; @@ -1913,7 +1904,7 @@ mod test { // Make sure the parent data hasn't changed! { - let mut buffer = Buffer::new(2048); + let mut buffer = Buffer::new(4, 512); parent .read(Block::new(0, block_size.trailing_zeros()), &mut buffer) .await?; @@ -1925,7 +1916,7 @@ mod test { } // Read whole volume and verify - let mut buffer = Buffer::new(4096); + let mut buffer = Buffer::new(8, 512); volume .read(Block::new(0, block_size.trailing_zeros()), &mut buffer) .await?; @@ -1951,7 +1942,7 @@ mod test { // Make sure the parent data hasn't changed! { - let mut buffer = Buffer::new(2048); + let mut buffer = Buffer::new(4, 512); parent .read(Block::new(0, block_size.trailing_zeros()), &mut buffer) .await?; @@ -1963,7 +1954,7 @@ mod test { } // Read whole volume and verify - let mut buffer = Buffer::new(4096); + let mut buffer = Buffer::new(8, 512); volume .read(Block::new(0, block_size.trailing_zeros()), &mut buffer) .await?; @@ -1988,7 +1979,7 @@ mod test { .await?; // Read whole volume and verify - let mut buffer = Buffer::new(4096); + let mut buffer = Buffer::new(8, 512); volume .read(Block::new(0, block_size.trailing_zeros()), &mut buffer) .await?; @@ -2005,7 +1996,7 @@ mod test { volume.read_only_parent = None; // Read whole volume and verify - let mut buffer = Buffer::new(4096); + let mut buffer = Buffer::new(8, 512); volume .read(Block::new(0, block_size.trailing_zeros()), &mut buffer) .await?; @@ -2026,7 +2017,7 @@ mod test { ) .await?; - let mut buffer = Buffer::new(4096); + let mut buffer = Buffer::new(8, 512); volume .read(Block::new(0, block_size.trailing_zeros()), &mut buffer) .await?; @@ -2087,7 +2078,7 @@ mod test { // Ownership starts off false - let mut buffer = Buffer::new(1024); + let mut buffer = Buffer::new(2, BLOCK_SIZE as usize); parent .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -2105,7 +2096,7 @@ mod test { // Ownership is returned by the downstairs - let mut buffer = Buffer::new(1024); + let mut buffer = Buffer::new(2, BLOCK_SIZE as usize); parent .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -2131,7 +2122,7 @@ mod test { // So is it? - let mut buffer = Buffer::new(1024); + let mut buffer = Buffer::new(2, BLOCK_SIZE as usize); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -2369,7 +2360,7 @@ mod test { assert_eq!(volume.total_size().await?, 2048); // Read volume and verify contents - let mut buffer = Buffer::new(2048); + let mut buffer = Buffer::new(4, BLOCK_SIZE as usize); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -2482,7 +2473,7 @@ mod test { volume.add_subvolume(overlay.clone()).await?; volume.add_read_only_parent(parent.clone()).await?; - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -2496,7 +2487,7 @@ mod test { ) .await?; - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -2510,7 +2501,7 @@ mod test { volume.add_read_only_parent(parent).await?; volume.add_subvolume(overlay).await?; - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -2538,7 +2529,7 @@ mod test { .await?; // Read parent, verify contents - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); parent .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -2572,7 +2563,7 @@ mod test { // } // Read whole volume, verify contents - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -2588,7 +2579,7 @@ mod test { .await?; // Read whole volume, verify new contents - let mut buffer = Buffer::new(BLOCK_SIZE * 10); + let mut buffer = Buffer::new(10, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await?; @@ -2621,7 +2612,7 @@ mod test { }; let volume = Volume::construct(request, None, csl()).await.unwrap(); - let mut buffer = Buffer::new(BLOCK_SIZE); + let mut buffer = Buffer::new(1, BLOCK_SIZE); volume .read(Block::new(0, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await @@ -2629,7 +2620,7 @@ mod test { assert_eq!(vec![0x0; BLOCK_SIZE], buffer.into_vec()); - let mut buffer = Buffer::new(BLOCK_SIZE); + let mut buffer = Buffer::new(1, BLOCK_SIZE); volume .read(Block::new(1, BLOCK_SIZE.trailing_zeros()), &mut buffer) .await @@ -2660,7 +2651,7 @@ mod test { .await?; // Read back parent, verify 1s - let mut buffer = Buffer::new(block_size * 5); + let mut buffer = Buffer::new(5, block_size); parent .read(Block::new(0, block_size.trailing_zeros()), &mut buffer) .await?; @@ -2681,7 +2672,7 @@ mod test { assert_eq!(volume.total_size().await?, block_size as u64 * 10); // Verify volume contents in one read - let mut buffer = Buffer::new(block_size * 10); + let mut buffer = Buffer::new(10, block_size); volume .read(Block::new(0, block_size.trailing_zeros()), &mut buffer) .await?; @@ -2699,7 +2690,7 @@ mod test { .await?; // Verify volume contents in one read - let mut buffer = Buffer::new(block_size * 10); + let mut buffer = Buffer::new(10, block_size); volume .read(Block::new(0, block_size.trailing_zeros()), &mut buffer) .await?; @@ -3049,7 +3040,7 @@ mod test { let out_of_bounds = volume.total_size().await.unwrap() * BLOCK_SIZE; - let mut buffer = Buffer::new(BLOCK_SIZE as usize); + let mut buffer = Buffer::new(1, BLOCK_SIZE as usize); let res = volume .read( Block::new(