Commit e00e99ba authored by David Howells's avatar David Howells Committed by Christian Brauner

netfs: Fix interaction of streaming writes with zero-point tracker

When a folio that is marked for streaming write (dirty, but not uptodate,
with partial content specified in the private data) is written back, the
folio is effectively switched to the blank state upon completion of the
write.  This means that if we want to read it in future, we need to reread
the whole folio.

However, if the folio is above the zero_point position, when it is read
back, it will just be cleared and the read skipped, leading to apparent
local corruption.

Fix this by increasing the zero_point to the end of the dirty data in the
folio when clearing the folio state after writeback.  This is analogous to
the folio having ->release_folio() called upon it.

This was causing the config.log generated by configuring a cpython tree on
a cifs share to get corrupted because the scripts involved were appending
text to the file in small pieces.

Fixes: 288ace2f ("netfs: New writeback implementation")
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Link: https://lore.kernel.org/r/563286.1724500613@warthog.procyon.org.uk
cc: Steve French <sfrench@samba.org>
cc: Paulo Alcantara <pc@manguebit.com>
cc: Jeff Layton <jlayton@kernel.org>
cc: linux-cifs@vger.kernel.org
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.kernel.org
Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parent 950b03d0
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
int netfs_folio_written_back(struct folio *folio) int netfs_folio_written_back(struct folio *folio)
{ {
enum netfs_folio_trace why = netfs_folio_trace_clear; enum netfs_folio_trace why = netfs_folio_trace_clear;
struct netfs_inode *ictx = netfs_inode(folio->mapping->host);
struct netfs_folio *finfo; struct netfs_folio *finfo;
struct netfs_group *group = NULL; struct netfs_group *group = NULL;
int gcount = 0; int gcount = 0;
...@@ -41,6 +42,12 @@ int netfs_folio_written_back(struct folio *folio) ...@@ -41,6 +42,12 @@ int netfs_folio_written_back(struct folio *folio)
/* Streaming writes cannot be redirtied whilst under writeback, /* Streaming writes cannot be redirtied whilst under writeback,
* so discard the streaming record. * so discard the streaming record.
*/ */
unsigned long long fend;
fend = folio_pos(folio) + finfo->dirty_offset + finfo->dirty_len;
if (fend > ictx->zero_point)
ictx->zero_point = fend;
folio_detach_private(folio); folio_detach_private(folio);
group = finfo->netfs_group; group = finfo->netfs_group;
gcount++; gcount++;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment