Repository navigation
Linux 6.17: fuse: extend i_size from a READ reply under DLM - #266
Closed
cryptosven76 wants to merge 1 commit into
Closed
cryptosven76 wants to merge 1 commit into
cryptosven76 wants to merge 1 commit into
Conversation
With DLM and the writeback cache, i_size is only this node's view of the file: each writer claims its own extension under fi->lock, and the server's size is applied only when a GETATTR reply happens to arrive. Another node's data can therefore sit past the local i_size in the page cache, read in by the read-modify-write READ of a partial page under a write grant. iomap treats those bytes as post-EOF. iomap_writeback_handle_eof() zeroes them in the folio before writeback, and a concurrent local extension of i_size can then let the zeros reach the server over the other node's data (RED-51747). Even when they are not sent, the zeroed tail stays in the clean, uptodate folio. A READ reply proves the file reaches at least pos + bytes returned: the server returns a short count past its EOF and zero-filled pages for holes inside it. Under DLM with the writeback cache, raise i_size to that end, monotonically under fi->lock, and bump attr_version as fuse_read_update_size() does so that an older GETATTR reply cannot pull it back down. Leave it alone while FUSE_I_SIZE_UNSTABLE marks a local truncate in progress. Signed-off-by: Sven Oehme <soehme@ddn.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Author
|
close in favor of #267 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Second change for RED-51747, complementary to #264. It is independent of #264 (same base) so each can be reviewed on its own.
Problem
Under DLM with the writeback cache, i_size is only this node's view. Writers claim their own extension under
fi->lock, and the server's size is applied only when a GETATTR reply happens to arrive. A partial EOF page can hold another node's bytes, read in by the read-modify-write READ under a write grant. iomap treats them as post-EOF:iomap_writeback_handle_eof()zeroes them in the folio before writeback. Linux 6.17: fuse: do not send the zeroed EOF folio tail in iomap writeback #264 stops those zeros from being sent, but they stay in the clean, uptodate folio.iomap_block_needs_zeroing()(pos >= i_size) can zero-fill instead of reading a partial block that holds another node's data.Change
A READ reply proves the file reaches at least
pos + res: redfsd returns a short count (nob=0for a page past its EOF) and zero-filled pages for holes inside the file. Infuse_do_readfolio(), underfc->dlm && fc->writeback_cache, raise i_size to that end:fi->lock;attr_versionlikefuse_read_update_size(), so an older in-flight GETATTR reply cannot shrink it back andtruncate_pagecache()the data;FUSE_I_SIZE_UNSTABLEmarks a local truncate or size-changing setattr in progress.With this, the read-modify-write read that pulls in another node's bytes also moves the local EOF past them, so iomap never zeroes them. #264 stays useful as a guard that writeback never sends bytes past the EOF it zeroed at.
Review points
attr_versionbump would then make that stale size win over a GETATTR that started before the read completed. Worth checking against the-truncatebranch.fuse_cache_write_iter(): it shrinks i_size only if it still equals that writer's claimed end. A read-raised size is treated as a concurrent extender and kept, which looks right. A read-raised size equal to exactly that end would be retracted, which is harmless but imprecise.fuse_readpages_end()) is not changed. The kernel does not read ahead past the local i_size, so the RMW andread_foliopaths throughfuse_do_readfolio()are the ones that matter.Testing
Compile-tested only: built as DKMS
20261016.readsize1against Ubuntu 6.17.0-42 with no warnings. It has not been run yet. The RED-51747 reproducer (red/red PR 29256) on tyan-h3-u24 can test it alone and together with #264.🤖 Generated with Claude Code