Skip to content

Commit da0e01c

Browse files
dhowellsbrauner
authored andcommitted
afs: Fix fileserver rotation getting stuck
Fix the fileserver rotation code in a couple of ways: (1) op->server_states is an array, not a pointer to a single record, so fix the places that access it to index it. (2) In the places that go through an address list to work out which one has the best priority, fix the loops to skip known failed addresses. Without this, the rotation algorithm may get stuck on addresses that are inaccessible or don't respond. This can be triggered manually by finding a server that advertises a non-routable address and giving it a higher priority, eg.: echo "add udp 192.168.0.0/16 3000" >/proc/fs/afs/addr_prefs if the server, say, includes the address 192.168.7.7 in its address list, and then attempting to access a volume on that server. Fixes: 495f2ae ("afs: Fix fileserver rotation") Signed-off-by: David Howells <dhowells@redhat.com> cc: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org Link: https://lore.kernel.org/r/4005300.1712309731@warthog.procyon.org.uk/ # v1 Link: https://lore.kernel.org/r/998836.1714746152@warthog.procyon.org.uk Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent 4810ce7 commit da0e01c

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

fs/afs/rotate.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -541,11 +541,13 @@ bool afs_select_fileserver(struct afs_operation *op)
541541
test_bit(AFS_SE_EXCLUDED, &se->flags) ||
542542
!test_bit(AFS_SERVER_FL_RESPONDING, &s->flags))
543543
continue;
544-
es = op->server_states->endpoint_state;
544+
es = op->server_states[i].endpoint_state;
545545
sal = es->addresses;
546546

547547
afs_get_address_preferences_rcu(op->net, sal);
548548
for (j = 0; j < sal->nr_addrs; j++) {
549+
if (es->failed_set & (1 << j))
550+
continue;
549551
if (!sal->addrs[j].peer)
550552
continue;
551553
if (sal->addrs[j].prio > best_prio) {
@@ -605,6 +607,8 @@ bool afs_select_fileserver(struct afs_operation *op)
605607
best_prio = -1;
606608
addr_index = 0;
607609
for (i = 0; i < alist->nr_addrs; i++) {
610+
if (!(set & (1 << i)))
611+
continue;
608612
if (alist->addrs[i].prio > best_prio) {
609613
addr_index = i;
610614
best_prio = alist->addrs[i].prio;
@@ -674,7 +678,7 @@ bool afs_select_fileserver(struct afs_operation *op)
674678
for (i = 0; i < op->server_list->nr_servers; i++) {
675679
struct afs_endpoint_state *estate;
676680

677-
estate = op->server_states->endpoint_state;
681+
estate = op->server_states[i].endpoint_state;
678682
error = READ_ONCE(estate->error);
679683
if (error < 0)
680684
afs_op_accumulate_error(op, error, estate->abort_code);

0 commit comments

Comments
 (0)