summaryrefslogtreecommitdiffstats
path: root/fs/afs/vl_rotate.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2019-05-07 15:06:36 +0100
committerDavid Howells <dhowells@redhat.com>2019-05-16 12:58:23 +0100
commitd5c32c89b208e39a39cd8639aa21c012ce0daf4d (patch)
tree856d5540f898c041c51f8868e53381f37d2ff0b7 /fs/afs/vl_rotate.c
parenta49294eac27c7159cd8b89a96c3b1a857e37b683 (diff)
downloadlinux-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.c26
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);