aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/fs/afs/fs_operation.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2023-10-18 09:24:01 +0100
committerDavid Howells <dhowells@redhat.com>2024-01-01 16:37:27 +0000
commit495f2ae9e3552c30f7b83be3d142a932885d506e (patch)
tree3b92948d42863f697e4b62f7ef3f56387ff8e80d /fs/afs/fs_operation.c
parentafs: Overhaul invalidation handling to better support RO volumes (diff)
downloadwireguard-linux-495f2ae9e3552c30f7b83be3d142a932885d506e.tar.xz
wireguard-linux-495f2ae9e3552c30f7b83be3d142a932885d506e.zip
afs: Fix fileserver rotation
Fix the fileserver rotation so that it doesn't use RTT as the basis for deciding which server and address to use as this doesn't necessarily give a good indication of the best path. Instead, use the configurable preference list in conjunction with whatever probes have succeeded at the time of looking. To this end, make the following changes: (1) Keep an array of "server states" to track what addresses we've tried on each server and move the waitqueue entries there that we'll need for probing. (2) Each afs_server_state struct is made to pin the corresponding server's endpoint state rather than the afs_operation struct carrying a pin on the server we're currently looking at. (3) Drop the server list preference; we now always rescan the server list. (4) afs_wait_for_probes() now uses the server state list to guide it in what it waits for (and to provide the waitqueue entries) and returns an indication of whether we'd got a response, run out of responsive addresses or the endpoint state had been superseded and we need to restart the iteration. (5) Call afs_get_address_preferences*() occasionally to refresh the preference values. (6) When picking a server, scan the addresses of the servers for which we have as-yet untested communications, looking for the highest priority one and use that instead of trying all the addresses for a particular server in ascending-RTT order. (7) When a Busy or Offline state is seen across all available servers, do a short sleep. (8) If we detect that we accessed a future RO volume version whilst it is undergoing replication, reissue the op against the older version until at least half of the servers are replicated. (9) Whilst RO replication is ongoing, increase the frequency of Volume Location server checks for that volume to every ten minutes instead of hourly. Also add a tracepoint to track progress through the rotation algorithm. 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/fs_operation.c')
-rw-r--r--fs/afs/fs_operation.c8
1 files changed, 3 insertions, 5 deletions
diff --git a/fs/afs/fs_operation.c b/fs/afs/fs_operation.c
index cecc44af6a5f..3546b087e791 100644
--- a/fs/afs/fs_operation.c
+++ b/fs/afs/fs_operation.c
@@ -229,7 +229,6 @@ void afs_wait_for_operation(struct afs_operation *op)
*/
int afs_put_operation(struct afs_operation *op)
{
- struct afs_endpoint_state *estate = op->estate;
struct afs_addr_list *alist;
int i, ret = afs_op_error(op);
@@ -253,18 +252,17 @@ int afs_put_operation(struct afs_operation *op)
kfree(op->more_files);
}
- if (estate) {
- alist = estate->addresses;
+ if (op->estate) {
+ alist = op->estate->addresses;
if (alist) {
if (op->call_responded &&
op->addr_index != alist->preferred &&
test_bit(alist->preferred, &op->addr_tried))
WRITE_ONCE(alist->preferred, op->addr_index);
}
- afs_put_endpoint_state(estate, afs_estate_trace_put_operation);
- op->estate = NULL;
}
+ afs_clear_server_states(op);
afs_put_serverlist(op->net, op->server_list);
afs_put_volume(op->volume, afs_volume_trace_put_put_op);
key_put(op->key);