summaryrefslogtreecommitdiffstats
path: root/fs/afs/super.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2017-11-02 11:27:50 -0400
committerDavid Howells <dhowells@redhat.com>2017-11-13 10:38:18 -0500
commit989782dcdc91a5e6d5999c7a52a84a60a0811e56 (patch)
tree138ed46554536280e0d4d1834a16c28740e8cdae /fs/afs/super.c
parentbe080a6f43c40976afc950ee55e9b7f8e2b53525 (diff)
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/super.c')
-rw-r--r--fs/afs/super.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/fs/afs/super.c b/fs/afs/super.c
index e62fb1bdadc6..3d53b78b350d 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -200,10 +200,11 @@ static int afs_parse_options(struct afs_mount_params *params,
200 token = match_token(p, afs_options_list, args); 200 token = match_token(p, afs_options_list, args);
201 switch (token) { 201 switch (token) {
202 case afs_opt_cell: 202 case afs_opt_cell:
203 cell = afs_cell_lookup(params->net, 203 rcu_read_lock();
204 args[0].from, 204 cell = afs_lookup_cell_rcu(params->net,
205 args[0].to - args[0].from, 205 args[0].from,
206 false); 206 args[0].to - args[0].from);
207 rcu_read_unlock();
207 if (IS_ERR(cell)) 208 if (IS_ERR(cell))
208 return PTR_ERR(cell); 209 return PTR_ERR(cell);
209 afs_put_cell(params->net, params->cell); 210 afs_put_cell(params->net, params->cell);
@@ -308,7 +309,8 @@ static int afs_parse_device_name(struct afs_mount_params *params,
308 309
309 /* lookup the cell record */ 310 /* lookup the cell record */
310 if (cellname || !params->cell) { 311 if (cellname || !params->cell) {
311 cell = afs_cell_lookup(params->net, cellname, cellnamesz, true); 312 cell = afs_lookup_cell(params->net, cellname, cellnamesz,
313 NULL, false);
312 if (IS_ERR(cell)) { 314 if (IS_ERR(cell)) {
313 printk(KERN_ERR "kAFS: unable to lookup cell '%*.*s'\n", 315 printk(KERN_ERR "kAFS: unable to lookup cell '%*.*s'\n",
314 cellnamesz, cellnamesz, cellname ?: ""); 316 cellnamesz, cellnamesz, cellname ?: "");