diff options
author | David Howells <dhowells@redhat.com> | 2017-11-02 15:27:50 +0000 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2017-11-13 15:38:18 +0000 |
commit | 989782dcdc91a5e6d5999c7a52a84a60a0811e56 (patch) | |
tree | 138ed46554536280e0d4d1834a16c28740e8cdae /fs/afs/main.c | |
parent | be080a6f43c40976afc950ee55e9b7f8e2b53525 (diff) | |
download | linux-stable-989782dcdc91a5e6d5999c7a52a84a60a0811e56.tar.gz linux-stable-989782dcdc91a5e6d5999c7a52a84a60a0811e56.tar.bz2 linux-stable-989782dcdc91a5e6d5999c7a52a84a60a0811e56.zip |
afs: Overhaul cell database management
Overhaul the way that the in-kernel AFS client keeps track of cells in the
following manner:
(1) Cells are now held in an rbtree to make walking them quicker and RCU
managed (though this is probably overkill).
(2) Cells now have a manager work item that:
(A) Looks after fetching and refreshing the VL server list.
(B) Manages cell record lifetime, including initialising and
destruction.
(B) Manages cell record caching whereby threads are kept around for a
certain time after last use and then destroyed.
(C) Manages the FS-Cache index cookie for a cell. It is not permitted
for a cookie to be in use twice, so we have to be careful to not
allow a new cell record to exist at the same time as an old record
of the same name.
(3) Each AFS network namespace is given a manager work item that manages
the cells within it, maintaining a single timer to prod cells into
updating their DNS records.
This uses the reduce_timer() facility to make the timer expire at the
soonest timed event that needs happening.
(4) When a module is being unloaded, cells and cell managers are now
counted out using dec_after_work() to make sure the module text is
pinned until after the data structures have been cleaned up.
(5) Each cell's VL server list is now protected by a seqlock rather than a
semaphore.
Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/afs/main.c')
-rw-r--r-- | fs/afs/main.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/fs/afs/main.c b/fs/afs/main.c index 010e2e1a40f4..e7f87d723761 100644 --- a/fs/afs/main.c +++ b/fs/afs/main.c @@ -46,12 +46,15 @@ static int __net_init afs_net_init(struct afs_net *net) INIT_WORK(&net->charge_preallocation_work, afs_charge_preallocation); mutex_init(&net->socket_mutex); - INIT_LIST_HEAD(&net->cells); - rwlock_init(&net->cells_lock); - init_rwsem(&net->cells_sem); - init_waitqueue_head(&net->cells_freeable_wq); - init_rwsem(&net->proc_cells_sem); + + net->cells = RB_ROOT; + seqlock_init(&net->cells_lock); + INIT_WORK(&net->cells_manager, afs_manage_cells); + timer_setup(&net->cells_timer, afs_cells_timer, 0); + + spin_lock_init(&net->proc_cells_lock); INIT_LIST_HEAD(&net->proc_cells); + INIT_LIST_HEAD(&net->vl_updates); INIT_LIST_HEAD(&net->vl_graveyard); INIT_DELAYED_WORK(&net->vl_reaper, afs_vlocation_reaper); @@ -83,11 +86,14 @@ static int __net_init afs_net_init(struct afs_net *net) return 0; error_open_socket: + net->live = false; afs_vlocation_purge(net); afs_cell_purge(net); error_cell_init: + net->live = false; afs_proc_cleanup(net); error_proc: + net->live = false; return ret; } |