aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2019-05-07 10:16:26 -0400
committerDavid Howells <dhowells@redhat.com>2019-05-15 12:35:53 -0400
commit6b8812fc8ec28c13c09c89f88ce3958f19238838 (patch)
tree9cbdfed7205a1b2255706b1293893639b1122ba4 /fs/afs
parent773e0c40253443e0ce5491cb0e414b62f7cc45ed (diff)
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>
Diffstat (limited to 'fs/afs')
-rw-r--r--fs/afs/cell.c5
1 files changed, 2 insertions, 3 deletions
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)
404 clear_bit(AFS_CELL_FL_DNS_FAIL, &cell->flags); 404 clear_bit(AFS_CELL_FL_DNS_FAIL, &cell->flags);
405 clear_bit(AFS_CELL_FL_NOT_FOUND, &cell->flags); 405 clear_bit(AFS_CELL_FL_NOT_FOUND, &cell->flags);
406 406
407 /* Exclusion on changing vl_addrs is achieved by a 407 write_lock(&cell->vl_servers_lock);
408 * non-reentrant work item.
409 */
410 old = rcu_dereference_protected(cell->vl_servers, true); 408 old = rcu_dereference_protected(cell->vl_servers, true);
411 rcu_assign_pointer(cell->vl_servers, vllist); 409 rcu_assign_pointer(cell->vl_servers, vllist);
412 cell->dns_expiry = expiry; 410 cell->dns_expiry = expiry;
411 write_unlock(&cell->vl_servers_lock);
413 412
414 if (old) 413 if (old)
415 afs_put_vlserverlist(cell->net, old); 414 afs_put_vlserverlist(cell->net, old);