diff options
author | David Howells | 2018-10-20 00:57:57 +0100 |
---|---|---|
committer | David Howells | 2018-10-24 00:41:07 +0100 |
commit | 0a5143f2f89cc88d8a3eada8e8ccd86c1e988257 (patch) | |
tree | 249b578b9fd7a79f7b52d4534a0e9ba4cc5b8cc9 /fs/afs/volume.c | |
parent | e7f680f45bd1deb4ca479c2348b395e1a4d44b17 (diff) |
afs: Implement VL server rotation
Track VL servers as independent entities rather than lumping all their
addresses together into one set and implement server-level rotation by:
(1) Add the concept of a VL server list, where each server has its own
separate address list. This code is similar to the FS server list.
(2) Use the DNS resolver to retrieve a set of servers and their associated
addresses, ports, preference and weight ratings.
(3) In the case of a legacy DNS resolver or an address list given directly
through /proc/net/afs/cells, create a list containing just a dummy
server record and attach all the addresses to that.
(4) Implement a simple rotation policy, for the moment ignoring the
priorities and weights assigned to the servers.
(5) Show the address list through /proc/net/afs/<cell>/vlservers. This
also displays the source and status of the data as indicated by the
upcall.
Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/afs/volume.c')
-rw-r--r-- | fs/afs/volume.c | 52 |
1 files changed, 16 insertions, 36 deletions
diff --git a/fs/afs/volume.c b/fs/afs/volume.c index 3037bd01f617..1cd263fa6028 100644 --- a/fs/afs/volume.c +++ b/fs/afs/volume.c @@ -74,55 +74,35 @@ static struct afs_vldb_entry *afs_vl_lookup_vldb(struct afs_cell *cell, const char *volname, size_t volnamesz) { - struct afs_addr_cursor ac; - struct afs_vldb_entry *vldb; + struct afs_vldb_entry *vldb = ERR_PTR(-EDESTADDRREQ); + struct afs_vl_cursor vc; int ret; - ret = afs_set_vl_cursor(&ac, cell); - if (ret < 0) - return ERR_PTR(ret); + if (!afs_begin_vlserver_operation(&vc, cell, key)) + return ERR_PTR(-ERESTARTSYS); - while (afs_iterate_addresses(&ac)) { - if (!test_bit(ac.index, &ac.alist->probed)) { - ret = afs_vl_get_capabilities(cell->net, &ac, key); + while (afs_select_vlserver(&vc)) { + if (!test_bit(vc.ac.index, &vc.ac.alist->probed)) { + ret = afs_vl_get_capabilities(cell->net, &vc.ac, key); switch (ret) { case VL_SERVICE: - clear_bit(ac.index, &ac.alist->yfs); - set_bit(ac.index, &ac.alist->probed); - ac.addr->srx_service = ret; + clear_bit(vc.ac.index, &vc.ac.alist->yfs); + set_bit(vc.ac.index, &vc.ac.alist->probed); + vc.ac.addr->srx_service = ret; break; case YFS_VL_SERVICE: - set_bit(ac.index, &ac.alist->yfs); - set_bit(ac.index, &ac.alist->probed); - ac.addr->srx_service = ret; + set_bit(vc.ac.index, &vc.ac.alist->yfs); + set_bit(vc.ac.index, &vc.ac.alist->probed); + vc.ac.addr->srx_service = ret; break; } } - vldb = afs_vl_get_entry_by_name_u(cell->net, &ac, key, - volname, volnamesz); - switch (ac.error) { - case 0: - afs_end_cursor(&ac); - return vldb; - case -ECONNABORTED: - ac.error = afs_abort_to_error(ac.abort_code); - goto error; - case -ENOMEM: - case -ENONET: - goto error; - case -ENETUNREACH: - case -EHOSTUNREACH: - case -ECONNREFUSED: - break; - default: - ac.error = -EIO; - goto error; - } + vldb = afs_vl_get_entry_by_name_u(&vc, volname, volnamesz); } -error: - return ERR_PTR(afs_end_cursor(&ac)); + ret = afs_end_vlserver_operation(&vc); + return ret < 0 ? ERR_PTR(ret) : vldb; } /* |