summaryrefslogtreecommitdiffstats
path: root/fs/afs
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2023-10-30 12:43:24 +0100
committerDavid Howells <dhowells@redhat.com>2024-01-01 17:37:27 +0100
commit92f091cdddace38e57ad570663b058a38b4d8bed (patch)
tree991f09f937e580fac3fc823a74aaf81b7e863da8 /fs/afs
parentafs: Mark address lists with configured priorities (diff)
downloadlinux-92f091cdddace38e57ad570663b058a38b4d8bed.tar.xz
linux-92f091cdddace38e57ad570663b058a38b4d8bed.zip
afs: Dispatch fileserver probes in priority order
When probing all the addresses for a fileserver, dispatch them in order of descending priority to try and get back highest priority one first. Also add a tracepoint to show the transmission and completion of the probes. 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')
-rw-r--r--fs/afs/fs_probe.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/fs/afs/fs_probe.c b/fs/afs/fs_probe.c
index 8008d3ecabab..c5702698b18b 100644
--- a/fs/afs/fs_probe.c
+++ b/fs/afs/fs_probe.c
@@ -102,7 +102,7 @@ void afs_fileserver_probe_result(struct afs_call *call)
struct afs_address *addr = &alist->addrs[call->probe_index];
struct afs_server *server = call->server;
unsigned int index = call->probe_index;
- unsigned int rtt_us = 0, cap0;
+ unsigned int rtt_us = -1, cap0;
int ret = call->error;
_enter("%pU,%u", &server->uuid, index);
@@ -182,6 +182,7 @@ responded:
out:
spin_unlock(&server->probe_lock);
+ trace_afs_fs_probe(server, false, alist, index, call->error, call->abort_code, rtt_us);
_debug("probe %pU [%u] %pISpc rtt=%d ret=%d",
&server->uuid, index, rxrpc_kernel_remote_addr(alist->addrs[index].peer),
rtt_us, ret);
@@ -207,6 +208,8 @@ void afs_fs_probe_fileserver(struct afs_net *net, struct afs_server *server,
afs_get_addrlist(alist, afs_alist_trace_get_probe);
read_unlock(&server->fs_lock);
+ afs_get_address_preferences(net, alist);
+
server->probed_at = jiffies;
atomic_set(&server->probe_outstanding, all ? alist->nr_addrs : 1);
memset(&server->probe, 0, sizeof(server->probe));
@@ -217,10 +220,28 @@ void afs_fs_probe_fileserver(struct afs_net *net, struct afs_server *server,
all = true;
if (all) {
- for (index = 0; index < alist->nr_addrs; index++)
+ unsigned long unprobed = (1UL << alist->nr_addrs) - 1;
+ unsigned int i;
+ int best_prio;
+
+ while (unprobed) {
+ best_prio = -1;
+ index = 0;
+ for (i = 0; i < alist->nr_addrs; i++) {
+ if (test_bit(i, &unprobed) &&
+ alist->addrs[i].prio > best_prio) {
+ index = i;
+ best_prio = alist->addrs[i].prio;
+ }
+ }
+ __clear_bit(index, &unprobed);
+
+ trace_afs_fs_probe(server, true, alist, index, 0, 0, 0);
if (!afs_fs_get_capabilities(net, server, alist, index, key))
afs_fs_probe_not_done(net, server, alist, index);
+ }
} else {
+ trace_afs_fs_probe(server, true, alist, index, 0, 0, 0);
if (!afs_fs_get_capabilities(net, server, alist, index, key))
afs_fs_probe_not_done(net, server, alist, index);
}