mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 02:17:36 -04:00
netfs: Fix DIO write retry for filesystems without a ->prepare_write()
Fix netfs_unbuffered_write() so that it doesn't re-issue a write twice when the filesystem doesn't have a ->prepare_write(). The resetting of the iterator and the call to netfs_reissue_write() should just be removed as almost everything it does is done again when the loop it's in goes back to the top. It does, however, still need the IN_PROGRESS flag setting, so that (and the stat inc) are moved out of the if-statement. Further, the MADE_PROGRESS flags should be cleared and wreq->transferred should be updated, so fix those too. Reported-by: syzbot+3c74b1f0c372e98efc32@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=3c74b1f0c372e98efc32 Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260625140640.3116900-16-dhowells@redhat.com cc: Paulo Alcantara <pc@manguebit.org> cc: hongao <hongao@uniontech.com> cc: ChenXiaoSong <chenxiaosong@chenxiaosong.com> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
This commit is contained in:
committed by
Christian Brauner
parent
b6a713fd34
commit
64f04f9789
@@ -166,13 +166,16 @@ static int netfs_unbuffered_write(struct netfs_io_request *wreq)
|
||||
*/
|
||||
subreq->error = -EAGAIN;
|
||||
trace_netfs_sreq(subreq, netfs_sreq_trace_retry);
|
||||
if (subreq->transferred > 0)
|
||||
if (subreq->transferred > 0) {
|
||||
iov_iter_advance(&wreq->buffer.iter, subreq->transferred);
|
||||
wreq->transferred += subreq->transferred;
|
||||
}
|
||||
|
||||
if (stream->source == NETFS_UPLOAD_TO_SERVER &&
|
||||
wreq->netfs_ops->retry_request)
|
||||
wreq->netfs_ops->retry_request(wreq, stream);
|
||||
|
||||
__clear_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags);
|
||||
__clear_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags);
|
||||
__clear_bit(NETFS_SREQ_BOUNDARY, &subreq->flags);
|
||||
__clear_bit(NETFS_SREQ_FAILED, &subreq->flags);
|
||||
@@ -186,17 +189,10 @@ static int netfs_unbuffered_write(struct netfs_io_request *wreq)
|
||||
|
||||
netfs_get_subrequest(subreq, netfs_sreq_trace_get_resubmit);
|
||||
|
||||
if (stream->prepare_write) {
|
||||
if (stream->prepare_write)
|
||||
stream->prepare_write(subreq);
|
||||
__set_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags);
|
||||
netfs_stat(&netfs_n_wh_retry_write_subreq);
|
||||
} else {
|
||||
struct iov_iter source;
|
||||
|
||||
netfs_reset_iter(subreq);
|
||||
source = subreq->io_iter;
|
||||
netfs_reissue_write(stream, subreq, &source);
|
||||
}
|
||||
__set_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags);
|
||||
netfs_stat(&netfs_n_wh_retry_write_subreq);
|
||||
}
|
||||
|
||||
netfs_unbuffered_write_done(wreq);
|
||||
|
||||
Reference in New Issue
Block a user