Commit 6b8812fc authored by David Howells's avatar David Howells

afs: Fix missing lock when replacing VL server list

When afs_update_cell() replaces the cell->vl_servers list, it uses RCU
protocol so that proc is protected, but doesn't take ->vl_servers_lock to
protect afs_start_vl_iteration() (which does actually take a shared lock).

Fix this by making afs_update_cell() take an exclusive lock when replacing
->vl_servers.

Fixes: 0a5143f2 ("afs: Implement VL server rotation")
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent 773e0c40
...@@ -404,12 +404,11 @@ static void afs_update_cell(struct afs_cell *cell) ...@@ -404,12 +404,11 @@ static void afs_update_cell(struct afs_cell *cell)
clear_bit(AFS_CELL_FL_DNS_FAIL, &cell->flags); clear_bit(AFS_CELL_FL_DNS_FAIL, &cell->flags);
clear_bit(AFS_CELL_FL_NOT_FOUND, &cell->flags); clear_bit(AFS_CELL_FL_NOT_FOUND, &cell->flags);
/* Exclusion on changing vl_addrs is achieved by a write_lock(&cell->vl_servers_lock);
* non-reentrant work item.
*/
old = rcu_dereference_protected(cell->vl_servers, true); old = rcu_dereference_protected(cell->vl_servers, true);
rcu_assign_pointer(cell->vl_servers, vllist); rcu_assign_pointer(cell->vl_servers, vllist);
cell->dns_expiry = expiry; cell->dns_expiry = expiry;
write_unlock(&cell->vl_servers_lock);
if (old) if (old)
afs_put_vlserverlist(cell->net, old); afs_put_vlserverlist(cell->net, old);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment