summaryrefslogtreecommitdiff
path: root/fs/afs/proc.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2023-10-31 19:30:37 +0300
committerDavid Howells <dhowells@redhat.com>2024-01-01 19:37:27 +0300
commitf49b594df3ebca53c91f4d6448680463f10aa479 (patch)
treed18f0048178320274cf73b7e62c4cbb3a8ae9b80 /fs/afs/proc.c
parente6a7d7f71b17e0a44e2155bdad47eae7b5368503 (diff)
downloadlinux-f49b594df3ebca53c91f4d6448680463f10aa479.tar.xz
afs: Keep a record of the current fileserver endpoint state
Keep a record of the current fileserver endpoint state, including the probe state, and replace it when a new probe is started rather than just squelching the old state and overwriting it. Clearance of the old state can cause a race if there's another thread also currently trying to communicate with that server. It appears that this race might be the culprit for some occasions where kafs complains about invalid data in the RPC reply because the rotation algorithm fell all the way through without actually issuing an RPC call and the error return got filled in from the probe state (which has a zero error recorded). Whatever happens to be in the caller's reply buffer is then taken as the response. Signed-off-by: David Howells <dhowells@redhat.com> cc: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org
Diffstat (limited to 'fs/afs/proc.c')
-rw-r--r--fs/afs/proc.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/fs/afs/proc.c b/fs/afs/proc.c
index 944eb51e75a1..a138022d8e0d 100644
--- a/fs/afs/proc.c
+++ b/fs/afs/proc.c
@@ -424,8 +424,9 @@ static const struct seq_operations afs_proc_cell_vlservers_ops = {
*/
static int afs_proc_servers_show(struct seq_file *m, void *v)
{
- struct afs_server *server;
+ struct afs_endpoint_state *estate;
struct afs_addr_list *alist;
+ struct afs_server *server;
unsigned long failed;
int i;
@@ -435,7 +436,8 @@ static int afs_proc_servers_show(struct seq_file *m, void *v)
}
server = list_entry(v, struct afs_server, proc_link);
- alist = rcu_dereference(server->addresses);
+ estate = rcu_dereference(server->endpoint_state);
+ alist = estate->addresses;
seq_printf(m, "%pU %3d %3d %s\n",
&server->uuid,
refcount_read(&server->ref),
@@ -443,13 +445,14 @@ static int afs_proc_servers_show(struct seq_file *m, void *v)
server->cell->name);
seq_printf(m, " - info: fl=%lx rtt=%u brk=%x\n",
server->flags, server->rtt, server->cb_s_break);
- seq_printf(m, " - probe: last=%d out=%d\n",
- (int)(jiffies - server->probed_at) / HZ,
- atomic_read(&server->probe_outstanding));
- failed = alist->probe_failed;
- seq_printf(m, " - ALIST v=%u rsp=%lx f=%lx ap=%u\n",
- alist->version, alist->responded, alist->probe_failed,
- alist->addr_pref_version);
+ seq_printf(m, " - probe: last=%d\n",
+ (int)(jiffies - server->probed_at) / HZ);
+ failed = estate->failed_set;
+ seq_printf(m, " - ESTATE pq=%x np=%u rsp=%lx f=%lx\n",
+ estate->probe_seq, atomic_read(&estate->nr_probing),
+ estate->responsive_set, estate->failed_set);
+ seq_printf(m, " - ALIST v=%u ap=%u\n",
+ alist->version, alist->addr_pref_version);
for (i = 0; i < alist->nr_addrs; i++) {
const struct afs_address *addr = &alist->addrs[i];