// SPDX-License-Identifier: GPL-2.0-or-later
/* Handle fileserver selection and rotation.
 *
 * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 */

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/sched/signal.h>
#include "internal.h"
#include "afs_fs.h"
#include "protocol_uae.h"

void afs_clear_server_states(struct afs_operation *op)
{
	unsigned int i;

	if (op->server_states) {
		for (i = 0; i < op->server_list->nr_servers; i++)
			afs_put_endpoint_state(op->server_states[i].endpoint_state,
					       afs_estate_trace_put_server_state);
		kfree(op->server_states);
	}
}

/*
 * Begin iteration through a server list, starting with the vnode's last used
 * server if possible, or the last recorded good server if not.
 */
static bool afs_start_fs_iteration(struct afs_operation *op,
				   struct afs_vnode *vnode)
{
	struct afs_server *server;
	void *cb_server;
	int i;

	trace_afs_rotate(op, afs_rotate_trace_start, 0);

	read_lock(&op->volume->servers_lock);
	op->server_list = afs_get_serverlist(
		rcu_dereference_protected(op->volume->servers,
					  lockdep_is_held(&op->volume->servers_lock)));
	read_unlock(&op->volume->servers_lock);

	op->server_states = kzalloc_objs(op->server_states[0],
					 op->server_list->nr_servers);
	if (!op->server_states) {
		afs_op_nomem(op);
		trace_afs_rotate(op, afs_rotate_trace_nomem, 0);
		return false;
	}

	rcu_read_lock();
	for (i = 0; i < op->server_list->nr_servers; i++) {
		struct afs_endpoint_state *estate;
		struct afs_server_state *s = &op->server_states[i];

		server = op->server_list->servers[i].server;
		estate = rcu_dereference(server->endpoint_state);
		s->endpoint_state = afs_get_endpoint_state(estate,
							   afs_estate_trace_get_server_state);
		s->probe_seq = estate->probe_seq;
		s->untried_addrs = (1UL << estate->addresses->nr_addrs) - 1;
		init_waitqueue_entry(&s->probe_waiter, current);
		afs_get_address_preferences(op->net, estate->addresses);
	}
	rcu_read_unlock();


	op->untried_servers = (1UL << op->server_list->nr_servers) - 1;
	op->server_index = -1;

	cb_server = vnode->cb_server;
	if (cb_server) {
		/* See if the vnode's preferred record is still available */
		for (i = 0; i < op->server_list->nr_servers; i++) {
			server = op->server_list->servers[i].server;
			if (server == cb_server) {
				op->server_index = i;
				goto found_interest;
			}
		}

		/* If we have a lock outstanding on a server that's no longer
		 * serving this vnode, then we can't switch to another server
		 * and have to return an error.
		 */
		if (op->flags & AFS_OPERATION_CUR_ONLY) {
			afs_op_set_error(op, -ESTALE);
			trace_afs_rotate(op, afs_rotate_trace_stale_lock, 0);
			return false;
		}

		/* Note that the callback promise is effectively broken */
		write_seqlock(&vnode->cb_lock);
		ASSERTCMP(cb_server, ==, vnode->cb_server);
		vnode->cb_server = NULL;
		if (afs_clear_cb_promise(vnode, afs_cb_promise_clear_rotate_server))
			vnode->cb_break++;
		write_sequnlock(&vnode->cb_lock);
	}

found_interest:
	return true;
}

/*
 * Post volume busy note.
 */
static void afs_busy(struct afs_operation *op, u32 abort_code)
{
	const char *m;

	switch (abort_code) {
	case VOFFLINE:		m = "offline";		break;
	case VRESTARTING:	m = "restarting";	break;
	case VSALVAGING:	m = "being salvaged";	break;
	default:		m = "busy";		break;
	}

	pr_notice("kAFS: Volume %llu '%s' on server %pU is %s\n",
		  op->volume->vid, op->volume->name, &op->server->uuid, m);
}

/*
 * Sleep and retry the operation to the same fileserver.
 */
static bool afs_sleep_and_retry(struct afs_operation *op)
{
	trace_afs_rotate(op, afs_rotate_trace_busy_sleep, 0);
	if (!(op->flags & AFS_OPERATION_UNINTR)) {
		msleep_interruptible(1000);
		if (signal_pending(current)) {
			afs_op_set_error(op, -ERESTARTSYS);
			return false;
		}
	} else {
		msleep(1000);
	}

	return true;
}

/*
 * Select the fileserver to use.  May be called multiple times to rotate
 * through the fileservers.
 */
bool afs_select_fileserver(struct afs_operation *op)
{
	struct afs_addr_list *alist;
	struct afs_server *server;
	struct afs_vnode *vnode = op->file[0].vnode;
	unsigned long set, failed;
	s32 abort_code = op->call_abort_code;
	int best_prio = 0;
	int error = op->call_error, addr_index, i, j;

	op->nr_iterations++;

	_enter("OP=%x+%x,%llx,%u{%lx},%u{%lx},%d,%d",
	       op->debug_id, op->nr_iterations, op->volume->vid,
	       op->server_index, op->untried_servers,
	       op->addr_index, op->addr_tried,
	       error, abort_code);

	if (op->flags & AFS_OPERATION_STOP) {
		trace_afs_rotate(op, afs_rotate_trace_stopped, 0);
		_leave(" = f [stopped]");
		return false;
	}

	if (op->nr_iterations == 0)
		goto start;

	WRITE_ONCE(op->estate->addresses->addrs[op->addr_index].last_error, error);
	trace_afs_rotate(op, afs_rotate_trace_iter, op->call_error);

	/* Evaluate the result of the previous operation, if there was one. */
	switch (op->call_error) {
	case 0:
		clear_bit(AFS_SE_VOLUME_OFFLINE,
			  &op->server_list->servers[op->server_index].flags);
		clear_bit(AFS_SE_VOLUME_BUSY,
			  &op->server_list->servers[op->server_index].flags);
		op->cumul_error.responded = true;

		/* We succeeded, but we may need to redo the op from another
		 * server if we're looking at a set of RO volumes where some of
		 * the servers have not yet been brought up to date lest we
		 * regress the data.  We only switch to the new version once
		 * >=50% of the servers are updated.
		 */
		error = afs_update_volume_state(op);
		if (error != 0) {
			if (error == 1) {
				afs_sleep_and_retry(op);
				goto restart_from_beginning;
			}
			afs_op_set_error(op, error);
			goto failed;
		}
		fallthrough;
	default:
		/* Success or local failure.  Stop. */
		afs_op_set_error(op, error);
		op->flags |= AFS_OPERATION_STOP;
		trace_afs_rotate(op, afs_rotate_trace_stop, error);
		_leave(" = f [okay/local %d]", error);
		return false;

	case -ECONNABORTED:
		/* The far side rejected the operation on some grounds.  This
		 * might involve the server being busy or the volume having been moved.
		 *
		 * Note that various V* errors should not be sent to a cache manager
		 * by a fileserver as they should be translated to more modern UAE*
		 * errors instead.  IBM AFS and OpenAFS fileservers, however, do leak
		 * these abort codes.
		 */
		trace_afs_rotate(op, afs_rotate_trace_aborted, abort_code);
		op->cumul_error.responded = true;
		switch (abort_code) {
		case VNOVOL:
			/* This fileserver doesn't know about the volume.
			 * - May indicate that the VL is wrong - retry once and compare
			 *   the results.
			 * - May indicate that the fileserver couldn't attach to the vol.
			 * - The volume might have been temporarily removed so that it can
			 *   be replaced by a volume restore.  "vos" might have ended one
			 *   transaction and has yet to create the next.
			 * - The volume might not be blessed or might not be in-service
			 *   (administrative action).
			 */
			if (op->flags & AFS_OPERATION_VNOVOL) {
				afs_op_accumulate_error(op, -EREMOTEIO, abort_code);
				goto next_server;
			}

			write_lock(&op->volume->servers_lock);
			op->server_list->vnovol_mask |= 1 << op->server_index;
			write_unlock(&op->volume->servers_lock);

			set_bit(AFS_VOLUME_NEEDS_UPDATE, &op->volume->flags);
			error = afs_check_volume_status(op->volume, op);
			if (error < 0) {
				afs_op_set_error(op, error);
				goto failed;
			}

			if (test_bit(AFS_VOLUME_DELETED, &op->volume->flags)) {
				afs_op_set_error(op, -ENOMEDIUM);
				goto failed;
			}

			/* If the server list didn't change, then assume that
			 * it's the fileserver having trouble.
			 */
			if (rcu_access_pointer(op->volume->servers) == op->server_list) {
				afs_op_accumulate_error(op, -EREMOTEIO, abort_code);
				goto next_server;
			}

			/* Try again */
			op->flags |= AFS_OPERATION_VNOVOL;
			_leave(" = t [vnovol]");
			return true;

		case VVOLEXISTS:
		case VONLINE:
			/* These should not be returned from the fileserver. */
			pr_warn("Fileserver returned unexpected abort %d\n",
				abort_code);
			afs_op_accumulate_error(op, -EREMOTEIO, abort_code);
			goto next_server;

		case VNOSERVICE:
			/* Prior to AFS 3.2 VNOSERVICE was returned from the fileserver
			 * if the volume was neither in-service nor administratively
			 * blessed.  All usage was replaced by VNOVOL because AFS 3.1 and
			 * earlier cache managers did not handle VNOSERVICE and assumed
			 * it was the client OSes errno 105.
			 *
			 * Starting with OpenAFS 1.4.8 VNOSERVICE was repurposed as the
			 * fileserver idle dead time error which was sent in place of
			 * RX_CALL_TIMEOUT (-3).  The error was intended to be sent if the
			 * fileserver took too long to send a reply to the client.
			 * RX_CALL_TIMEOUT would have caused the cache manager to mark the
			 * server down whereas VNOSERVICE since AFS 3.2 would cause cache
			 * manager to temporarily (up to 15 minutes) mark the volume
			 * instance as unusable.
			 *
			 * The idle dead logic resulted in cache inconsistency since a
			 * state changing call that the cache manager assumed was dead
			 * could still be processed to completion by the fileserver.  This
			 * logic was removed in OpenAFS 1.8.0 and VNOSERVICE is no longer
			 * returned.  However, many 1.4.8 through 1.6.24 fileservers are
			 * still in existence.
			 *
			 * AuriStorFS fileservers have never returned VNOSERVICE.
			 *
			 * VNOSERVICE should be treated as an alias for RX_CALL_TIMEOUT.
			 */
		case RX_CALL_TIMEOUT:
			afs_op_accumulate_error(op, -ETIMEDOUT, abort_code);
			goto next_server;

		case VSALVAGING: /* This error should not be leaked to cache managers
				  * but is from OpenAFS demand attach fileservers.
				  * It should be treated as an alias for VOFFLINE.
				  */
		case VSALVAGE: /* VSALVAGE should be treated as a synonym of VOFFLINE */
		case VOFFLINE:
			/* The volume is in use by the volserver or another volume utility
			 * for an operation that might alter the contents.  The volume is
			 * expected to come back but it might take a long time (could be
			 * days).
			 */
			if (!test_and_set_bit(AFS_SE_VOLUME_OFFLINE,
					      &op->server_list->servers[op->server_index].flags)) {
				afs_busy(op, abort_code);
				clear_bit(AFS_SE_VOLUME_BUSY,
					  &op->server_list->servers[op->server_index].flags);
			}
			if (op->flags & AFS_OPERATION_NO_VSLEEP) {
				afs_op_set_error(op, -EADV);
				goto failed;
			}
			goto busy;

		case VRESTARTING: /* The fileserver is either shutting down or starting up. */
		case VBUSY:
			/* The volume is in use by the volserver or another volume
			 * utility for an operation that is not expected to alter the
			 * contents of the volume.  VBUSY does not need to be returned
			 * for a ROVOL or BACKVOL bound to an ITBusy volserver
			 * transaction.  The fileserver is permitted to continue serving
			 * content from ROVOLs and BACKVOLs during an ITBusy transaction
			 * because the content will not change.  However, many fileserver
			 * releases do return VBUSY for ROVOL and BACKVOL instances under
			 * many circumstances.
			 *
			 * Retry after going round all the servers unless we have a file
			 * lock we need to maintain.
			 */
			if (op->flags & AFS_OPERATION_NO_VSLEEP) {
				afs_op_set_error(op, -EBUSY);
				goto failed;
			}
			if (!test_and_set_bit(AFS_SE_VOLUME_BUSY,
					      &op->server_list->servers[op->server_index].flags)) {
				afs_busy(op, abort_code);
				clear_bit(AFS_SE_VOLUME_OFFLINE,
					  &op->server_list->servers[op->server_index].flags);
			}
		busy:
			if (op->flags & AFS_OPERATION_CUR_ONLY) {
				if (!afs_sleep_and_retry(op))
					goto failed;

				/* Retry with same server & address */
				_leave(" = t [vbusy]");
				return true;
			}

			op->flags |= AFS_OPERATION_VBUSY;
			goto next_server;

		case VMOVED:
			/* The volume migrated to another server.  We consider
			 * consider all locks and callbacks broken and request
			 * an update from the VLDB.
			 *
			 * We also limit the number of VMOVED hops we will
			 * honour, just in case someone sets up a loop.
			 */
			if (op->flags & AFS_OPERATION_VMOVED) {
				afs_op_set_error(op, -EREMOTEIO);
				goto failed;
			}
			op->flags |= AFS_OPERATION_VMOVED;

			set_bit(AFS_VOLUME_WAIT, &op->volume->flags);
			set_bit(AFS_VOLUME_NEEDS_UPDATE, &op->volume->flags);
			error = afs_check_volume_status(op->volume, op);
			if (error < 0) {
				afs_op_set_error(op, error);
				goto failed;
			}

			/* If the server list didn't change, then the VLDB is
			 * out of sync with the fileservers.  This is hopefully
			 * a temporary condition, however, so we don't want to
			 * permanently block access to the file.
			 *
			 * TODO: Try other fileservers if we can.
			 *
			 * TODO: Retry a few times with sleeps.
			 */
			if (rcu_access_pointer(op->volume->servers) == op->server_list) {
				afs_op_accumulate_error(op, -ENOMEDIUM, abort_code);
				goto failed;
			}

			goto restart_from_beginning;

		case UAEIO:
		case VIO:
			afs_op_accumulate_error(op, -EREMOTEIO, abort_code);
			if (op->volume->type != AFSVL_RWVOL)
				goto next_server;
			goto failed;

		case VDISKFULL:
		case UAENOSPC:
			/* The partition is full.  Only applies to RWVOLs.
			 * Translate locally and return ENOSPC.
			 * No replicas to failover to.
			 */
			afs_op_set_error(op, -ENOSPC);
			goto failed_but_online;

		case VOVERQUOTA:
		case UAEDQUOT:
			/* Volume is full.  Only applies to RWVOLs.
			 * Translate locally and return EDQUOT.
			 * No replicas to failover to.
			 */
			afs_op_set_error(op, -EDQUOT);
			goto failed_but_online;

		case RX_INVALID_OPERATION:
		case RXGEN_OPCODE:
			/* Handle downgrading to an older operation. */
			afs_op_set_error(op, -ENOTSUPP);
			if (op->flags & AFS_OPERATION_DOWNGRADE) {
				op->flags &= ~AFS_OPERATION_DOWNGRADE;
				goto go_again;
			}
			goto failed_but_online;

		default:
			afs_op_accumulate_error(op, error, abort_code);
		failed_but_online:
			clear_bit(AFS_SE_VOLUME_OFFLINE,
				  &op->server_list->servers[op->server_index].flags);
			clear_bit(AFS_SE_VOLUME_BUSY,
				  &op->server_list->servers[op->server_index].flags);
			goto failed;
		}

	case -ETIMEDOUT:
	case -ETIME:
		if (afs_op_error(op) != -EDESTADDRREQ)
			goto iterate_address;
		fallthrough;
	case -ERFKILL:
	case -EADDRNOTAVAIL:
	case -ENETUNREACH:
	case -EHOSTUNREACH:
	case -EHOSTDOWN:
	case -ECONNREFUSED:
		_debug("no conn");
		afs_op_accumulate_error(op, error, 0);
		goto iterate_address;

	case -ENETRESET:
		pr_warn("kAFS: Peer reset %s (op=%x)\n",
			op->type ? op->type->name : "???", op->debug_id);
		fallthrough;
	case -ECONNRESET:
		_debug("call reset");
		afs_op_set_error(op, error);
		goto failed;
	}

restart_from_beginning:
	trace_afs_rotate(op, afs_rotate_trace_restart, 0);
	_debug("restart");
	op->estate = NULL;
	op->server = NULL;
	afs_clear_server_states(op);
	op->server_states = NULL;
	afs_put_serverlist(op->net, op->server_list);
	op->server_list = NULL;
start:
	_debug("start");
	ASSERTCMP(op->estate, ==, NULL);
	/* See if we need to do an update of the volume record.  Note that the
	 * volume may have moved or even have been deleted.
	 */
	error = afs_check_volume_status(op->volume, op);
	trace_afs_rotate(op, afs_rotate_trace_check_vol_status, error);
	if (error < 0) {
		afs_op_set_error(op, error);
		goto failed;
	}

	if (!afs_start_fs_iteration(op, vnode))
		goto failed;

	_debug("__ VOL %llx __", op->volume->vid);

pick_server:
	_debug("pick [%lx]", op->untried_servers);
	ASSERTCMP(op->estate, ==, NULL);

	error = afs_wait_for_fs_probes(op, op->server_states,
				       !(op->flags & AFS_OPERATION_UNINTR));
	switch (error) {
	case 0: /* No untried responsive servers and no outstanding probes */
		trace_afs_rotate(op, afs_rotate_trace_probe_none, 0);
		goto no_more_servers;
	case 1: /* Got a response */
		trace_afs_rotate(op, afs_rotate_trace_probe_response, 0);
		break;
	case 2: /* Probe data superseded */
		trace_afs_rotate(op, afs_rotate_trace_probe_superseded, 0);
		goto restart_from_beginning;
	default:
		trace_afs_rotate(op, afs_rotate_trace_probe_error, error);
		afs_op_set_error(op, error);
		goto failed;
	}

	/* Pick the untried server with the highest priority untried endpoint.
	 * If we have outstanding callbacks, we stick with the server we're
	 * already using if we can.
	 */
	if (op->server) {
		_debug("server %u", op->server_index);
		if (test_bit(op->server_index, &op->untried_servers))
			goto selected_server;
		op->server = NULL;
		_debug("no server");
	}

	rcu_read_lock();
	op->server_index = -1;
	best_prio = -1;
	for (i = 0; i < op->server_list->nr_servers; i++) {
		struct afs_endpoint_state *es;
		struct afs_server_entry *se = &op->server_list->servers[i];
		struct afs_addr_list *sal;
		struct afs_server *s = se->server;

		if (!test_bit(i, &op->untried_servers) ||
		    test_bit(AFS_SE_EXCLUDED, &se->flags) ||
		    !test_bit(AFS_SERVER_FL_RESPONDING, &s->flags))
			continue;
		es = op->server_states[i].endpoint_state;
		sal = es->addresses;

		afs_get_address_preferences_rcu(op->net, sal);
		for (j = 0; j < sal->nr_addrs; j++) {
			if (es->failed_set & (1 << j))
				continue;
			if (!sal->addrs[j].peer)
				continue;
			if (sal->addrs[j].prio > best_prio) {
				op->server_index = i;
				best_prio = sal->addrs[j].prio;
			}
		}
	}
	rcu_read_unlock();

	if (op->server_index == -1)
		goto no_more_servers;

selected_server:
	trace_afs_rotate(op, afs_rotate_trace_selected_server, best_prio);
	_debug("use %d prio %u", op->server_index, best_prio);
	__clear_bit(op->server_index, &op->untried_servers);

	/* We're starting on a different fileserver from the list.  We need to
	 * check it, create a callback intercept, find its address list and
	 * probe its capabilities before we use it.
	 */
	ASSERTCMP(op->estate, ==, NULL);
	server = op->server_list->servers[op->server_index].server;

	if (!afs_check_server_record(op, server, op->key))
		goto failed;

	_debug("USING SERVER: %pU", &server->uuid);

	op->flags |= AFS_OPERATION_RETRY_SERVER;
	op->server = server;
	if (vnode->cb_server != server) {
		vnode->cb_server = server;
		vnode->cb_v_check = atomic_read(&vnode->volume->cb_v_break);
		afs_clear_cb_promise(vnode, afs_cb_promise_clear_server_change);
	}

retry_server:
	op->addr_tried = 0;
	op->addr_index = -1;

iterate_address:
	/* Iterate over the current server's address list to try and find an
	 * address on which it will respond to us.
	 */
	op->estate = op->server_states[op->server_index].endpoint_state;
	set = READ_ONCE(op->estate->responsive_set);
	failed = READ_ONCE(op->estate->failed_set);
	_debug("iterate ES=%x rs=%lx fs=%lx", op->estate->probe_seq, set, failed);
	set &= ~(failed | op->addr_tried);
	trace_afs_rotate(op, afs_rotate_trace_iterate_addr, set);
	if (!set)
		goto wait_for_more_probe_results;

	alist = op->estate->addresses;
	best_prio = -1;
	addr_index = 0;
	for (i = 0; i < alist->nr_addrs; i++) {
		if (!(set & (1 << i)))
			continue;
		if (alist->addrs[i].prio > best_prio) {
			addr_index = i;
			best_prio = alist->addrs[i].prio;
		}
	}

	alist->preferred = addr_index;

	op->addr_index = addr_index;
	set_bit(addr_index, &op->addr_tried);

	_debug("address [%u] %u/%u %pISp",
	       op->server_index, addr_index, alist->nr_addrs,
	       rxrpc_kernel_remote_addr(alist->addrs[op->addr_index].peer));
go_again:
	op->volsync.creation = TIME64_MIN;
	op->volsync.update = TIME64_MIN;
	op->call_responded = false;
	_leave(" = t");
	return true;

wait_for_more_probe_results:
	error = afs_wait_for_one_fs_probe(op->server, op->estate, op->addr_tried,
					  !(op->flags & AFS_OPERATION_UNINTR));
	if (error == 1)
		goto iterate_address;
	if (!error)
		goto restart_from_beginning;

	/* We've now had a failure to respond on all of a server's addresses -
	 * immediately probe them again and consider retrying the server.
	 */
	trace_afs_rotate(op, afs_rotate_trace_probe_fileserver, 0);
	afs_probe_fileserver(op->net, op->server);
	if (op->flags & AFS_OPERATION_RETRY_SERVER) {
		error = afs_wait_for_one_fs_probe(op->server, op->estate, op->addr_tried,
						  !(op->flags & AFS_OPERATION_UNINTR));
		switch (error) {
		case 1:
			op->flags &= ~AFS_OPERATION_RETRY_SERVER;
			trace_afs_rotate(op, afs_rotate_trace_retry_server, 1);
			goto retry_server;
		case 0:
			trace_afs_rotate(op, afs_rotate_trace_retry_server, 0);
			goto restart_from_beginning;
		case -ERESTARTSYS:
			afs_op_set_error(op, error);
			goto failed;
		case -ETIME:
		case -EDESTADDRREQ:
			goto next_server;
		}
	}

next_server:
	trace_afs_rotate(op, afs_rotate_trace_next_server, 0);
	_debug("next");
	op->estate = NULL;
	goto pick_server;

no_more_servers:
	/* That's all the servers poked to no good effect.  Try again if some
	 * of them were busy.
	 */
	trace_afs_rotate(op, afs_rotate_trace_no_more_servers, 0);
	if (op->flags & AFS_OPERATION_VBUSY) {
		afs_sleep_and_retry(op);
		op->flags &= ~AFS_OPERATION_VBUSY;
		goto restart_from_beginning;
	}

	rcu_read_lock();
	for (i = 0; i < op->server_list->nr_servers; i++) {
		struct afs_endpoint_state *estate;

		estate = op->server_states[i].endpoint_state;
		error = READ_ONCE(estate->error);
		if (error < 0)
			afs_op_accumulate_error(op, error, estate->abort_code);
	}
	rcu_read_unlock();

failed:
	trace_afs_rotate(op, afs_rotate_trace_failed, 0);
	op->flags |= AFS_OPERATION_STOP;
	op->estate = NULL;
	_leave(" = f [failed %d]", afs_op_error(op));
	return false;
}

/*
 * Dump cursor state in the case of the error being EDESTADDRREQ.
 */
void afs_dump_edestaddrreq(const struct afs_operation *op)
{
	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("OP: cbb=%x cbb2=%x fl=%x err=%hd\n",
		  op->file[0].cb_break_before,
		  op->file[1].cb_break_before, op->flags, op->cumul_error.error);
	pr_notice("OP: ut=%lx ix=%d ni=%u\n",
		  op->untried_servers, op->server_index, op->nr_iterations);
	pr_notice("OP: call  er=%d ac=%d r=%u\n",
		  op->call_error, op->call_abort_code, op->call_responded);

	if (op->server_list) {
		const struct afs_server_list *sl = op->server_list;

		pr_notice("FC: SL nr=%u vnov=%hx\n",
			  sl->nr_servers, sl->vnovol_mask);
		for (i = 0; i < sl->nr_servers; i++) {
			const struct afs_server *s = sl->servers[i].server;
			const struct afs_endpoint_state *e =
				rcu_dereference(s->endpoint_state);
			const struct afs_addr_list *a = e->addresses;

			pr_notice("FC: server fl=%lx av=%u %pU\n",
				  s->flags, s->addr_version, &s->uuid);
			pr_notice("FC:  - pq=%x R=%lx F=%lx\n",
				  e->probe_seq, e->responsive_set, e->failed_set);
			if (a) {
				pr_notice("FC:  - av=%u nr=%u/%u/%u pr=%u\n",
					  a->version,
					  a->nr_ipv4, a->nr_addrs, a->max_addrs,
					  a->preferred);
				if (a == e->addresses)
					pr_notice("FC:  - current\n");
			}
		}
	}

	pr_notice("AC: t=%lx ax=%d\n", op->addr_tried, op->addr_index);
	rcu_read_unlock();
}
