[PATCH v4 0/2] fuse: zero the partial EOF page when extending a file
Jimmy Zuber <[email protected]>
| Newsgroups | dev.linux.lists.fuse-devel,org.kernel.vger.linux-kernel,org.kernel.vger.linux-kselftest |
|---|---|
| Message-ID | <[email protected]> |
Extending a fuse file past a non-page-aligned EOF does not zero the tail of the old last page. When that page is cached and has been mmap-dirtied beyond the old EOF, the now in-bounds tail is served to later reads as stale data rather than zeros, which violates POSIX file-extension semantics. Some file systems get this zeroing automatically at writeback time (block_write_full_folio() / iomap_writeback_handle_eof() zero the tail of the folio straddling i_size). A non-writeback caching fuse file system uses neither path, so it has to zero the tail itself from the size-extending paths, like XFS (xfs_file_write_zero_eof()) and ext4 (ext4_block_zero_eof()) do. Patch 1 calls truncate_pagecache_range() over the newly-exposed range up front from the three paths that extend a file: buffered write, setattr, and fallocate. Patch 2 adds a self-contained raw /dev/fuse selftest covering each path. Tested by booting the patched kernel under User-Mode Linux and running the new selftest, and reproduced against libfuse's passthrough_ll example daemon. Changes since v3 [3]: - Drop the fuse_zero_partial_eof_folio() helper and call truncate_pagecache_range(inode, from, to - 1) from the three extend paths instead. Miklos pointed out the helper's folio_mkclean()/folio_mark_dirty() dance is only needed by file systems using buffer heads (as Jan noted), and that truncate_pagecache_range() already does the rest of the zeroing. The selftest is unchanged and still passes with patch 1 (and fails without it). Changes since v1 [1]: - Zero from the size-extending paths up front, keyed on the write starting beyond EOF, rather than after the fact from fuse_write_update_attr(), so a write that lands inside the old EOF folio is preserved. (v2 [2] carried this change but went out with malformed recipient headers; it was resent as v3 [3].) [1] https://lore.kernel.org/all/[email protected]/ [2] https://lore.kernel.org/all/[email protected]/ [3] https://lore.kernel.org/all/[email protected]/ Jimmy Zuber (2): fuse: zero the partial EOF page when extending a file selftests/fuse: test post-EOF page zeroing when a file is extended fs/fuse/dir.c | 3 + fs/fuse/file.c | 9 + .../selftests/filesystems/fuse/.gitignore | 1 + .../selftests/filesystems/fuse/Makefile | 3 + .../filesystems/fuse/write_extend_eof_test.c | 368 ++++++++++++++++++ 5 files changed, 384 insertions(+) create mode 100644 tools/testing/selftests/filesystems/fuse/write_extend_eof_test.c base-commit: 7d87a5a284bb34edb3f4e7e312ef403b3385a7b7 -- 2.50.1