On Tue, Jul 27, 2021 at 06:51:54PM -0700, Eric Biggers wrote:
From: Eric Biggers ebiggers@google.com
Currently, non-overwrite DIO writes are fundamentally unsafe on f2fs as they require preallocating blocks, but f2fs doesn't support unwritten blocks and therefore has to preallocate the blocks as regular blocks. f2fs has no way to reliably roll back such preallocations, so as a result, f2fs will leak uninitialized blocks to users if a DIO write doesn't fully complete. This can be easily reproduced by issuing a DIO write that will fail due to misalignment, e.g.:
rm -f file truncate -s 1000000 file dd if=/dev/zero bs=999999 oflag=direct conv=notrunc of=file od -tx1 file # shows uninitialized disk blocks
Until a proper design for non-overwrite DIO writes on f2fs can be designed and implemented, remove support for them and make them fall back to buffered I/O. This is what other filesystems that don't support unwritten blocks, e.g. ext2, also do, at least for non-extending DIO writes. However, f2fs can't do extending DIO writes either, as f2fs appears to have no mechanism for guaranteeing that leftover allocated blocks past EOF will get truncated. (f2fs does have an orphan list, but it's only used for deleting inodes, not truncating them.)
This patch doesn't attempt to remove the F2FS_GET_BLOCK_{DIO,PRE_DIO} cases in f2fs_map_blocks(); that can be cleaned up later.
Fixes: bfad7c2d4033 ("f2fs: introduce a new direct_IO write path") Cc: stable@vger.kernel.org Signed-off-by: Eric Biggers ebiggers@google.com
Any opinion on this patch? This really needs to be fixed one way or another. Probably before the conversion to iomap, as this fix will need to be backported.
- Eric