tags 989630 +pending thanks I finally had time to investigate this problem. It turns out the only time this bug manifests is when creating an file system smaller than (blocksize)**2 bytes (e.g., 16 megabytes when the is block size is 4k).
The bug was introduced almost ten years ago (September 2011), and apparently no one noticed until you did! Thanks for providing a repro, BTW; I had initially tried reproducing this with a file system size larger than 16MB, and I couldn't see the problem. But when I used your precise reproduction instructions, I finally figured out what was going on. The patch to fix this is attached below. - Ted commit 6568ba325e54a2ae1d2617c5175936c819ab4c8c Author: Theodore Ts'o <ty...@mit.edu> Date: Sun Jul 18 09:15:28 2021 -0400 mke2fs: only try discarding a single block to test if discard works Commit d2bfdc7ff15c ("Use punch hole as "discard" on regular files") added a test to see if the storage device actually supports discard. The intent was to try discarding the first block but since io_channel_discard() interprets the offset and count arguments in blocks, and not bytes, mke2fs was actually discarding the first 16 megabytes (when the block size is 4k). This is normally not a problem, since most file systems are larger than that, and requests to discard beyond the end of the block device are ignored. However, when creating a small file system as part of a image containing multiple partitions, the initial test discard can end up discarding data beyond the file system being created. Addresses-Debian-Bug: #989630 Reported-by: Josh Triplett <j...@joshtriplett.org> Fixes: d2bfdc7ff15c ("Use punch hole as "discard" on regular files") Signed-off-by: Theodore Ts'o <ty...@mit.edu> diff --git a/misc/mke2fs.c b/misc/mke2fs.c index 9fa6eaa7..5a35e9ef 100644 --- a/misc/mke2fs.c +++ b/misc/mke2fs.c @@ -2794,7 +2794,7 @@ static int mke2fs_discard_device(ext2_filsys fs) struct ext2fs_numeric_progress_struct progress; blk64_t blocks = ext2fs_blocks_count(fs->super); blk64_t count = DISCARD_STEP_MB; - blk64_t cur; + blk64_t cur = 0; int retval = 0; /* @@ -2802,10 +2802,9 @@ static int mke2fs_discard_device(ext2_filsys fs) * we do not print numeric progress resulting in failure * afterwards. */ - retval = io_channel_discard(fs->io, 0, fs->blocksize); + retval = io_channel_discard(fs->io, 0, 1); if (retval) return retval; - cur = fs->blocksize; count *= (1024 * 1024); count /= fs->blocksize;