Unverified Commit cce18c26 authored by David Howells's avatar David Howells Committed by Christian Brauner
Browse files

netfs: Fix missing locking around retry adding new subreqs

Fix netfs_retry_read_subrequests() and netfs_retry_write_stream() to take
the appropriate lock when adding extra subrequests into
stream->subrequests.

Fixes: e2d46f2e ("netfs: Change the read result collector to only use one work item")
Fixes: 288ace2f ("netfs: New writeback implementation")
Closes: https://sashiko.dev/#/patchset/20260425125426.3855807-1-dhowells%40redhat.com


Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Link: https://patch.msgid.link/20260512123404.719402-3-dhowells@redhat.com


cc: Paulo Alcantara <pc@manguebit.org>
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.kernel.org
Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parent 6f0f7ac1
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -175,7 +175,9 @@ static void netfs_retry_read_subrequests(struct netfs_io_request *rreq)
			list_for_each_entry_safe_from(subreq, tmp,
						      &stream->subrequests, rreq_link) {
				trace_netfs_sreq(subreq, netfs_sreq_trace_superfluous);
				spin_lock(&rreq->lock);
				list_del(&subreq->rreq_link);
				spin_unlock(&rreq->lock);
				netfs_put_subrequest(subreq, netfs_sreq_trace_put_done);
				if (subreq == to)
					break;
@@ -203,8 +205,10 @@ static void netfs_retry_read_subrequests(struct netfs_io_request *rreq)
					     refcount_read(&subreq->ref),
					     netfs_sreq_trace_new);

			spin_lock(&rreq->lock);
			list_add(&subreq->rreq_link, &to->rreq_link);
			to = list_next_entry(to, rreq_link);
			spin_unlock(&rreq->lock);
			to = subreq;
			trace_netfs_sreq(subreq, netfs_sreq_trace_retry);

			stream->sreq_max_len	= umin(len, rreq->rsize);
+5 −1
Original line number Diff line number Diff line
@@ -130,7 +130,9 @@ static void netfs_retry_write_stream(struct netfs_io_request *wreq,
			list_for_each_entry_safe_from(subreq, tmp,
						      &stream->subrequests, rreq_link) {
				trace_netfs_sreq(subreq, netfs_sreq_trace_discard);
				spin_lock(&wreq->lock);
				list_del(&subreq->rreq_link);
				spin_unlock(&wreq->lock);
				netfs_put_subrequest(subreq, netfs_sreq_trace_put_done);
				if (subreq == to)
					break;
@@ -153,8 +155,10 @@ static void netfs_retry_write_stream(struct netfs_io_request *wreq,
					     netfs_sreq_trace_new);
			trace_netfs_sreq(subreq, netfs_sreq_trace_split);

			spin_lock(&wreq->lock);
			list_add(&subreq->rreq_link, &to->rreq_link);
			to = list_next_entry(to, rreq_link);
			spin_unlock(&wreq->lock);
			to = subreq;
			trace_netfs_sreq(subreq, netfs_sreq_trace_retry);

			stream->sreq_max_len	= len;