diff options
author | David Howells <dhowells@redhat.com> | 2018-10-20 01:57:59 +0200 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2018-10-24 01:41:09 +0200 |
commit | 3bf0fb6f33dd545693da5e65f5b1b9b9f0bfc35e (patch) | |
tree | df215e6a6ad11b6ac8158461144667e168591d28 /fs/afs/fsclient.c | |
parent | afs: Fix callback handling (diff) | |
download | linux-3bf0fb6f33dd545693da5e65f5b1b9b9f0bfc35e.tar.xz 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/fsclient.c')
-rw-r--r-- | fs/afs/fsclient.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c index 7c75a1813321..ca08c83168f5 100644 --- a/fs/afs/fsclient.c +++ b/fs/afs/fsclient.c @@ -2006,7 +2006,6 @@ int afs_fs_give_up_all_callbacks(struct afs_net *net, */ static int afs_deliver_fs_get_capabilities(struct afs_call *call) { - struct afs_server *server = call->reply[0]; u32 count; int ret; @@ -2042,15 +2041,18 @@ static int afs_deliver_fs_get_capabilities(struct afs_call *call) break; } - if (call->service_id == YFS_FS_SERVICE) - set_bit(AFS_SERVER_FL_IS_YFS, &server->flags); - else - clear_bit(AFS_SERVER_FL_IS_YFS, &server->flags); - _leave(" = 0 [done]"); return 0; } +static void afs_destroy_fs_get_capabilities(struct afs_call *call) +{ + struct afs_server *server = call->reply[0]; + + afs_put_server(call->net, server); + afs_flat_call_destructor(call); +} + /* * FS.GetCapabilities operation type */ @@ -2058,7 +2060,8 @@ static const struct afs_call_type afs_RXFSGetCapabilities = { .name = "FS.GetCapabilities", .op = afs_FS_GetCapabilities, .deliver = afs_deliver_fs_get_capabilities, - .destructor = afs_flat_call_destructor, + .done = afs_fileserver_probe_result, + .destructor = afs_destroy_fs_get_capabilities, }; /* @@ -2068,7 +2071,9 @@ static const struct afs_call_type afs_RXFSGetCapabilities = { int afs_fs_get_capabilities(struct afs_net *net, struct afs_server *server, struct afs_addr_cursor *ac, - struct key *key) + struct key *key, + unsigned int server_index, + bool async) { struct afs_call *call; __be32 *bp; @@ -2080,8 +2085,10 @@ int afs_fs_get_capabilities(struct afs_net *net, return -ENOMEM; call->key = key; - call->reply[0] = server; + call->reply[0] = afs_get_server(server); + call->reply[1] = (void *)(long)server_index; call->upgrade = true; + call->want_reply_time = true; /* marshall the parameters */ bp = call->request; @@ -2089,7 +2096,7 @@ int afs_fs_get_capabilities(struct afs_net *net, /* Can't take a ref on server */ trace_afs_make_fs_call(call, NULL); - return afs_make_call(ac, call, GFP_NOFS, false); + return afs_make_call(ac, call, GFP_NOFS, async); } /* |