// SPDX-License-Identifier: GPL-2.0-or-later /* AFS vlserver probing * * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com)
*/
/* * Handle the completion of a set of probes.
*/ staticvoid afs_finished_vl_probe(struct afs_vlserver *server)
{ if (!(server->probe.flags & AFS_VLSERVER_PROBE_RESPONDED)) {
server->rtt = UINT_MAX;
clear_bit(AFS_VLSERVER_FL_RESPONDING, &server->flags);
}
/* * Handle the completion of a probe RPC call.
*/ staticvoid afs_done_one_vl_probe(struct afs_vlserver *server, bool wake_up)
{ if (atomic_dec_and_test(&server->probe_outstanding)) {
afs_finished_vl_probe(server);
wake_up = true;
}
if (wake_up)
wake_up_all(&server->probe_wq);
}
/* * Process the result of probing a vlserver. This is called after successful * or failed delivery of an VL.GetCapabilities operation.
*/ void afs_vlserver_probe_result(struct afs_call *call)
{ struct afs_addr_list *alist = call->vl_probe; struct afs_vlserver *server = call->vlserver; struct afs_address *addr = &alist->addrs[call->probe_index]; unsignedint server_index = call->server_index; unsignedint rtt_us = 0; unsignedint index = call->probe_index; bool have_result = false; int ret = call->error;
/* * Probe all of a vlserver's addresses to find out the best route and to * query its capabilities.
*/ staticbool afs_do_probe_vlserver(struct afs_net *net, struct afs_vlserver *server, struct key *key, unsignedint server_index, struct afs_error *_e)
{ struct afs_addr_list *alist; struct afs_call *call; unsignedlong unprobed; unsignedint index, i; bool in_progress = false; int best_prio;
/* * Send off probes to all unprobed servers.
*/ int afs_send_vl_probes(struct afs_net *net, struct key *key, struct afs_vlserver_list *vllist)
{ struct afs_vlserver *server; struct afs_error e = {}; bool in_progress = false; int i;
for (i = 0; i < vllist->nr_servers; i++) {
server = vllist->servers[i].server; if (test_bit(AFS_VLSERVER_FL_PROBED, &server->flags)) continue;
if (!test_and_set_bit_lock(AFS_VLSERVER_FL_PROBING, &server->flags) &&
afs_do_probe_vlserver(net, server, key, i, &e))
in_progress = true;
}
return in_progress ? 0 : e.error;
}
/* * Wait for the first as-yet untried server to respond.
*/ int afs_wait_for_vl_probes(struct afs_vlserver_list *vllist, unsignedlong untried)
{ struct wait_queue_entry *waits; struct afs_vlserver *server; unsignedint rtt = UINT_MAX, rtt_s; bool have_responders = false; int pref = -1, i;
_enter("%u,%lx", vllist->nr_servers, untried);
/* Only wait for servers that have a probe outstanding. */ for (i = 0; i < vllist->nr_servers; i++) { if (test_bit(i, &untried)) {
server = vllist->servers[i].server; if (!test_bit(AFS_VLSERVER_FL_PROBING, &server->flags))
__clear_bit(i, &untried); if (server->probe.flags & AFS_VLSERVER_PROBE_RESPONDED)
have_responders = true;
}
} if (have_responders || !untried) return 0;
waits = kmalloc(array_size(vllist->nr_servers, sizeof(*waits)), GFP_KERNEL); if (!waits) return -ENOMEM;
for (i = 0; i < vllist->nr_servers; i++) { if (test_bit(i, &untried)) {
server = vllist->servers[i].server;
init_waitqueue_entry(&waits[i], current);
add_wait_queue(&server->probe_wq, &waits[i]);
}
}
for (;;) { bool still_probing = false;
set_current_state(TASK_INTERRUPTIBLE); for (i = 0; i < vllist->nr_servers; i++) { if (test_bit(i, &untried)) {
server = vllist->servers[i].server; if (server->probe.flags & AFS_VLSERVER_PROBE_RESPONDED) goto stop; if (test_bit(AFS_VLSERVER_FL_PROBING, &server->flags))
still_probing = true;
}
}
if (!still_probing || signal_pending(current)) goto stop;
schedule();
}
stop:
set_current_state(TASK_RUNNING);
for (i = 0; i < vllist->nr_servers; i++) { if (test_bit(i, &untried)) {
server = vllist->servers[i].server;
rtt_s = READ_ONCE(server->rtt); if (test_bit(AFS_VLSERVER_FL_RESPONDING, &server->flags) &&
rtt_s < rtt) {
pref = i;
rtt = rtt_s;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.