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

netfs: Provide helpers to perform NETFS_RREQ_IN_PROGRESS flag wangling



Provide helpers to clear and test the NETFS_RREQ_IN_PROGRESS and to insert
the appropriate barrierage.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Link: https://lore.kernel.org/20250701163852.2171681-4-dhowells@redhat.com


Tested-by: default avatarSteve French <sfrench@samba.org>
Reviewed-by: default avatarPaulo 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 9df7b5eb
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -274,6 +274,24 @@ static inline void netfs_wake_rreq_flag(struct netfs_io_request *rreq,
	}
}

/*
 * Test the NETFS_RREQ_IN_PROGRESS flag, inserting an appropriate barrier.
 */
static inline bool netfs_check_rreq_in_progress(const struct netfs_io_request *rreq)
{
	/* Order read of flags before read of anything else, such as error. */
	return test_bit_acquire(NETFS_RREQ_IN_PROGRESS, &rreq->flags);
}

/*
 * Test the NETFS_SREQ_IN_PROGRESS flag, inserting an appropriate barrier.
 */
static inline bool netfs_check_subreq_in_progress(const struct netfs_io_subrequest *subreq)
{
	/* Order read of flags before read of anything else, such as error. */
	return test_bit_acquire(NETFS_SREQ_IN_PROGRESS, &subreq->flags);
}

/*
 * fscache-cache.c
 */
+5 −5
Original line number Diff line number Diff line
@@ -356,14 +356,14 @@ void netfs_wait_for_in_progress_stream(struct netfs_io_request *rreq,
	DEFINE_WAIT(myself);

	list_for_each_entry(subreq, &stream->subrequests, rreq_link) {
		if (!test_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags))
		if (!netfs_check_subreq_in_progress(subreq))
			continue;

		trace_netfs_rreq(rreq, netfs_rreq_trace_wait_queue);
		for (;;) {
			prepare_to_wait(&rreq->waitq, &myself, TASK_UNINTERRUPTIBLE);

			if (!test_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags))
			if (!netfs_check_subreq_in_progress(subreq))
				break;

			trace_netfs_sreq(subreq, netfs_sreq_trace_wait_for);
@@ -400,7 +400,7 @@ static int netfs_collect_in_app(struct netfs_io_request *rreq,
						  struct netfs_io_subrequest,
						  rreq_link);
		if (subreq &&
		    (!test_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags) ||
		    (!netfs_check_subreq_in_progress(subreq) ||
		     test_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags))) {
			need_collect = true;
			break;
@@ -451,7 +451,7 @@ static ssize_t netfs_wait_for_request(struct netfs_io_request *rreq,
			}
		}

		if (!test_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags))
		if (!netfs_check_rreq_in_progress(rreq))
			break;

		schedule();
@@ -518,7 +518,7 @@ static void netfs_wait_for_pause(struct netfs_io_request *rreq,
			}
		}

		if (!test_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags) ||
		if (!netfs_check_rreq_in_progress(rreq) ||
		    !test_bit(NETFS_RREQ_PAUSE, &rreq->flags))
			break;

+2 −2
Original line number Diff line number Diff line
@@ -218,7 +218,7 @@ static void netfs_collect_read_results(struct netfs_io_request *rreq)
			stream->collected_to = front->start;
		}

		if (test_bit(NETFS_SREQ_IN_PROGRESS, &front->flags))
		if (netfs_check_subreq_in_progress(front))
			notes |= HIT_PENDING;
		smp_rmb(); /* Read counters after IN_PROGRESS flag. */
		transferred = READ_ONCE(front->transferred);
@@ -445,7 +445,7 @@ void netfs_read_collection_worker(struct work_struct *work)
	struct netfs_io_request *rreq = container_of(work, struct netfs_io_request, work);

	netfs_see_request(rreq, netfs_rreq_trace_see_work);
	if (test_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags)) {
	if (netfs_check_rreq_in_progress(rreq)) {
		if (netfs_read_collection(rreq))
			/* Drop the ref from the IN_PROGRESS flag. */
			netfs_put_request(rreq, netfs_rreq_trace_put_work_ip);
+2 −2
Original line number Diff line number Diff line
@@ -240,7 +240,7 @@ static void netfs_collect_write_results(struct netfs_io_request *wreq)
			}

			/* Stall if the front is still undergoing I/O. */
			if (test_bit(NETFS_SREQ_IN_PROGRESS, &front->flags)) {
			if (netfs_check_subreq_in_progress(front)) {
				notes |= HIT_PENDING;
				break;
			}
@@ -434,7 +434,7 @@ void netfs_write_collection_worker(struct work_struct *work)
	struct netfs_io_request *rreq = container_of(work, struct netfs_io_request, work);

	netfs_see_request(rreq, netfs_rreq_trace_see_work);
	if (test_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags)) {
	if (netfs_check_rreq_in_progress(rreq)) {
		if (netfs_write_collection(rreq))
			/* Drop the ref from the IN_PROGRESS flag. */
			netfs_put_request(rreq, netfs_rreq_trace_put_work_ip);