diff options
author | David Howells <dhowells@redhat.com> | 2019-05-07 15:06:36 +0100 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2019-05-16 12:58:23 +0100 |
commit | d5c32c89b208e39a39cd8639aa21c012ce0daf4d (patch) | |
tree | 856d5540f898c041c51f8868e53381f37d2ff0b7 /fs/afs/vl_rotate.c | |
parent | a49294eac27c7159cd8b89a96c3b1a857e37b683 (diff) | |
download | linux-d5c32c89b208e39a39cd8639aa21c012ce0daf4d.tar.gz linux-d5c32c89b208e39a39cd8639aa21c012ce0daf4d.tar.bz2 linux-d5c32c89b208e39a39cd8639aa21c012ce0daf4d.zip |
afs: Fix cell DNS lookup
Currently, once configured, AFS cells are looked up in the DNS at regular
intervals - which is a waste of resources if those cells aren't being
used. It also leads to a problem where cells preloaded, but not
configured, before the network is brought up end up effectively statically
configured with no VL servers and are unable to get any.
Fix this by not doing the DNS lookup until the first time a cell is
touched. It is waited for if we don't have any cached records yet,
otherwise the DNS lookup to maintain the record is done in the background.
This has the downside that the first time you touch a cell, you now have to
wait for the upcall to do the required DNS lookups rather than them already
being cached.
Further, the record is not replaced if the old record has at least one
server in it and the new record doesn't have any.
Fixes: 0a5143f2f89c ("afs: Implement VL server rotation")
Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/afs/vl_rotate.c')
-rw-r--r-- | fs/afs/vl_rotate.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/fs/afs/vl_rotate.c b/fs/afs/vl_rotate.c index 65629d73ad9d..3f845489a9f0 100644 --- a/fs/afs/vl_rotate.c +++ b/fs/afs/vl_rotate.c @@ -43,11 +43,29 @@ bool afs_begin_vlserver_operation(struct afs_vl_cursor *vc, struct afs_cell *cel static bool afs_start_vl_iteration(struct afs_vl_cursor *vc) { struct afs_cell *cell = vc->cell; + unsigned int dns_lookup_count; + + if (cell->dns_source == DNS_RECORD_UNAVAILABLE || + cell->dns_expiry <= ktime_get_real_seconds()) { + dns_lookup_count = smp_load_acquire(&cell->dns_lookup_count); + set_bit(AFS_CELL_FL_DO_LOOKUP, &cell->flags); + queue_work(afs_wq, &cell->manager); + + if (cell->dns_source == DNS_RECORD_UNAVAILABLE) { + if (wait_var_event_interruptible( + &cell->dns_lookup_count, + smp_load_acquire(&cell->dns_lookup_count) + != dns_lookup_count) < 0) { + vc->error = -ERESTARTSYS; + return false; + } + } - if (wait_on_bit(&cell->flags, AFS_CELL_FL_NO_LOOKUP_YET, - TASK_INTERRUPTIBLE)) { - vc->error = -ERESTARTSYS; - return false; + /* Status load is ordered after lookup counter load */ + if (cell->dns_source == DNS_RECORD_UNAVAILABLE) { + vc->error = -EDESTADDRREQ; + return false; + } } read_lock(&cell->vl_servers_lock); |