Skip to content

Commit 61ea6b3

Browse files
dhowellsSteve French
authored andcommitted
cifs: Fix setting of zero_point after DIO write
At the moment, at the end of a DIO write, cifs calls netfs_resize_file() to adjust the size of the file if it needs it. This will reduce the zero_point (the point above which we assume a read will just return zeros) if it's more than the new i_size, but won't increase it. With DIO writes, however, we definitely want to increase it as we have clobbered the local pagecache and then written some data that's not available locally. Fix cifs to make the zero_point above the end of a DIO or unbuffered write. This fixes corruption seen occasionally with the generic/708 xfs-test. In that case, the read-back of some of the written data is being short-circuited and replaced with zeroes. Fixes: 3ee1a1f ("cifs: Cut over to using netfslib") Cc: stable@vger.kernel.org Reported-by: Steve French <sfrench@samba.org> Signed-off-by: David Howells <dhowells@redhat.com> Reviewed-by: Paulo Alcantara (Red Hat) <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: Steve French <stfrench@microsoft.com>
1 parent d2c5eb5 commit 61ea6b3

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

fs/smb/client/file.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2358,13 +2358,18 @@ void cifs_write_subrequest_terminated(struct cifs_io_subrequest *wdata, ssize_t
23582358
bool was_async)
23592359
{
23602360
struct netfs_io_request *wreq = wdata->rreq;
2361-
loff_t new_server_eof;
2361+
struct netfs_inode *ictx = netfs_inode(wreq->inode);
2362+
loff_t wrend;
23622363

23632364
if (result > 0) {
2364-
new_server_eof = wdata->subreq.start + wdata->subreq.transferred + result;
2365-
2366-
if (new_server_eof > netfs_inode(wreq->inode)->remote_i_size)
2367-
netfs_resize_file(netfs_inode(wreq->inode), new_server_eof, true);
2365+
wrend = wdata->subreq.start + wdata->subreq.transferred + result;
2366+
2367+
if (wrend > ictx->zero_point &&
2368+
(wdata->rreq->origin == NETFS_UNBUFFERED_WRITE ||
2369+
wdata->rreq->origin == NETFS_DIO_WRITE))
2370+
ictx->zero_point = wrend;
2371+
if (wrend > ictx->remote_i_size)
2372+
netfs_resize_file(ictx, wrend, true);
23682373
}
23692374

23702375
netfs_write_subrequest_terminated(&wdata->subreq, result, was_async);

0 commit comments

Comments
 (0)