A flush uploads the dirty pages without the handle lock, then commits the
entry under it. A write in between grows the entry's size, but its pages
are not in the committed chunks. Clearing dirtyMetadata then made the next
flush skip the commit, leaving a file with the new size and no chunk for
the write, which reads back as zeros.
Count page writes on the handle and clear dirtyMetadata only when none
landed since the flush started uploading.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* mount: guard append gaps over concurrent content merges
* mount: fence a writeback inode when its async publication is abandoned
A drain that gives up on a non-precondition error left the token clear, so a
reopened writeback handle could publish past the stored EOF.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* mount: fence a writeback inode when its async data flush fails
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* mount: fence the inode when its last handle drops uncommitted content
A synchronous release whose final flush fails destroys the handle's dirty
pages, while under writeback the kernel EOF already counts them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Chris Lu <chrislusf@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>