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>
This commit is contained in:
David Howells
2017-11-02 15:27:50 +00:00
orang tua be080a6f43
melakukan 989782dcdc
6 mengubah file dengan 740 tambahan dan 353 penghapusan

Melihat File

@@ -200,10 +200,11 @@ static int afs_parse_options(struct afs_mount_params *params,
token = match_token(p, afs_options_list, args);
switch (token) {
case afs_opt_cell:
cell = afs_cell_lookup(params->net,
args[0].from,
args[0].to - args[0].from,
false);
rcu_read_lock();
cell = afs_lookup_cell_rcu(params->net,
args[0].from,
args[0].to - args[0].from);
rcu_read_unlock();
if (IS_ERR(cell))
return PTR_ERR(cell);
afs_put_cell(params->net, params->cell);
@@ -308,7 +309,8 @@ static int afs_parse_device_name(struct afs_mount_params *params,
/* lookup the cell record */
if (cellname || !params->cell) {
cell = afs_cell_lookup(params->net, cellname, cellnamesz, true);
cell = afs_lookup_cell(params->net, cellname, cellnamesz,
NULL, false);
if (IS_ERR(cell)) {
printk(KERN_ERR "kAFS: unable to lookup cell '%*.*s'\n",
cellnamesz, cellnamesz, cellname ?: "");