// 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 = kcalloc(op->server_list->nr_servers, sizeof(op->server_states[0]),
				    GFP_KERNEL);
	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 (atomic64_xchg(&vnode->cb_expires_at, AFS_NO_CB_PROMISE) != AFS_NO_CB_PROMISE)
			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;

		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);
		atomic64_set(&vnode->cb_expires_at, AFS_NO_CB_PROMISE);
	}

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);

	op->volsync.creation = TIME64_MIN;
	op->volsync.update = TIME64_MIN;
	op->call_responded = false;
	_debug("address [%u] %u/%u %pISp",
	       op->server_index, addr_index, alist->nr_addrs,
	       rxrpc_kernel_remote_addr(alist->addrs[op->addr_index].peer));
	_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();
}
