From 745d2add08185eeb7440d8e59c414f510674d09c Mon Sep 17 00:00:00 2001 From: Alexander Shirokov Date: Sun, 11 May 2025 13:10:27 +0200 Subject: [PATCH] shred: add 4K data alignment This commit allows aligning output data by 4K to better match GNU shred. The 4K block size is configured as a constant because it provides a widely used value in the simplest way. However, there is a chance that some systems may use a different value. So far, I haven't encountered anything other than 4K, I decided not to overcomplicate the approach for now. --- src/uu/shred/src/shred.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/uu/shred/src/shred.rs b/src/uu/shred/src/shred.rs index 3ad5d713f..a17756465 100644 --- a/src/uu/shred/src/shred.rs +++ b/src/uu/shred/src/shred.rs @@ -507,6 +507,11 @@ fn wipe_file( Ok(()) } +// Aligns data size up to the nearest multiple of block size +fn get_aligned_size(data_size: usize, block_size: usize) -> usize { + data_size.div_ceil(block_size) * block_size +} + fn do_pass( file: &mut File, pass_type: &PassType, @@ -525,10 +530,16 @@ fn do_pass( } // Now we might have some bytes left, so we write either that - // many bytes if exact is true, or BLOCK_SIZE bytes if not. + // many bytes if exact is true, or aligned by FS_BLOCK_SIZE bytes if not. let bytes_left = (file_size % BLOCK_SIZE as u64) as usize; if bytes_left > 0 { - let size = if exact { bytes_left } else { BLOCK_SIZE }; + let size = if exact { + bytes_left + } else { + // This alignment allows us to better match GNU shred's behavior. + const FS_BLOCK_SIZE: usize = 4096; + get_aligned_size(bytes_left, FS_BLOCK_SIZE) + }; let block = writer.bytes_for_pass(size); file.write_all(block)?; }