From 6b8812fc8ec28c13c09c89f88ce3958f19238838 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 7 May 2019 15:16:26 +0100 Subject: 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: 0a5143f2f89c ("afs: Implement VL server rotation") Signed-off-by: David Howells --- fs/afs/cell.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'fs/afs/cell.c') diff --git a/fs/afs/cell.c b/fs/afs/cell.c index 9de46116c749..9ca075e11239 100644 --- a/fs/afs/cell.c +++ b/fs/afs/cell.c @@ -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_NOT_FOUND, &cell->flags); - /* Exclusion on changing vl_addrs is achieved by a - * non-reentrant work item. - */ + write_lock(&cell->vl_servers_lock); old = rcu_dereference_protected(cell->vl_servers, true); rcu_assign_pointer(cell->vl_servers, vllist); cell->dns_expiry = expiry; + write_unlock(&cell->vl_servers_lock); if (old) afs_put_vlserverlist(cell->net, old); -- cgit v1.2.3