diff options
author | David Howells <dhowells@redhat.com> | 2023-10-31 17:30:37 +0100 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2024-01-01 17:37:27 +0100 |
commit | f49b594df3ebca53c91f4d6448680463f10aa479 (patch) | |
tree | d18f0048178320274cf73b7e62c4cbb3a8ae9b80 /fs/afs/fsclient.c | |
parent | afs: Dispatch vlserver probes in priority order (diff) | |
download | linux-f49b594df3ebca53c91f4d6448680463f10aa479.tar.xz linux-f49b594df3ebca53c91f4d6448680463f10aa479.zip |
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/fsclient.c')
-rw-r--r-- | fs/afs/fsclient.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c index 4f98b43b0dde..f1f879ba9cf7 100644 --- a/fs/afs/fsclient.c +++ b/fs/afs/fsclient.c @@ -1697,7 +1697,7 @@ static int afs_deliver_fs_get_capabilities(struct afs_call *call) static void afs_fs_get_capabilities_destructor(struct afs_call *call) { - afs_put_addrlist(call->probe_alist, afs_alist_trace_put_getcaps); + afs_put_endpoint_state(call->probe, afs_estate_trace_put_getcaps); afs_flat_call_destructor(call); } @@ -1719,7 +1719,7 @@ static const struct afs_call_type afs_RXFSGetCapabilities = { * ->done() - otherwise we return false to indicate we didn't even try. */ bool afs_fs_get_capabilities(struct afs_net *net, struct afs_server *server, - struct afs_addr_list *alist, unsigned int addr_index, + struct afs_endpoint_state *estate, unsigned int addr_index, struct key *key) { struct afs_call *call; @@ -1733,8 +1733,8 @@ bool afs_fs_get_capabilities(struct afs_net *net, struct afs_server *server, call->key = key; call->server = afs_use_server(server, afs_server_trace_get_caps); - call->peer = rxrpc_kernel_get_peer(alist->addrs[addr_index].peer); - call->probe_alist = afs_get_addrlist(alist, afs_alist_trace_get_getcaps); + call->peer = rxrpc_kernel_get_peer(estate->addresses->addrs[addr_index].peer); + call->probe = afs_get_endpoint_state(estate, afs_estate_trace_get_getcaps); call->probe_index = addr_index; call->service_id = server->service_id; call->upgrade = true; |