From 6b8812fc8ec28c13c09c89f88ce3958f19238838 Mon Sep 17 00:00:00 2001
From: David Howells <dhowells@redhat.com>
Date: Tue, 7 May 2019 15:16:26 +0100
Subject: [PATCH] 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 <dhowells@redhat.com>
---
 fs/afs/cell.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/fs/afs/cell.c b/fs/afs/cell.c
index 9de46116c7492..9ca075e112393 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);
-- 
GitLab