diff options
author | David Howells <dhowells@redhat.com> | 2017-11-02 11:27:50 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2017-11-13 10:38:18 -0500 |
commit | 989782dcdc91a5e6d5999c7a52a84a60a0811e56 (patch) | |
tree | 138ed46554536280e0d4d1834a16c28740e8cdae /fs/afs/super.c | |
parent | be080a6f43c40976afc950ee55e9b7f8e2b53525 (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.c | 12 |
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 ?: ""); |