diff options
author | David Howells <dhowells@redhat.com> | 2018-10-20 00:57:58 +0100 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2018-10-24 00:41:09 +0100 |
commit | 744bcd713a4eabb248246f7deccfad30c579b7f5 (patch) | |
tree | 60470fca4f54503cb844f02d12f25a4c67529972 /fs/afs/vl_rotate.c | |
parent | 30062bd13e3659a309d249a06d5f4ebb4a5c5251 (diff) |
afs: Allow dumping of server cursor on operation failure
Provide an option to allow the file or volume location server cursor to be
dumped if the rotation routine falls off the end without managing to
contact a server.
Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/afs/vl_rotate.c')
-rw-r--r-- | fs/afs/vl_rotate.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/fs/afs/vl_rotate.c b/fs/afs/vl_rotate.c index 44a936ad9c7a..5b99ea7be194 100644 --- a/fs/afs/vl_rotate.c +++ b/fs/afs/vl_rotate.c @@ -83,6 +83,8 @@ bool afs_select_vlserver(struct afs_vl_cursor *vc) return false; } + vc->nr_iterations++; + /* Evaluate the result of the previous operation, if there was one. */ switch (error) { case SHRT_MAX: @@ -235,12 +237,63 @@ failed: } /* + * Dump cursor state in the case of the error being EDESTADDRREQ. + */ +static void afs_vl_dump_edestaddrreq(const struct afs_vl_cursor *vc) +{ + static int count; + int i; + + if (!IS_ENABLED(CONFIG_AFS_DEBUG_CURSOR) || count > 3) + return; + count++; + + rcu_read_lock(); + pr_notice("EDESTADDR occurred\n"); + pr_notice("VC: st=%u ix=%u ni=%hu fl=%hx err=%hd\n", + vc->start, vc->index, vc->nr_iterations, vc->flags, vc->error); + + if (vc->server_list) { + const struct afs_vlserver_list *sl = vc->server_list; + pr_notice("VC: SL nr=%u ix=%u\n", + sl->nr_servers, sl->index); + for (i = 0; i < sl->nr_servers; i++) { + const struct afs_vlserver *s = sl->servers[i].server; + pr_notice("VC: server fl=%lx %s+%hu\n", + s->flags, s->name, s->port); + if (s->addresses) { + const struct afs_addr_list *a = + rcu_dereference(s->addresses); + pr_notice("VC: - av=%u nr=%u/%u/%u ax=%u\n", + a->version, + a->nr_ipv4, a->nr_addrs, a->max_addrs, + a->index); + pr_notice("VC: - pr=%lx yf=%lx\n", + a->probed, a->yfs); + if (a == vc->ac.alist) + pr_notice("VC: - current\n"); + } + } + } + + pr_notice("AC: as=%u ax=%u ac=%d er=%d b=%u r=%u ni=%hu\n", + vc->ac.start, vc->ac.index, vc->ac.abort_code, vc->ac.error, + vc->ac.begun, vc->ac.responded, vc->ac.nr_iterations); + rcu_read_unlock(); +} + +/* * Tidy up a volume location server cursor and unlock the vnode. */ int afs_end_vlserver_operation(struct afs_vl_cursor *vc) { struct afs_net *net = vc->cell->net; + if (vc->error == -EDESTADDRREQ || + vc->error == -ENETUNREACH || + vc->error == -EHOSTUNREACH) + afs_vl_dump_edestaddrreq(vc); + afs_end_cursor(&vc->ac); afs_put_vlserverlist(net, vc->server_list); |