summaryrefslogtreecommitdiff
path: root/fs/afs/vl_rotate.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/afs/vl_rotate.c')
-rw-r--r--fs/afs/vl_rotate.c53
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);