summaryrefslogtreecommitdiffstats
path: root/fs/afs/vl_list.c
diff options
context:
space:
mode:
authorDavid Howells2018-10-20 01:57:59 +0200
committerDavid Howells2018-10-24 01:41:09 +0200
commit3bf0fb6f33dd545693da5e65f5b1b9b9f0bfc35e (patch)
treedf215e6a6ad11b6ac8158461144667e168591d28 /fs/afs/vl_list.c
parentafs: Fix callback handling (diff)
downloadkernel-qcow2-linux-3bf0fb6f33dd545693da5e65f5b1b9b9f0bfc35e.tar.gz
kernel-qcow2-linux-3bf0fb6f33dd545693da5e65f5b1b9b9f0bfc35e.tar.xz
kernel-qcow2-linux-3bf0fb6f33dd545693da5e65f5b1b9b9f0bfc35e.zip
afs: Probe multiple fileservers simultaneously
Send probes to all the unprobed fileservers in a fileserver list on all addresses simultaneously in an attempt to find out the fastest route whilst not getting stuck for 20s on any server or address that we don't get a reply from. This alleviates the problem whereby attempting to access a new server can take a long time because the rotation algorithm ends up rotating through all servers and addresses until it finds one that responds. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/afs/vl_list.c')
-rw-r--r--fs/afs/vl_list.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/fs/afs/vl_list.c b/fs/afs/vl_list.c
index c1e316ba105a..b4f1a84519b9 100644
--- a/fs/afs/vl_list.c
+++ b/fs/afs/vl_list.c
@@ -23,6 +23,8 @@ struct afs_vlserver *afs_alloc_vlserver(const char *name, size_t name_len,
if (vlserver) {
atomic_set(&vlserver->usage, 1);
rwlock_init(&vlserver->lock);
+ init_waitqueue_head(&vlserver->probe_wq);
+ spin_lock_init(&vlserver->probe_lock);
vlserver->name_len = name_len;
vlserver->port = port;
memcpy(vlserver->name, name, name_len);
@@ -141,7 +143,7 @@ static struct afs_addr_list *afs_extract_vl_addrs(const u8 **_b, const u8 *end,
/* Start with IPv6 if available. */
if (alist->nr_ipv4 < alist->nr_addrs)
- alist->index = alist->nr_ipv4;
+ alist->preferred = alist->nr_ipv4;
*_b = b;
return alist;
@@ -307,6 +309,8 @@ struct afs_vlserver_list *afs_extract_vlserver_list(struct afs_cell *cell,
(vllist->nr_servers - j) * sizeof(struct afs_vlserver_entry));
}
+ clear_bit(AFS_VLSERVER_FL_PROBED, &server->flags);
+
vllist->servers[j].priority = bs.priority;
vllist->servers[j].weight = bs.weight;
vllist->servers[j].server = server;