[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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.