summaryrefslogtreecommitdiff
path: root/fs/netfs/buffered_read.c
diff options
context:
space:
mode:
authorChristian Brauner <brauner@kernel.org>2025-02-13 16:00:53 +0100
committerChristian Brauner <brauner@kernel.org>2025-02-13 16:00:53 +0100
commita33f72554adf4552e53af3784cebfc4f2886c396 (patch)
treeafa16f1d2c2a31b92d7fd05248f1f6186032c8be /fs/netfs/buffered_read.c
parent240189294fbc9550f5cd7ae9b446ad3cf3c5386a (diff)
parent5de0219a9bb9dacc4ce6e8f2745540dcce786983 (diff)
Merge patch series "netfs: Miscellaneous fixes"
David Howells <dhowells@redhat.com> says: Here are some miscellaneous fixes and changes for netfslib: (1) Fix a number of read-retry hangs, including: (a) Incorrect getting/putting of references on subreqs as we retry them. (b) Failure to track whether a last old subrequest in a retried set is superfluous. (c) Inconsistency in the usage of wait queues used for subrequests (ie. using clear_and_wake_up_bit() whilst waiting on a private waitqueue). (Note that waitqueue consistency also needs looking at for netfs_io_request structs.) (2) Add stats counters for retries and publish in /proc/fs/netfs/stats. This is not a fix per se, but is useful in debugging and shouldn't otherwise change the operation of the code. (3) Fix the ordering of queuing subrequests with respect to setting the request flag that says we've now queued them all. * patches from https://lore.kernel.org/r/20250212222402.3618494-1-dhowells@redhat.com: netfs: Fix setting NETFS_RREQ_ALL_QUEUED to be after all subreqs queued netfs: Add retry stat counters netfs: Fix a number of read-retry hangs Link: https://lore.kernel.org/r/20250212222402.3618494-1-dhowells@redhat.com Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'fs/netfs/buffered_read.c')
-rw-r--r--fs/netfs/buffered_read.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/fs/netfs/buffered_read.c b/fs/netfs/buffered_read.c
index f761d44b3436..0d1b6d35ff3b 100644
--- a/fs/netfs/buffered_read.c
+++ b/fs/netfs/buffered_read.c
@@ -155,8 +155,9 @@ static void netfs_read_cache_to_pagecache(struct netfs_io_request *rreq,
netfs_cache_read_terminated, subreq);
}
-static void netfs_issue_read(struct netfs_io_request *rreq,
- struct netfs_io_subrequest *subreq)
+static void netfs_queue_read(struct netfs_io_request *rreq,
+ struct netfs_io_subrequest *subreq,
+ bool last_subreq)
{
struct netfs_io_stream *stream = &rreq->io_streams[0];
@@ -177,8 +178,17 @@ static void netfs_issue_read(struct netfs_io_request *rreq,
}
}
+ if (last_subreq) {
+ smp_wmb(); /* Write lists before ALL_QUEUED. */
+ set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
+ }
+
spin_unlock(&rreq->lock);
+}
+static void netfs_issue_read(struct netfs_io_request *rreq,
+ struct netfs_io_subrequest *subreq)
+{
switch (subreq->source) {
case NETFS_DOWNLOAD_FROM_SERVER:
rreq->netfs_ops->issue_read(subreq);
@@ -293,11 +303,8 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
}
size -= slice;
start += slice;
- if (size <= 0) {
- smp_wmb(); /* Write lists before ALL_QUEUED. */
- set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
- }
+ netfs_queue_read(rreq, subreq, size <= 0);
netfs_issue_read(rreq, subreq);
cond_resched();
} while (size > 0);