// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright 2023 Red Hat
 */

/**
 * DOC:
 *
 * Hash Locks:
 *
 * A hash_lock controls and coordinates writing, index access, and dedupe among groups of data_vios
 * concurrently writing identical blocks, allowing them to deduplicate not only against advice but
 * also against each other. This saves on index queries and allows those data_vios to concurrently
 * deduplicate against a single block instead of being serialized through a PBN read lock. Only one
 * index query is needed for each hash_lock, instead of one for every data_vio.
 *
 * Hash_locks are assigned to hash_zones by computing a modulus on the hash itself. Each hash_zone
 * has a single dedicated queue and thread for performing all operations on the hash_locks assigned
 * to that zone. The concurrency guarantees of this single-threaded model allow the code to omit
 * more fine-grained locking for the hash_lock structures.
 *
 * A hash_lock acts like a state machine perhaps more than as a lock. Other than the starting and
 * ending states INITIALIZING and BYPASSING, every state represents and is held for the duration of
 * an asynchronous operation. All state transitions are performed on the thread of the hash_zone
 * containing the lock. An asynchronous operation is almost always performed upon entering a state,
 * and the callback from that operation triggers exiting the state and entering a new state.
 *
 * In all states except DEDUPING, there is a single data_vio, called the lock agent, performing the
 * asynchronous operations on behalf of the lock. The agent will change during the lifetime of the
 * lock if the lock is shared by more than one data_vio. data_vios waiting to deduplicate are kept
 * on a wait queue. Viewed a different way, the agent holds the lock exclusively until the lock
 * enters the DEDUPING state, at which point it becomes a shared lock that all the waiters (and any
 * new data_vios that arrive) use to share a PBN lock. In state DEDUPING, there is no agent. When
 * the last data_vio in the lock calls back in DEDUPING, it becomes the agent and the lock becomes
 * exclusive again. New data_vios that arrive in the lock will also go on the wait queue.
 *
 * The existence of lock waiters is a key factor controlling which state the lock transitions to
 * next. When the lock is new or has waiters, it will always try to reach DEDUPING, and when it
 * doesn't, it will try to clean up and exit.
 *
 * Deduping requires holding a PBN lock on a block that is known to contain data identical to the
 * data_vios in the lock, so the lock will send the agent to the duplicate zone to acquire the PBN
 * lock (LOCKING), to the kernel I/O threads to read and verify the data (VERIFYING), or to write a
 * new copy of the data to a full data block or a slot in a compressed block (WRITING).
 *
 * Cleaning up consists of updating the index when the data location is different from the initial
 * index query (UPDATING, triggered by stale advice, compression, and rollover), releasing the PBN
 * lock on the duplicate block (UNLOCKING), and if the agent is the last data_vio referencing the
 * lock, releasing the hash_lock itself back to the hash zone (BYPASSING).
 *
 * The shortest sequence of states is for non-concurrent writes of new data:
 *   INITIALIZING -> QUERYING -> WRITING -> BYPASSING
 * This sequence is short because no PBN read lock or index update is needed.
 *
 * Non-concurrent, finding valid advice looks like this (endpoints elided):
 *   -> QUERYING -> LOCKING -> VERIFYING -> DEDUPING -> UNLOCKING ->
 * Or with stale advice (endpoints elided):
 *   -> QUERYING -> LOCKING -> VERIFYING -> UNLOCKING -> WRITING -> UPDATING ->
 *
 * When there are not enough available reference count increments available on a PBN for a data_vio
 * to deduplicate, a new lock is forked and the excess waiters roll over to the new lock (which
 * goes directly to WRITING). The new lock takes the place of the old lock in the lock map so new
 * data_vios will be directed to it. The two locks will proceed independently, but only the new
 * lock will have the right to update the index (unless it also forks).
 *
 * Since rollover happens in a lock instance, once a valid data location has been selected, it will
 * not change. QUERYING and WRITING are only performed once per lock lifetime. All other
 * non-endpoint states can be re-entered.
 *
 * The function names in this module follow a convention referencing the states and transitions in
 * the state machine. For example, for the LOCKING state, there are start_locking() and
 * finish_locking() functions.  start_locking() is invoked by the finish function of the state (or
 * states) that transition to LOCKING. It performs the actual lock state change and must be invoked
 * on the hash zone thread.  finish_locking() is called by (or continued via callback from) the
 * code actually obtaining the lock. It does any bookkeeping or decision-making required and
 * invokes the appropriate start function of the state being transitioned to after LOCKING.
 *
 * ----------------------------------------------------------------------
 *
 * Index Queries:
 *
 * A query to the UDS index is handled asynchronously by the index's threads. When the query is
 * complete, a callback supplied with the query will be called from one of the those threads. Under
 * heavy system load, the index may be slower to respond than is desirable for reasonable I/O
 * throughput. Since deduplication of writes is not necessary for correct operation of a VDO
 * device, it is acceptable to timeout out slow index queries and proceed to fulfill a write
 * request without deduplicating. However, because the uds_request struct itself is supplied by the
 * caller, we can not simply reuse a uds_request object which we have chosen to timeout. Hence,
 * each hash_zone maintains a pool of dedupe_contexts which each contain a uds_request along with a
 * reference to the data_vio on behalf of which they are performing a query.
 *
 * When a hash_lock needs to query the index, it attempts to acquire an unused dedupe_context from
 * its hash_zone's pool. If one is available, that context is prepared, associated with the
 * hash_lock's agent, added to the list of pending contexts, and then sent to the index. The
 * context's state will be transitioned from DEDUPE_CONTEXT_IDLE to DEDUPE_CONTEXT_PENDING. If all
 * goes well, the dedupe callback will be called by the index which will change the context's state
 * to DEDUPE_CONTEXT_COMPLETE, and the associated data_vio will be enqueued to run back in the hash
 * zone where the query results will be processed and the context will be put back in the idle
 * state and returned to the hash_zone's available list.
 *
 * The first time an index query is launched from a given hash_zone, a timer is started. When the
 * timer fires, the hash_zone's completion is enqueued to run in the hash_zone where the zone's
 * pending list will be searched for any contexts in the pending state which have been running for
 * too long. Those contexts are transitioned to the DEDUPE_CONTEXT_TIMED_OUT state and moved to the
 * zone's timed_out list where they won't be examined again if there is a subsequent time out). The
 * data_vios associated with timed out contexts are sent to continue processing their write
 * operation without deduplicating. The timer is also restarted.
 *
 * When the dedupe callback is run for a context which is in the timed out state, that context is
 * moved to the DEDUPE_CONTEXT_TIMED_OUT_COMPLETE state. No other action need be taken as the
 * associated data_vios have already been dispatched.
 *
 * If a hash_lock needs a dedupe context, and the available list is empty, the timed_out list will
 * be searched for any contexts which are timed out and complete. One of these will be used
 * immediately, and the rest will be returned to the available list and marked idle.
 */

#include "dedupe.h"

#include <linux/atomic.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/ratelimit.h>
#include <linux/spinlock.h>
#include <linux/timer.h>

#include "logger.h"
#include "memory-alloc.h"
#include "numeric.h"
#include "permassert.h"
#include "string-utils.h"

#include "indexer.h"

#include "action-manager.h"
#include "admin-state.h"
#include "completion.h"
#include "constants.h"
#include "data-vio.h"
#include "int-map.h"
#include "io-submitter.h"
#include "packer.h"
#include "physical-zone.h"
#include "slab-depot.h"
#include "statistics.h"
#include "types.h"
#include "vdo.h"
#include "wait-queue.h"

#define DEDUPE_QUERY_TIMER_IDLE 0
#define DEDUPE_QUERY_TIMER_RUNNING 1
#define DEDUPE_QUERY_TIMER_FIRED 2

enum dedupe_context_state {
	DEDUPE_CONTEXT_IDLE,
	DEDUPE_CONTEXT_PENDING,
	DEDUPE_CONTEXT_TIMED_OUT,
	DEDUPE_CONTEXT_COMPLETE,
	DEDUPE_CONTEXT_TIMED_OUT_COMPLETE,
};

/* Possible index states: closed, opened, or transitioning between those two. */
enum index_state {
	IS_CLOSED,
	IS_CHANGING,
	IS_OPENED,
};

static const char *CLOSED = "closed";
static const char *CLOSING = "closing";
static const char *ERROR = "error";
static const char *OFFLINE = "offline";
static const char *ONLINE = "online";
static const char *OPENING = "opening";
static const char *SUSPENDED = "suspended";
static const char *UNKNOWN = "unknown";

/* Version 2 uses the kernel space UDS index and is limited to 16 bytes */
#define UDS_ADVICE_VERSION 2
/* version byte + state byte + 64-bit little-endian PBN */
#define UDS_ADVICE_SIZE (1 + 1 + sizeof(u64))

enum hash_lock_state {
	/* State for locks that are not in use or are being initialized. */
	VDO_HASH_LOCK_INITIALIZING,

	/* This is the sequence of states typically used on the non-dedupe path. */
	VDO_HASH_LOCK_QUERYING,
	VDO_HASH_LOCK_WRITING,
	VDO_HASH_LOCK_UPDATING,

	/* The remaining states are typically used on the dedupe path in this order. */
	VDO_HASH_LOCK_LOCKING,
	VDO_HASH_LOCK_VERIFYING,
	VDO_HASH_LOCK_DEDUPING,
	VDO_HASH_LOCK_UNLOCKING,

	/*
	 * Terminal state for locks returning to the pool. Must be last both because it's the final
	 * state, and also because it's used to count the states.
	 */
	VDO_HASH_LOCK_BYPASSING,
};

static const char * const LOCK_STATE_NAMES[] = {
	[VDO_HASH_LOCK_BYPASSING] = "BYPASSING",
	[VDO_HASH_LOCK_DEDUPING] = "DEDUPING",
	[VDO_HASH_LOCK_INITIALIZING] = "INITIALIZING",
	[VDO_HASH_LOCK_LOCKING] = "LOCKING",
	[VDO_HASH_LOCK_QUERYING] = "QUERYING",
	[VDO_HASH_LOCK_UNLOCKING] = "UNLOCKING",
	[VDO_HASH_LOCK_UPDATING] = "UPDATING",
	[VDO_HASH_LOCK_VERIFYING] = "VERIFYING",
	[VDO_HASH_LOCK_WRITING] = "WRITING",
};

struct hash_lock {
	/* The block hash covered by this lock */
	struct uds_record_name hash;

	/* When the lock is unused, this list entry allows the lock to be pooled */
	struct list_head pool_node;

	/*
	 * A list containing the data VIOs sharing this lock, all having the same record name and
	 * data block contents, linked by their hash_lock_node fields.
	 */
	struct list_head duplicate_vios;

	/* The number of data_vios sharing this lock instance */
	data_vio_count_t reference_count;

	/* The maximum value of reference_count in the lifetime of this lock */
	data_vio_count_t max_references;

	/* The current state of this lock */
	enum hash_lock_state state;

	/* True if the UDS index should be updated with new advice */
	bool update_advice;

	/* True if the advice has been verified to be a true duplicate */
	bool verified;

	/* True if the lock has already accounted for an initial verification */
	bool verify_counted;

	/* True if this lock is registered in the lock map (cleared on rollover) */
	bool registered;

	/*
	 * If verified is false, this is the location of a possible duplicate. If verified is true,
	 * it is the verified location of a true duplicate.
	 */
	struct zoned_pbn duplicate;

	/* The PBN lock on the block containing the duplicate data */
	struct pbn_lock *duplicate_lock;

	/* The data_vio designated to act on behalf of the lock */
	struct data_vio *agent;

	/*
	 * Other data_vios with data identical to the agent who are currently waiting for the agent
	 * to get the information they all need to deduplicate--either against each other, or
	 * against an existing duplicate on disk.
	 */
	struct vdo_wait_queue waiters;
};

#define LOCK_POOL_CAPACITY MAXIMUM_VDO_USER_VIOS

struct hash_zones {
	struct action_manager *manager;
	struct uds_parameters parameters;
	struct uds_index_session *index_session;
	struct ratelimit_state ratelimiter;
	atomic64_t timeouts;
	atomic64_t dedupe_context_busy;

	/* This spinlock protects the state fields and the starting of dedupe requests. */
	spinlock_t lock;

	/* The fields in the next block are all protected by the lock */
	struct vdo_completion completion;
	enum index_state index_state;
	enum index_state index_target;
	struct admin_state state;
	bool changing;
	bool create_flag;
	bool dedupe_flag;
	bool error_flag;
	u64 reported_timeouts;

	/* The number of zones */
	zone_count_t zone_count;
	/* The hash zones themselves */
	struct hash_zone zones[] __counted_by(zone_count);
};

/* These are in milliseconds. */
unsigned int vdo_dedupe_index_timeout_interval = 5000;
unsigned int vdo_dedupe_index_min_timer_interval = 100;
/* Same two variables, in jiffies for easier consumption. */
static u64 vdo_dedupe_index_timeout_jiffies;
static u64 vdo_dedupe_index_min_timer_jiffies;

static inline struct hash_zone *as_hash_zone(struct vdo_completion *completion)
{
	vdo_assert_completion_type(completion, VDO_HASH_ZONE_COMPLETION);
	return container_of(completion, struct hash_zone, completion);
}

static inline struct hash_zones *as_hash_zones(struct vdo_completion *completion)
{
	vdo_assert_completion_type(completion, VDO_HASH_ZONES_COMPLETION);
	return container_of(completion, struct hash_zones, completion);
}

static inline void assert_in_hash_zone(struct hash_zone *zone, const char *name)
{
	VDO_ASSERT_LOG_ONLY((vdo_get_callback_thread_id() == zone->thread_id),
			    "%s called on hash zone thread", name);
}

static inline bool change_context_state(struct dedupe_context *context, int old, int new)
{
	return (atomic_cmpxchg(&context->state, old, new) == old);
}

static inline bool change_timer_state(struct hash_zone *zone, int old, int new)
{
	return (atomic_cmpxchg(&zone->timer_state, old, new) == old);
}

/**
 * return_hash_lock_to_pool() - (Re)initialize a hash lock and return it to its pool.
 * @zone: The zone from which the lock was borrowed.
 * @lock: The lock that is no longer in use.
 */
static void return_hash_lock_to_pool(struct hash_zone *zone, struct hash_lock *lock)
{
	memset(lock, 0, sizeof(*lock));
	INIT_LIST_HEAD(&lock->pool_node);
	INIT_LIST_HEAD(&lock->duplicate_vios);
	vdo_waitq_init(&lock->waiters);
	list_add_tail(&lock->pool_node, &zone->lock_pool);
}

/**
 * vdo_get_duplicate_lock() - Get the PBN lock on the duplicate data location for a data_vio from
 *                            the hash_lock the data_vio holds (if there is one).
 * @data_vio: The data_vio to query.
 *
 * Return: The PBN lock on the data_vio's duplicate location.
 */
struct pbn_lock *vdo_get_duplicate_lock(struct data_vio *data_vio)
{
	if (data_vio->hash_lock == NULL)
		return NULL;

	return data_vio->hash_lock->duplicate_lock;
}

/**
 * hash_lock_key() - Return hash_lock's record name as a hash code.
 * @lock: The hash lock.
 *
 * Return: The key to use for the int map.
 */
static inline u64 hash_lock_key(struct hash_lock *lock)
{
	return get_unaligned_le64(&lock->hash.name);
}

/**
 * get_hash_lock_state_name() - Get the string representation of a hash lock state.
 * @state: The hash lock state.
 *
 * Return: The short string representing the state
 */
static const char *get_hash_lock_state_name(enum hash_lock_state state)
{
	/* Catch if a state has been added without updating the name array. */
	BUILD_BUG_ON((VDO_HASH_LOCK_BYPASSING + 1) != ARRAY_SIZE(LOCK_STATE_NAMES));
	return (state < ARRAY_SIZE(LOCK_STATE_NAMES)) ? LOCK_STATE_NAMES[state] : "INVALID";
}

/**
 * assert_hash_lock_agent() - Assert that a data_vio is the agent of its hash lock, and that this
 *                            is being called in the hash zone.
 * @data_vio: The data_vio expected to be the lock agent.
 * @where: A string describing the function making the assertion.
 */
static void assert_hash_lock_agent(struct data_vio *data_vio, const char *where)
{
	/* Not safe to access the agent field except from the hash zone. */
	assert_data_vio_in_hash_zone(data_vio);
	VDO_ASSERT_LOG_ONLY(data_vio == data_vio->hash_lock->agent,
			    "%s must be for the hash lock agent", where);
}

/**
 * set_duplicate_lock() - Set the duplicate lock held by a hash lock. May only be called in the
 *                        physical zone of the PBN lock.
 * @hash_lock: The hash lock to update.
 * @pbn_lock: The PBN read lock to use as the duplicate lock.
 */
static void set_duplicate_lock(struct hash_lock *hash_lock, struct pbn_lock *pbn_lock)
{
	VDO_ASSERT_LOG_ONLY((hash_lock->duplicate_lock == NULL),
			    "hash lock must not already hold a duplicate lock");
	pbn_lock->holder_count += 1;
	hash_lock->duplicate_lock = pbn_lock;
}

/**
 * dequeue_lock_waiter() - Remove the first data_vio from the lock's waitq and return it.
 * @lock: The lock containing the wait queue.
 *
 * Return: The first (oldest) waiter in the queue, or NULL if the queue is empty.
 */
static inline struct data_vio *dequeue_lock_waiter(struct hash_lock *lock)
{
	return vdo_waiter_as_data_vio(vdo_waitq_dequeue_waiter(&lock->waiters));
}

/**
 * set_hash_lock() - Set, change, or clear the hash lock a data_vio is using.
 * @data_vio: The data_vio to update.
 * @new_lock: The hash lock the data_vio is joining.
 *
 * Updates the hash lock (or locks) to reflect the change in membership.
 */
static void set_hash_lock(struct data_vio *data_vio, struct hash_lock *new_lock)
{
	struct hash_lock *old_lock = data_vio->hash_lock;

	if (old_lock != NULL) {
		VDO_ASSERT_LOG_ONLY(data_vio->hash_zone != NULL,
				    "must have a hash zone when holding a hash lock");
		VDO_ASSERT_LOG_ONLY(!list_empty(&data_vio->hash_lock_entry),
				    "must be on a hash lock list when holding a hash lock");
		VDO_ASSERT_LOG_ONLY(old_lock->reference_count > 0,
				    "hash lock reference must be counted");

		if ((old_lock->state != VDO_HASH_LOCK_BYPASSING) &&
		    (old_lock->state != VDO_HASH_LOCK_UNLOCKING)) {
			/*
			 * If the reference count goes to zero in a non-terminal state, we're most
			 * likely leaking this lock.
			 */
			VDO_ASSERT_LOG_ONLY(old_lock->reference_count > 1,
					    "hash locks should only become unreferenced in a terminal state, not state %s",
					    get_hash_lock_state_name(old_lock->state));
		}

		list_del_init(&data_vio->hash_lock_entry);
		old_lock->reference_count -= 1;

		data_vio->hash_lock = NULL;
	}

	if (new_lock != NULL) {
		/*
		 * Keep all data_vios sharing the lock on a list since they can complete in any
		 * order and we'll always need a pointer to one to compare data.
		 */
		list_move_tail(&data_vio->hash_lock_entry, &new_lock->duplicate_vios);
		new_lock->reference_count += 1;
		if (new_lock->max_references < new_lock->reference_count)
			new_lock->max_references = new_lock->reference_count;

		data_vio->hash_lock = new_lock;
	}
}

/* There are loops in the state diagram, so some forward decl's are needed. */
static void start_deduping(struct hash_lock *lock, struct data_vio *agent,
			   bool agent_is_done);
static void start_locking(struct hash_lock *lock, struct data_vio *agent);
static void start_writing(struct hash_lock *lock, struct data_vio *agent);
static void unlock_duplicate_pbn(struct vdo_completion *completion);
static void transfer_allocation_lock(struct data_vio *data_vio);

/**
 * exit_hash_lock() - Bottleneck for data_vios that have written or deduplicated and that are no
 *                    longer needed to be an agent for the hash lock.
 * @data_vio: The data_vio to complete and send to be cleaned up.
 */
static void exit_hash_lock(struct data_vio *data_vio)
{
	/* Release the hash lock now, saving a thread transition in cleanup. */
	vdo_release_hash_lock(data_vio);

	/* Complete the data_vio and start the clean-up path to release any locks it still holds. */
	data_vio->vio.completion.callback = complete_data_vio;

	continue_data_vio(data_vio);
}

/**
 * set_duplicate_location() - Set the location of the duplicate block for data_vio, updating the
 *                            is_duplicate and duplicate fields from a zoned_pbn.
 * @data_vio: The data_vio to modify.
 * @source: The location of the duplicate.
 */
static void set_duplicate_location(struct data_vio *data_vio,
				   const struct zoned_pbn source)
{
	data_vio->is_duplicate = (source.pbn != VDO_ZERO_BLOCK);
	data_vio->duplicate = source;
}

/**
 * retire_lock_agent() - Retire the active lock agent, replacing it with the first lock waiter, and
 *                       make the retired agent exit the hash lock.
 * @lock: The hash lock to update.
 *
 * Return: The new lock agent (which will be NULL if there was no waiter)
 */
static struct data_vio *retire_lock_agent(struct hash_lock *lock)
{
	struct data_vio *old_agent = lock->agent;
	struct data_vio *new_agent = dequeue_lock_waiter(lock);

	lock->agent = new_agent;
	exit_hash_lock(old_agent);
	if (new_agent != NULL)
		set_duplicate_location(new_agent, lock->duplicate);
	return new_agent;
}

/**
 * wait_on_hash_lock() - Add a data_vio to the lock's queue of waiters.
 * @lock: The hash lock on which to wait.
 * @data_vio: The data_vio to add to the queue.
 */
static void wait_on_hash_lock(struct hash_lock *lock, struct data_vio *data_vio)
{
	vdo_waitq_enqueue_waiter(&lock->waiters, &data_vio->waiter);

	/*
	 * Make sure the agent doesn't block indefinitely in the packer since it now has at least
	 * one other data_vio waiting on it.
	 */
	if ((lock->state != VDO_HASH_LOCK_WRITING) || !cancel_data_vio_compression(lock->agent))
		return;

	/*
	 * Even though we're waiting, we also have to send ourselves as a one-way message to the
	 * packer to ensure the agent continues executing. This is safe because
	 * cancel_vio_compression() guarantees the agent won't continue executing until this
	 * message arrives in the packer, and because the wait queue link isn't used for sending
	 * the message.
	 */
	data_vio->compression.lock_holder = lock->agent;
	launch_data_vio_packer_callback(data_vio, vdo_remove_lock_holder_from_packer);
}

/**
 * abort_waiter() - waiter_callback_fn function that shunts waiters to write their blocks without
 *                  optimization.
 * @waiter: The data_vio's waiter link.
 * @context: Not used.
 */
static void abort_waiter(struct vdo_waiter *waiter, void __always_unused *context)
{
	write_data_vio(vdo_waiter_as_data_vio(waiter));
}

/**
 * start_bypassing() - Stop using the hash lock.
 * @lock: The hash lock.
 * @agent: The data_vio acting as the agent for the lock.
 *
 * Stops using the hash lock. This is the final transition for hash locks which did not get an
 * error.
 */
static void start_bypassing(struct hash_lock *lock, struct data_vio *agent)
{
	lock->state = VDO_HASH_LOCK_BYPASSING;
	exit_hash_lock(agent);
}

void vdo_clean_failed_hash_lock(struct data_vio *data_vio)
{
	struct hash_lock *lock = data_vio->hash_lock;

	if (lock->state == VDO_HASH_LOCK_BYPASSING) {
		exit_hash_lock(data_vio);
		return;
	}

	if (lock->agent == NULL) {
		lock->agent = data_vio;
	} else if (data_vio != lock->agent) {
		exit_hash_lock(data_vio);
		return;
	}

	lock->state = VDO_HASH_LOCK_BYPASSING;

	/* Ensure we don't attempt to update advice when cleaning up. */
	lock->update_advice = false;

	vdo_waitq_notify_all_waiters(&lock->waiters, abort_waiter, NULL);

	if (lock->duplicate_lock != NULL) {
		/* The agent must reference the duplicate zone to launch it. */
		data_vio->duplicate = lock->duplicate;
		launch_data_vio_duplicate_zone_callback(data_vio, unlock_duplicate_pbn);
		return;
	}

	lock->agent = NULL;
	data_vio->is_duplicate = false;
	exit_hash_lock(data_vio);
}

/**
 * finish_unlocking() - Handle the result of the agent for the lock releasing a read lock on
 *                      duplicate candidate.
 * @completion: The completion of the data_vio acting as the lock's agent.
 *
 * This continuation is registered in unlock_duplicate_pbn().
 */
static void finish_unlocking(struct vdo_completion *completion)
{
	struct data_vio *agent = as_data_vio(completion);
	struct hash_lock *lock = agent->hash_lock;

	assert_hash_lock_agent(agent, __func__);

	VDO_ASSERT_LOG_ONLY(lock->duplicate_lock == NULL,
			    "must have released the duplicate lock for the hash lock");

	if (!lock->verified) {
		/*
		 * UNLOCKING -> WRITING transition: The lock we released was on an unverified
		 * block, so it must have been a lock on advice we were verifying, not on a
		 * location that was used for deduplication. Go write (or compress) the block to
		 * get a location to dedupe against.
		 */
		start_writing(lock, agent);
		return;
	}

	/*
	 * With the lock released, the verified duplicate block may already have changed and will
	 * need to be re-verified if a waiter arrived.
	 */
	lock->verified = false;

	if (vdo_waitq_has_waiters(&lock->waiters)) {
		/*
		 * UNLOCKING -> LOCKING transition: A new data_vio entered the hash lock while the
		 * agent was releasing the PBN lock. The current agent exits and the waiter has to
		 * re-lock and re-verify the duplicate location.
		 *
		 * TODO: If we used the current agent to re-acquire the PBN lock we wouldn't need
		 * to re-verify.
		 */
		agent = retire_lock_agent(lock);
		start_locking(lock, agent);
		return;
	}

	/*
	 * UNLOCKING -> BYPASSING transition: The agent is done with the lock and no other
	 * data_vios reference it, so remove it from the lock map and return it to the pool.
	 */
	start_bypassing(lock, agent);
}

/**
 * unlock_duplicate_pbn() - Release a read lock on the PBN of the block that may or may not have
 *                          contained duplicate data.
 * @completion: The completion of the data_vio acting as the lock's agent.
 *
 * This continuation is launched by start_unlocking(), and calls back to finish_unlocking() on the
 * hash zone thread.
 */
static void unlock_duplicate_pbn(struct vdo_completion *completion)
{
	struct data_vio *agent = as_data_vio(completion);
	struct hash_lock *lock = agent->hash_lock;

	assert_data_vio_in_duplicate_zone(agent);
	VDO_ASSERT_LOG_ONLY(lock->duplicate_lock != NULL,
			    "must have a duplicate lock to release");

	vdo_release_physical_zone_pbn_lock(agent->duplicate.zone, agent->duplicate.pbn,
					   vdo_forget(lock->duplicate_lock));
	if (lock->state == VDO_HASH_LOCK_BYPASSING) {
		complete_data_vio(completion);
		return;
	}

	launch_data_vio_hash_zone_callback(agent, finish_unlocking);
}

/**
 * start_unlocking() - Release a read lock on the PBN of the block that may or may not have
 *                     contained duplicate data.
 * @lock: The hash lock.
 * @agent: The data_vio currently acting as the agent for the lock.
 */
static void start_unlocking(struct hash_lock *lock, struct data_vio *agent)
{
	lock->state = VDO_HASH_LOCK_UNLOCKING;
	launch_data_vio_duplicate_zone_callback(agent, unlock_duplicate_pbn);
}

static void release_context(struct dedupe_context *context)
{
	struct hash_zone *zone = context->zone;

	WRITE_ONCE(zone->active, zone->active - 1);
	list_move(&context->list_entry, &zone->available);
}

static void process_update_result(struct data_vio *agent)
{
	struct dedupe_context *context = agent->dedupe_context;

	if ((context == NULL) ||
	    !change_context_state(context, DEDUPE_CONTEXT_COMPLETE, DEDUPE_CONTEXT_IDLE))
		return;

	agent->dedupe_context = NULL;
	release_context(context);
}

/**
 * finish_updating() - Process the result of a UDS update performed by the agent for the lock.
 * @completion: The completion of the data_vio that performed the update
 *
 * This continuation is registered in start_querying().
 */
static void finish_updating(struct vdo_completion *completion)
{
	struct data_vio *agent = as_data_vio(completion);
	struct hash_lock *lock = agent->hash_lock;

	assert_hash_lock_agent(agent, __func__);

	process_update_result(agent);

	/*
	 * UDS was updated successfully, so don't update again unless the duplicate location
	 * changes due to rollover.
	 */
	lock->update_advice = false;

	if (vdo_waitq_has_waiters(&lock->waiters)) {
		/*
		 * UPDATING -> DEDUPING transition: A new data_vio arrived during the UDS update.
		 * Send it on the verified dedupe path. The agent is done with the lock, but the
		 * lock may still need to use it to clean up after rollover.
		 */
		start_deduping(lock, agent, true);
		return;
	}

	if (lock->duplicate_lock != NULL) {
		/*
		 * UPDATING -> UNLOCKING transition: No one is waiting to dedupe, but we hold a
		 * duplicate PBN lock, so go release it.
		 */
		start_unlocking(lock, agent);
		return;
	}

	/*
	 * UPDATING -> BYPASSING transition: No one is waiting to dedupe and there's no lock to
	 * release.
	 */
	start_bypassing(lock, agent);
}

static void query_index(struct data_vio *data_vio, enum uds_request_type operation);

/**
 * start_updating() - Continue deduplication with the last step, updating UDS with the location of
 *                    the duplicate that should be returned as advice in the future.
 * @lock: The hash lock.
 * @agent: The data_vio currently acting as the agent for the lock.
 */
static void start_updating(struct hash_lock *lock, struct data_vio *agent)
{
	lock->state = VDO_HASH_LOCK_UPDATING;

	VDO_ASSERT_LOG_ONLY(lock->verified, "new advice should have been verified");
	VDO_ASSERT_LOG_ONLY(lock->update_advice, "should only update advice if needed");

	agent->last_async_operation = VIO_ASYNC_OP_UPDATE_DEDUPE_INDEX;
	set_data_vio_hash_zone_callback(agent, finish_updating);
	query_index(agent, UDS_UPDATE);
}

/**
 * finish_deduping() - Handle a data_vio that has finished deduplicating against the block locked
 *                     by the hash lock.
 * @lock: The hash lock.
 * @data_vio: The lock holder that has finished deduplicating.
 *
 * If there are other data_vios still sharing the lock, this will just release the data_vio's share
 * of the lock and finish processing the data_vio. If this is the last data_vio holding the lock,
 * this makes the data_vio the lock agent and uses it to advance the state of the lock so it can
 * eventually be released.
 */
static void finish_deduping(struct hash_lock *lock, struct data_vio *data_vio)
{
	struct data_vio *agent = data_vio;

	VDO_ASSERT_LOG_ONLY(lock->agent == NULL, "shouldn't have an agent in DEDUPING");
	VDO_ASSERT_LOG_ONLY(!vdo_waitq_has_waiters(&lock->waiters),
			    "shouldn't have any lock waiters in DEDUPING");

	/* Just release the lock reference if other data_vios are still deduping. */
	if (lock->reference_count > 1) {
		exit_hash_lock(data_vio);
		return;
	}

	/* The hash lock must have an agent for all other lock states. */
	lock->agent = agent;
	if (lock->update_advice) {
		/*
		 * DEDUPING -> UPDATING transition: The location of the duplicate block changed
		 * since the initial UDS query because of compression, rollover, or because the
		 * query agent didn't have an allocation. The UDS update was delayed in case there
		 * was another change in location, but with only this data_vio using the hash lock,
		 * it's time to update the advice.
		 */
		start_updating(lock, agent);
	} else {
		/*
		 * DEDUPING -> UNLOCKING transition: Release the PBN read lock on the duplicate
		 * location so the hash lock itself can be released (contingent on no new data_vios
		 * arriving in the lock before the agent returns).
		 */
		start_unlocking(lock, agent);
	}
}

/**
 * acquire_lock() - Get the lock for a record name.
 * @zone: The zone responsible for the hash.
 * @hash: The hash to lock.
 * @replace_lock: If non-NULL, the lock already registered for the hash which should be replaced by
 *                the new lock.
 * @lock_ptr: A pointer to receive the hash lock.
 *
 * Gets the lock for the hash (record name) of the data in a data_vio, or if one does not exist (or
 * if we are explicitly rolling over), initialize a new lock for the hash and register it in the
 * zone. This must only be called in the correct thread for the zone.
 *
 * Return: VDO_SUCCESS or an error code.
 */
static int __must_check acquire_lock(struct hash_zone *zone,
				     const struct uds_record_name *hash,
				     struct hash_lock *replace_lock,
				     struct hash_lock **lock_ptr)
{
	struct hash_lock *lock, *new_lock;
	int result;

	/*
	 * Borrow and prepare a lock from the pool so we don't have to do two int_map accesses
	 * in the common case of no lock contention.
	 */
	result = VDO_ASSERT(!list_empty(&zone->lock_pool),
			    "never need to wait for a free hash lock");
	if (result != VDO_SUCCESS)
		return result;

	new_lock = list_entry(zone->lock_pool.prev, struct hash_lock, pool_node);
	list_del_init(&new_lock->pool_node);

	/*
	 * Fill in the hash of the new lock so we can map it, since we have to use the hash as the
	 * map key.
	 */
	new_lock->hash = *hash;

	result = vdo_int_map_put(zone->hash_lock_map, hash_lock_key(new_lock),
				 new_lock, (replace_lock != NULL), (void **) &lock);
	if (result != VDO_SUCCESS) {
		return_hash_lock_to_pool(zone, vdo_forget(new_lock));
		return result;
	}

	if (replace_lock != NULL) {
		/* On mismatch put the old lock back and return a severe error */
		VDO_ASSERT_LOG_ONLY(lock == replace_lock,
				    "old lock must have been in the lock map");
		/* TODO: Check earlier and bail out? */
		VDO_ASSERT_LOG_ONLY(replace_lock->registered,
				    "old lock must have been marked registered");
		replace_lock->registered = false;
	}

	if (lock == replace_lock) {
		lock = new_lock;
		lock->registered = true;
	} else {
		/* There's already a lock for the hash, so we don't need the borrowed lock. */
		return_hash_lock_to_pool(zone, vdo_forget(new_lock));
	}

	*lock_ptr = lock;
	return VDO_SUCCESS;
}

/**
 * enter_forked_lock() - Bind the data_vio to a new hash lock.
 * @waiter: The data_vio's waiter link.
 * @context: The new hash lock.
 *
 * Implements waiter_callback_fn. Binds the data_vio that was waiting to a new hash lock and waits
 * on that lock.
 */
static void enter_forked_lock(struct vdo_waiter *waiter, void *context)
{
	struct data_vio *data_vio = vdo_waiter_as_data_vio(waiter);
	struct hash_lock *new_lock = context;

	set_hash_lock(data_vio, new_lock);
	wait_on_hash_lock(new_lock, data_vio);
}

/**
 * fork_hash_lock() - Fork a hash lock because it has run out of increments on the duplicate PBN.
 * @old_lock: The hash lock to fork.
 * @new_agent: The data_vio that will be the agent for the new lock.
 *
 * Transfers the new agent and any lock waiters to a new hash lock instance which takes the place
 * of the old lock in the lock map. The old lock remains active, but will not update advice.
 */
static void fork_hash_lock(struct hash_lock *old_lock, struct data_vio *new_agent)
{
	struct hash_lock *new_lock;
	int result;

	result = acquire_lock(new_agent->hash_zone, &new_agent->record_name, old_lock,
			      &new_lock);
	if (result != VDO_SUCCESS) {
		continue_data_vio_with_error(new_agent, result);
		return;
	}

	/*
	 * Only one of the two locks should update UDS. The old lock is out of references, so it
	 * would be poor dedupe advice in the short term.
	 */
	old_lock->update_advice = false;
	new_lock->update_advice = true;

	set_hash_lock(new_agent, new_lock);
	new_lock->agent = new_agent;

	vdo_waitq_notify_all_waiters(&old_lock->waiters, enter_forked_lock, new_lock);

	new_agent->is_duplicate = false;
	start_writing(new_lock, new_agent);
}

/**
 * launch_dedupe() - Reserve a reference count increment for a data_vio and launch it on the dedupe
 *                   path.
 * @lock: The hash lock.
 * @data_vio: The data_vio to deduplicate using the hash lock.
 * @has_claim: True if the data_vio already has claimed an increment from the duplicate lock.
 *
 * If no increments are available, this will roll over to a new hash lock and launch the data_vio
 * as the writing agent for that lock.
 */
static void launch_dedupe(struct hash_lock *lock, struct data_vio *data_vio,
			  bool has_claim)
{
	if (!has_claim && !vdo_claim_pbn_lock_increment(lock->duplicate_lock)) {
		/* Out of increments, so must roll over to a new lock. */
		fork_hash_lock(lock, data_vio);
		return;
	}

	/* Deduplicate against the lock's verified location. */
	set_duplicate_location(data_vio, lock->duplicate);
	data_vio->new_mapped = data_vio->duplicate;
	update_metadata_for_data_vio_write(data_vio, lock->duplicate_lock);
}

/**
 * start_deduping() - Enter the hash lock state where data_vios deduplicate in parallel against a
 *                    true copy of their data on disk.
 * @lock: The hash lock.
 * @agent: The data_vio acting as the agent for the lock.
 * @agent_is_done: True only if the agent has already written or deduplicated against its data.
 *
 * If the agent itself needs to deduplicate, an increment for it must already have been claimed
 * from the duplicate lock, ensuring the hash lock will still have a data_vio holding it.
 */
static void start_deduping(struct hash_lock *lock, struct data_vio *agent,
			   bool agent_is_done)
{
	lock->state = VDO_HASH_LOCK_DEDUPING;

	/*
	 * We don't take the downgraded allocation lock from the agent unless we actually need to
	 * deduplicate against it.
	 */
	if (lock->duplicate_lock == NULL) {
		VDO_ASSERT_LOG_ONLY(!vdo_is_state_compressed(agent->new_mapped.state),
				    "compression must have shared a lock");
		VDO_ASSERT_LOG_ONLY(agent_is_done,
				    "agent must have written the new duplicate");
		transfer_allocation_lock(agent);
	}

	VDO_ASSERT_LOG_ONLY(vdo_is_pbn_read_lock(lock->duplicate_lock),
			    "duplicate_lock must be a PBN read lock");

	/*
	 * This state is not like any of the other states. There is no designated agent--the agent
	 * transitioning to this state and all the waiters will be launched to deduplicate in
	 * parallel.
	 */
	lock->agent = NULL;

	/*
	 * Launch the agent (if not already deduplicated) and as many lock waiters as we have
	 * available increments for on the dedupe path. If we run out of increments, rollover will
	 * be triggered and the remaining waiters will be transferred to the new lock.
	 */
	if (!agent_is_done) {
		launch_dedupe(lock, agent, true);
		agent = NULL;
	}
	while (vdo_waitq_has_waiters(&lock->waiters))
		launch_dedupe(lock, dequeue_lock_waiter(lock), false);

	if (agent_is_done) {
		/*
		 * In the degenerate case where all the waiters rolled over to a new lock, this
		 * will continue to use the old agent to clean up this lock, and otherwise it just
		 * lets the agent exit the lock.
		 */
		finish_deduping(lock, agent);
	}
}

/**
 * increment_stat() - Increment a statistic counter in a non-atomic yet thread-safe manner.
 * @stat: The statistic field to increment.
 */
static inline void increment_stat(u64 *stat)
{
	/*
	 * Must only be mutated on the hash zone thread. Prevents any compiler shenanigans from
	 * affecting other threads reading stats.
	 */
	WRITE_ONCE(*stat, *stat + 1);
}

/**
 * finish_verifying() - Handle the result of the agent for the lock comparing its data to the
 *                      duplicate candidate.
 * @completion: The completion of the data_vio used to verify dedupe
 *
 * This continuation is registered in start_verifying().
 */
static void finish_verifying(struct vdo_completion *completion)
{
	struct data_vio *agent = as_data_vio(completion);
	struct hash_lock *lock = agent->hash_lock;

	assert_hash_lock_agent(agent, __func__);

	lock->verified = agent->is_duplicate;

	/*
	 * Only count the result of the initial verification of the advice as valid or stale, and
	 * not any re-verifications due to PBN lock releases.
	 */
	if (!lock->verify_counted) {
		lock->verify_counted = true;
		if (lock->verified)
			increment_stat(&agent->hash_zone->statistics.dedupe_advice_valid);
		else
			increment_stat(&agent->hash_zone->statistics.dedupe_advice_stale);
	}

	/*
	 * Even if the block is a verified duplicate, we can't start to deduplicate unless we can
	 * claim a reference count increment for the agent.
	 */
	if (lock->verified && !vdo_claim_pbn_lock_increment(lock->duplicate_lock)) {
		agent->is_duplicate = false;
		lock->verified = false;
	}

	if (lock->verified) {
		/*
		 * VERIFYING -> DEDUPING transition: The advice is for a true duplicate, so start
		 * deduplicating against it, if references are available.
		 */
		start_deduping(lock, agent, false);
	} else {
		/*
		 * VERIFYING -> UNLOCKING transition: Either the verify failed or we'd try to
		 * dedupe and roll over immediately, which would fail because it would leave the
		 * lock without an agent to release the PBN lock. In both cases, the data will have
		 * to be written or compressed, but first the advice PBN must be unlocked by the
		 * VERIFYING agent.
		 */
		lock->update_advice = true;
		start_unlocking(lock, agent);
	}
}

static bool blocks_equal(char *block1, char *block2)
{
	int i;

	for (i = 0; i < VDO_BLOCK_SIZE; i += sizeof(u64)) {
		if (*((u64 *) &block1[i]) != *((u64 *) &block2[i]))
			return false;
	}

	return true;
}

static void verify_callback(struct vdo_completion *completion)
{
	struct data_vio *agent = as_data_vio(completion);

	agent->is_duplicate = blocks_equal(agent->vio.data, agent->scratch_block);
	launch_data_vio_hash_zone_callback(agent, finish_verifying);
}

static void uncompress_and_verify(struct vdo_completion *completion)
{
	struct data_vio *agent = as_data_vio(completion);
	int result;

	result = uncompress_data_vio(agent, agent->duplicate.state,
				     agent->scratch_block);
	if (result == VDO_SUCCESS) {
		verify_callback(completion);
		return;
	}

	agent->is_duplicate = false;
	launch_data_vio_hash_zone_callback(agent, finish_verifying);
}

static void verify_endio(struct bio *bio)
{
	struct data_vio *agent = vio_as_data_vio(bio->bi_private);
	int result = blk_status_to_errno(bio->bi_status);

	vdo_count_completed_bios(bio);
	if (result != VDO_SUCCESS) {
		agent->is_duplicate = false;
		launch_data_vio_hash_zone_callback(agent, finish_verifying);
		return;
	}

	if (vdo_is_state_compressed(agent->duplicate.state)) {
		launch_data_vio_cpu_callback(agent, uncompress_and_verify,
					     CPU_Q_COMPRESS_BLOCK_PRIORITY);
		return;
	}

	launch_data_vio_cpu_callback(agent, verify_callback,
				     CPU_Q_COMPLETE_READ_PRIORITY);
}

/**
 * start_verifying() - Begin the data verification phase.
 * @lock: The hash lock (must be LOCKING).
 * @agent: The data_vio to use to read and compare candidate data.
 *
 * Continue the deduplication path for a hash lock by using the agent to read (and possibly
 * decompress) the data at the candidate duplicate location, comparing it to the data in the agent
 * to verify that the candidate is identical to all the data_vios sharing the hash. If so, it can
 * be deduplicated against, otherwise a data_vio allocation will have to be written to and used for
 * dedupe.
 */
static void start_verifying(struct hash_lock *lock, struct data_vio *agent)
{
	int result;
	struct vio *vio = &agent->vio;
	char *buffer = (vdo_is_state_compressed(agent->duplicate.state) ?
			(char *) agent->compression.block :
			agent->scratch_block);

	lock->state = VDO_HASH_LOCK_VERIFYING;
	VDO_ASSERT_LOG_ONLY(!lock->verified, "hash lock only verifies advice once");

	agent->last_async_operation = VIO_ASYNC_OP_VERIFY_DUPLICATION;
	result = vio_reset_bio(vio, buffer, verify_endio, REQ_OP_READ,
			       agent->duplicate.pbn);
	if (result != VDO_SUCCESS) {
		set_data_vio_hash_zone_callback(agent, finish_verifying);
		continue_data_vio_with_error(agent, result);
		return;
	}

	set_data_vio_bio_zone_callback(agent, vdo_submit_vio);
	vdo_launch_completion_with_priority(&vio->completion, BIO_Q_VERIFY_PRIORITY);
}

/**
 * finish_locking() - Handle the result of the agent for the lock attempting to obtain a PBN read
 *                    lock on the candidate duplicate block.
 * @completion: The completion of the data_vio that attempted to get the read lock.
 *
 * This continuation is registered in lock_duplicate_pbn().
 */
static void finish_locking(struct vdo_completion *completion)
{
	struct data_vio *agent = as_data_vio(completion);
	struct hash_lock *lock = agent->hash_lock;

	assert_hash_lock_agent(agent, __func__);

	if (!agent->is_duplicate) {
		VDO_ASSERT_LOG_ONLY(lock->duplicate_lock == NULL,
				    "must not hold duplicate_lock if not flagged as a duplicate");
		/*
		 * LOCKING -> WRITING transition: The advice block is being modified or has no
		 * available references, so try to write or compress the data, remembering to
		 * update UDS later with the new advice.
		 */
		increment_stat(&agent->hash_zone->statistics.dedupe_advice_stale);
		lock->update_advice = true;
		start_writing(lock, agent);
		return;
	}

	VDO_ASSERT_LOG_ONLY(lock->duplicate_lock != NULL,
			    "must hold duplicate_lock if flagged as a duplicate");

	if (!lock->verified) {
		/*
		 * LOCKING -> VERIFYING transition: Continue on the unverified dedupe path, reading
		 * the candidate duplicate and comparing it to the agent's data to decide whether
		 * it is a true duplicate or stale advice.
		 */
		start_verifying(lock, agent);
		return;
	}

	if (!vdo_claim_pbn_lock_increment(lock->duplicate_lock)) {
		/*
		 * LOCKING -> UNLOCKING transition: The verified block was re-locked, but has no
		 * available increments left. Must first release the useless PBN read lock before
		 * rolling over to a new copy of the block.
		 */
		agent->is_duplicate = false;
		lock->verified = false;
		lock->update_advice = true;
		start_unlocking(lock, agent);
		return;
	}

	/*
	 * LOCKING -> DEDUPING transition: Continue on the verified dedupe path, deduplicating
	 * against a location that was previously verified or written to.
	 */
	start_deduping(lock, agent, false);
}

static bool acquire_provisional_reference(struct data_vio *agent, struct pbn_lock *lock,
					  struct slab_depot *depot)
{
	/* Ensure that the newly-locked block is referenced. */
	struct vdo_slab *slab = vdo_get_slab(depot, agent->duplicate.pbn);
	int result = vdo_acquire_provisional_reference(slab, agent->duplicate.pbn, lock);

	if (result == VDO_SUCCESS)
		return true;

	vdo_log_warning_strerror(result,
				 "Error acquiring provisional reference for dedupe candidate; aborting dedupe");
	agent->is_duplicate = false;
	vdo_release_physical_zone_pbn_lock(agent->duplicate.zone,
					   agent->duplicate.pbn, lock);
	continue_data_vio_with_error(agent, result);
	return false;
}

/**
 * lock_duplicate_pbn() - Acquire a read lock on the PBN of the block containing candidate
 *                        duplicate data (compressed or uncompressed).
 * @completion: The completion of the data_vio attempting to acquire the physical block lock on
 *              behalf of its hash lock.
 *
 * If the PBN is already locked for writing, the lock attempt is abandoned and is_duplicate will be
 * cleared before calling back. This continuation is launched from start_locking(), and calls back
 * to finish_locking() on the hash zone thread.
 */
static void lock_duplicate_pbn(struct vdo_completion *completion)
{
	unsigned int increment_limit;
	struct pbn_lock *lock;
	int result;

	struct data_vio *agent = as_data_vio(completion);
	struct slab_depot *depot = vdo_from_data_vio(agent)->depot;
	struct physical_zone *zone = agent->duplicate.zone;

	assert_data_vio_in_duplicate_zone(agent);

	set_data_vio_hash_zone_callback(agent, finish_locking);

	/*
	 * While in the zone that owns it, find out how many additional references can be made to
	 * the block if it turns out to truly be a duplicate.
	 */
	increment_limit = vdo_get_increment_limit(depot, agent->duplicate.pbn);
	if (increment_limit == 0) {
		/*
		 * We could deduplicate against it later if a reference happened to be released
		 * during verification, but it's probably better to bail out now.
		 */
		agent->is_duplicate = false;
		continue_data_vio(agent);
		return;
	}

	result = vdo_attempt_physical_zone_pbn_lock(zone, agent->duplicate.pbn,
						    VIO_READ_LOCK, &lock);
	if (result != VDO_SUCCESS) {
		continue_data_vio_with_error(agent, result);
		return;
	}

	if (!vdo_is_pbn_read_lock(lock)) {
		/*
		 * There are three cases of write locks: uncompressed data block writes, compressed
		 * (packed) block writes, and block map page writes. In all three cases, we give up
		 * on trying to verify the advice and don't bother to try deduplicate against the
		 * data in the write lock holder.
		 *
		 * 1) We don't ever want to try to deduplicate against a block map page.
		 *
		 * 2a) It's very unlikely we'd deduplicate against an entire packed block, both
		 * because of the chance of matching it, and because we don't record advice for it,
		 * but for the uncompressed representation of all the fragments it contains. The
		 * only way we'd be getting lock contention is if we've written the same
		 * representation coincidentally before, had it become unreferenced, and it just
		 * happened to be packed together from compressed writes when we go to verify the
		 * lucky advice. Giving up is a minuscule loss of potential dedupe.
		 *
		 * 2b) If the advice is for a slot of a compressed block, it's about to get
		 * smashed, and the write smashing it cannot contain our data--it would have to be
		 * writing on behalf of our hash lock, but that's impossible since we're the lock
		 * agent.
		 *
		 * 3a) If the lock is held by a data_vio with different data, the advice is already
		 * stale or is about to become stale.
		 *
		 * 3b) If the lock is held by a data_vio that matches us, we may as well either
		 * write it ourselves (or reference the copy we already wrote) instead of
		 * potentially having many duplicates wait for the lock holder to write, journal,
		 * hash, and finally arrive in the hash lock. We lose a chance to avoid a UDS
		 * update in the very rare case of advice for a free block that just happened to be
		 * allocated to a data_vio with the same hash. There's also a chance to save on a
		 * block write, at the cost of a block verify. Saving on a full block compare in
		 * all stale advice cases almost certainly outweighs saving a UDS update and
		 * trading a write for a read in a lucky case where advice would have been saved
		 * from becoming stale.
		 */
		agent->is_duplicate = false;
		continue_data_vio(agent);
		return;
	}

	if (lock->holder_count == 0) {
		if (!acquire_provisional_reference(agent, lock, depot))
			return;

		/*
		 * The increment limit we grabbed earlier is still valid. The lock now holds the
		 * rights to acquire all those references. Those rights will be claimed by hash
		 * locks sharing this read lock.
		 */
		lock->increment_limit = increment_limit;
	}

	/*
	 * We've successfully acquired a read lock on behalf of the hash lock, so mark it as such.
	 */
	set_duplicate_lock(agent->hash_lock, lock);

	/*
	 * TODO: Optimization: We could directly launch the block verify, then switch to a hash
	 * thread.
	 */
	continue_data_vio(agent);
}

/**
 * start_locking() - Continue deduplication for a hash lock that has obtained valid advice of a
 *                   potential duplicate through its agent.
 * @lock: The hash lock (currently must be QUERYING).
 * @agent: The data_vio bearing the dedupe advice.
 */
static void start_locking(struct hash_lock *lock, struct data_vio *agent)
{
	VDO_ASSERT_LOG_ONLY(lock->duplicate_lock == NULL,
			    "must not acquire a duplicate lock when already holding it");

	lock->state = VDO_HASH_LOCK_LOCKING;

	/*
	 * TODO: Optimization: If we arrange to continue on the duplicate zone thread when
	 * accepting the advice, and don't explicitly change lock states (or use an agent-local
	 * state, or an atomic), we can avoid a thread transition here.
	 */
	agent->last_async_operation = VIO_ASYNC_OP_LOCK_DUPLICATE_PBN;
	launch_data_vio_duplicate_zone_callback(agent, lock_duplicate_pbn);
}

/**
 * finish_writing() - Re-entry point for the lock agent after it has finished writing or
 *                    compressing its copy of the data block.
 * @lock: The hash lock, which must be in state WRITING.
 * @agent: The data_vio that wrote its data for the lock.
 *
 * The agent will never need to dedupe against anything, so it's done with the lock, but the lock
 * may not be finished with it, as a UDS update might still be needed.
 *
 * If there are other lock holders, the agent will hand the job to one of them and exit, leaving
 * the lock to deduplicate against the just-written block. If there are no other lock holders, the
 * agent either exits (and later tears down the hash lock), or it remains the agent and updates
 * UDS.
 */
static void finish_writing(struct hash_lock *lock, struct data_vio *agent)
{
	/*
	 * Dedupe against the data block or compressed block slot the agent wrote. Since we know
	 * the write succeeded, there's no need to verify it.
	 */
	lock->duplicate = agent->new_mapped;
	lock->verified = true;

	if (vdo_is_state_compressed(lock->duplicate.state) && lock->registered) {
		/*
		 * Compression means the location we gave in the UDS query is not the location
		 * we're using to deduplicate.
		 */
		lock->update_advice = true;
	}

	/* If there are any waiters, we need to start deduping them. */
	if (vdo_waitq_has_waiters(&lock->waiters)) {
		/*
		 * WRITING -> DEDUPING transition: an asynchronously-written block failed to
		 * compress, so the PBN lock on the written copy was already transferred. The agent
		 * is done with the lock, but the lock may still need to use it to clean up after
		 * rollover.
		 */
		start_deduping(lock, agent, true);
		return;
	}

	/*
	 * There are no waiters and the agent has successfully written, so take a step towards
	 * being able to release the hash lock (or just release it).
	 */
	if (lock->update_advice) {
		/*
		 * WRITING -> UPDATING transition: There's no waiter and a UDS update is needed, so
		 * retain the WRITING agent and use it to launch the update. The happens on
		 * compression, rollover, or the QUERYING agent not having an allocation.
		 */
		start_updating(lock, agent);
	} else if (lock->duplicate_lock != NULL) {
		/*
		 * WRITING -> UNLOCKING transition: There's no waiter and no update needed, but the
		 * compressed write gave us a shared duplicate lock that we must release.
		 */
		set_duplicate_location(agent, lock->duplicate);
		start_unlocking(lock, agent);
	} else {
		/*
		 * WRITING -> BYPASSING transition: There's no waiter, no update needed, and no
		 * duplicate lock held, so both the agent and lock have no more work to do. The
		 * agent will release its allocation lock in cleanup.
		 */
		start_bypassing(lock, agent);
	}
}

/**
 * select_writing_agent() - Search through the lock waiters for a data_vio that has an allocation.
 * @lock: The hash lock to modify.
 *
 * If an allocation is found, swap agents, put the old agent at the head of the wait queue, then
 * return the new agent. Otherwise, just return the current agent.
 */
static struct data_vio *select_writing_agent(struct hash_lock *lock)
{
	struct vdo_wait_queue temp_queue;
	struct data_vio *data_vio;

	vdo_waitq_init(&temp_queue);

	/*
	 * Move waiters to the temp queue one-by-one until we find an allocation. Not ideal to
	 * search, but it only happens when nearly out of space.
	 */
	while (((data_vio = dequeue_lock_waiter(lock)) != NULL) &&
	       !data_vio_has_allocation(data_vio)) {
		/* Use the lower-level enqueue since we're just moving waiters around. */
		vdo_waitq_enqueue_waiter(&temp_queue, &data_vio->waiter);
	}

	if (data_vio != NULL) {
		/*
		 * Move the rest of the waiters over to the temp queue, preserving the order they
		 * arrived at the lock.
		 */
		vdo_waitq_transfer_all_waiters(&lock->waiters, &temp_queue);

		/*
		 * The current agent is being replaced and will have to wait to dedupe; make it the
		 * first waiter since it was the first to reach the lock.
		 */
		vdo_waitq_enqueue_waiter(&lock->waiters, &lock->agent->waiter);
		lock->agent = data_vio;
	} else {
		/* No one has an allocation, so keep the current agent. */
		data_vio = lock->agent;
	}

	/* Swap all the waiters back onto the lock's queue. */
	vdo_waitq_transfer_all_waiters(&temp_queue, &lock->waiters);
	return data_vio;
}

/**
 * start_writing() - Begin the non-duplicate write path.
 * @lock: The hash lock (currently must be QUERYING).
 * @agent: The data_vio currently acting as the agent for the lock.
 *
 * Begins the non-duplicate write path for a hash lock that had no advice, selecting a data_vio
 * with an allocation as a new agent, if necessary, then resuming the agent on the data_vio write
 * path.
 */
static void start_writing(struct hash_lock *lock, struct data_vio *agent)
{
	lock->state = VDO_HASH_LOCK_WRITING;

	/*
	 * The agent might not have received an allocation and so can't be used for writing, but
	 * it's entirely possible that one of the waiters did.
	 */
	if (!data_vio_has_allocation(agent)) {
		agent = select_writing_agent(lock);
		/* If none of the waiters had an allocation, the writes all have to fail. */
		if (!data_vio_has_allocation(agent)) {
			/*
			 * TODO: Should we keep a variant of BYPASSING that causes new arrivals to
			 * fail immediately if they don't have an allocation? It might be possible
			 * that on some path there would be non-waiters still referencing the lock,
			 * so it would remain in the map as everything is currently spelled, even
			 * if the agent and all waiters release.
			 */
			continue_data_vio_with_error(agent, VDO_NO_SPACE);
			return;
		}
	}

	/*
	 * If the agent compresses, it might wait indefinitely in the packer, which would be bad if
	 * there are any other data_vios waiting.
	 */
	if (vdo_waitq_has_waiters(&lock->waiters))
		cancel_data_vio_compression(agent);

	/*
	 * Send the agent to the compress/pack/write path in vioWrite. If it succeeds, it will
	 * return to the hash lock via vdo_continue_hash_lock() and call finish_writing().
	 */
	launch_compress_data_vio(agent);
}

/*
 * Decode VDO duplicate advice from the old_metadata field of a UDS request.
 * Returns true if valid advice was found and decoded
 */
static bool decode_uds_advice(struct dedupe_context *context)
{
	const struct uds_request *request = &context->request;
	struct data_vio *data_vio = context->requestor;
	size_t offset = 0;
	const struct uds_record_data *encoding = &request->old_metadata;
	struct vdo *vdo = vdo_from_data_vio(data_vio);
	struct zoned_pbn *advice = &data_vio->duplicate;
	u8 version;
	int result;

	if ((request->status != UDS_SUCCESS) || !request->found)
		return false;

	version = encoding->data[offset++];
	if (version != UDS_ADVICE_VERSION) {
		vdo_log_error("invalid UDS advice version code %u", version);
		return false;
	}

	advice->state = encoding->data[offset++];
	advice->pbn = get_unaligned_le64(&encoding->data[offset]);
	offset += sizeof(u64);
	BUG_ON(offset != UDS_ADVICE_SIZE);

	/* Don't use advice that's clearly meaningless. */
	if ((advice->state == VDO_MAPPING_STATE_UNMAPPED) || (advice->pbn == VDO_ZERO_BLOCK)) {
		vdo_log_debug("Invalid advice from deduplication server: pbn %llu, state %u. Giving up on deduplication of logical block %llu",
			      (unsigned long long) advice->pbn, advice->state,
			      (unsigned long long) data_vio->logical.lbn);
		atomic64_inc(&vdo->stats.invalid_advice_pbn_count);
		return false;
	}

	result = vdo_get_physical_zone(vdo, advice->pbn, &advice->zone);
	if ((result != VDO_SUCCESS) || (advice->zone == NULL)) {
		vdo_log_debug("Invalid physical block number from deduplication server: %llu, giving up on deduplication of logical block %llu",
			      (unsigned long long) advice->pbn,
			      (unsigned long long) data_vio->logical.lbn);
		atomic64_inc(&vdo->stats.invalid_advice_pbn_count);
		return false;
	}

	return true;
}

static void process_query_result(struct data_vio *agent)
{
	struct dedupe_context *context = agent->dedupe_context;

	if (context == NULL)
		return;

	if (change_context_state(context, DEDUPE_CONTEXT_COMPLETE, DEDUPE_CONTEXT_IDLE)) {
		agent->is_duplicate = decode_uds_advice(context);
		agent->dedupe_context = NULL;
		release_context(context);
	}
}

/**
 * finish_querying() - Process the result of a UDS query performed by the agent for the lock.
 * @completion: The completion of the data_vio that performed the query.
 *
 * This continuation is registered in start_querying().
 */
static void finish_querying(struct vdo_completion *completion)
{
	struct data_vio *agent = as_data_vio(completion);
	struct hash_lock *lock = agent->hash_lock;

	assert_hash_lock_agent(agent, __func__);

	process_query_result(agent);

	if (agent->is_duplicate) {
		lock->duplicate = agent->duplicate;
		/*
		 * QUERYING -> LOCKING transition: Valid advice was obtained from UDS. Use the
		 * QUERYING agent to start the hash lock on the unverified dedupe path, verifying
		 * that the advice can be used.
		 */
		start_locking(lock, agent);
	} else {
		/*
		 * The agent will be used as the duplicate if has an allocation; if it does, that
		 * location was posted to UDS, so no update will be needed.
		 */
		lock->update_advice = !data_vio_has_allocation(agent);
		/*
		 * QUERYING -> WRITING transition: There was no advice or the advice wasn't valid,
		 * so try to write or compress the data.
		 */
		start_writing(lock, agent);
	}
}

/**
 * start_querying() - Start deduplication for a hash lock.
 * @lock: The initialized hash lock.
 * @data_vio: The data_vio that has just obtained the new lock.
 *
 * Starts deduplication for a hash lock that has finished initializing by making the data_vio that
 * requested it the agent, entering the QUERYING state, and using the agent to perform the UDS
 * query on behalf of the lock.
 */
static void start_querying(struct hash_lock *lock, struct data_vio *data_vio)
{
	lock->agent = data_vio;
	lock->state = VDO_HASH_LOCK_QUERYING;
	data_vio->last_async_operation = VIO_ASYNC_OP_CHECK_FOR_DUPLICATION;
	set_data_vio_hash_zone_callback(data_vio, finish_querying);
	query_index(data_vio,
		    (data_vio_has_allocation(data_vio) ? UDS_POST : UDS_QUERY));
}

/**
 * report_bogus_lock_state() - Complain that a data_vio has entered a hash_lock that is in an
 *                             unimplemented or unusable state and continue the data_vio with an
 *                             error.
 * @lock: The hash lock.
 * @data_vio: The data_vio attempting to enter the lock.
 */
static void report_bogus_lock_state(struct hash_lock *lock, struct data_vio *data_vio)
{
	VDO_ASSERT_LOG_ONLY(false, "hash lock must not be in unimplemented state %s",
			    get_hash_lock_state_name(lock->state));
	continue_data_vio_with_error(data_vio, VDO_LOCK_ERROR);
}

/**
 * vdo_continue_hash_lock() - Continue the processing state after writing, compressing, or
 *                            deduplicating.
 * @completion: The data_vio completion to continue processing in its hash lock.
 *
 * Asynchronously continue processing a data_vio in its hash lock after it has finished writing,
 * compressing, or deduplicating, so it can share the result with any data_vios waiting in the hash
 * lock, or update the UDS index, or simply release its share of the lock.
 *
 * Context: This must only be called in the correct thread for the hash zone.
 */
void vdo_continue_hash_lock(struct vdo_completion *completion)
{
	struct data_vio *data_vio = as_data_vio(completion);
	struct hash_lock *lock = data_vio->hash_lock;

	switch (lock->state) {
	case VDO_HASH_LOCK_WRITING:
		VDO_ASSERT_LOG_ONLY(data_vio == lock->agent,
				    "only the lock agent may continue the lock");
		finish_writing(lock, data_vio);
		break;

	case VDO_HASH_LOCK_DEDUPING:
		finish_deduping(lock, data_vio);
		break;

	case VDO_HASH_LOCK_BYPASSING:
		/* This data_vio has finished the write path and the lock doesn't need it. */
		exit_hash_lock(data_vio);
		break;

	case VDO_HASH_LOCK_INITIALIZING:
	case VDO_HASH_LOCK_QUERYING:
	case VDO_HASH_LOCK_UPDATING:
	case VDO_HASH_LOCK_LOCKING:
	case VDO_HASH_LOCK_VERIFYING:
	case VDO_HASH_LOCK_UNLOCKING:
		/* A lock in this state should never be re-entered. */
		report_bogus_lock_state(lock, data_vio);
		break;

	default:
		report_bogus_lock_state(lock, data_vio);
	}
}

/**
 * is_hash_collision() - Check to see if a hash collision has occurred.
 * @lock: The lock to check.
 * @candidate: The data_vio seeking to share the lock.
 *
 * Check whether the data in data_vios sharing a lock is different than in a data_vio seeking to
 * share the lock, which should only be possible in the extremely unlikely case of a hash
 * collision.
 *
 * Return: true if the given data_vio must not share the lock because it doesn't have the same data
 *         as the lock holders.
 */
static bool is_hash_collision(struct hash_lock *lock, struct data_vio *candidate)
{
	struct data_vio *lock_holder;
	struct hash_zone *zone;
	bool collides;

	if (list_empty(&lock->duplicate_vios))
		return false;

	lock_holder = list_first_entry(&lock->duplicate_vios, struct data_vio,
				       hash_lock_entry);
	zone = candidate->hash_zone;
	collides = !blocks_equal(lock_holder->vio.data, candidate->vio.data);
	if (collides)
		increment_stat(&zone->statistics.concurrent_hash_collisions);
	else
		increment_stat(&zone->statistics.concurrent_data_matches);

	return collides;
}

static inline int assert_hash_lock_preconditions(const struct data_vio *data_vio)
{
	int result;

	/* FIXME: BUG_ON() and/or enter read-only mode? */
	result = VDO_ASSERT(data_vio->hash_lock == NULL,
			    "must not already hold a hash lock");
	if (result != VDO_SUCCESS)
		return result;

	result = VDO_ASSERT(list_empty(&data_vio->hash_lock_entry),
			    "must not already be a member of a hash lock list");
	if (result != VDO_SUCCESS)
		return result;

	return VDO_ASSERT(data_vio->recovery_sequence_number == 0,
			  "must not hold a recovery lock when getting a hash lock");
}

/**
 * vdo_acquire_hash_lock() - Acquire or share a lock on a record name.
 * @completion: The data_vio completion acquiring a lock on its record name.
 *
 * Acquire or share a lock on the hash (record name) of the data in a data_vio, updating the
 * data_vio to reference the lock. This must only be called in the correct thread for the zone. In
 * the unlikely case of a hash collision, this function will succeed, but the data_vio will not get
 * a lock reference.
 */
void vdo_acquire_hash_lock(struct vdo_completion *completion)
{
	struct data_vio *data_vio = as_data_vio(completion);
	struct hash_lock *lock;
	int result;

	assert_data_vio_in_hash_zone(data_vio);

	result = assert_hash_lock_preconditions(data_vio);
	if (result != VDO_SUCCESS) {
		continue_data_vio_with_error(data_vio, result);
		return;
	}

	result = acquire_lock(data_vio->hash_zone, &data_vio->record_name, NULL, &lock);
	if (result != VDO_SUCCESS) {
		continue_data_vio_with_error(data_vio, result);
		return;
	}

	if (is_hash_collision(lock, data_vio)) {
		/*
		 * Hash collisions are extremely unlikely, but the bogus dedupe would be a data
		 * corruption. Bypass optimization entirely. We can't compress a data_vio without
		 * a hash_lock as the compressed write depends on the hash_lock to manage the
		 * references for the compressed block.
		 */
		write_data_vio(data_vio);
		return;
	}

	set_hash_lock(data_vio, lock);
	switch (lock->state) {
	case VDO_HASH_LOCK_INITIALIZING:
		start_querying(lock, data_vio);
		return;

	case VDO_HASH_LOCK_QUERYING:
	case VDO_HASH_LOCK_WRITING:
	case VDO_HASH_LOCK_UPDATING:
	case VDO_HASH_LOCK_LOCKING:
	case VDO_HASH_LOCK_VERIFYING:
	case VDO_HASH_LOCK_UNLOCKING:
		/* The lock is busy, and can't be shared yet. */
		wait_on_hash_lock(lock, data_vio);
		return;

	case VDO_HASH_LOCK_BYPASSING:
		/* We can't use this lock, so bypass optimization entirely. */
		vdo_release_hash_lock(data_vio);
		write_data_vio(data_vio);
		return;

	case VDO_HASH_LOCK_DEDUPING:
		launch_dedupe(lock, data_vio, false);
		return;

	default:
		/* A lock in this state should not be acquired by new VIOs. */
		report_bogus_lock_state(lock, data_vio);
	}
}

/**
 * vdo_release_hash_lock() - Release a data_vio's share of a hash lock, if held, and null out the
 *                           data_vio's reference to it.
 * @data_vio: The data_vio releasing its hash lock.
 *
 * If the data_vio is the only one holding the lock, this also releases any resources or locks used
 * by the hash lock (such as a PBN read lock on a block containing data with the same hash) and
 * returns the lock to the hash zone's lock pool.
 *
 * Context: This must only be called in the correct thread for the hash zone.
 */
void vdo_release_hash_lock(struct data_vio *data_vio)
{
	u64 lock_key;
	struct hash_lock *lock = data_vio->hash_lock;
	struct hash_zone *zone = data_vio->hash_zone;

	if (lock == NULL)
		return;

	set_hash_lock(data_vio, NULL);

	if (lock->reference_count > 0) {
		/* The lock is still in use by other data_vios. */
		return;
	}

	lock_key = hash_lock_key(lock);
	if (lock->registered) {
		struct hash_lock *removed;

		removed = vdo_int_map_remove(zone->hash_lock_map, lock_key);
		VDO_ASSERT_LOG_ONLY(lock == removed,
				    "hash lock being released must have been mapped");
	} else {
		VDO_ASSERT_LOG_ONLY(lock != vdo_int_map_get(zone->hash_lock_map, lock_key),
				    "unregistered hash lock must not be in the lock map");
	}

	VDO_ASSERT_LOG_ONLY(!vdo_waitq_has_waiters(&lock->waiters),
			    "hash lock returned to zone must have no waiters");
	VDO_ASSERT_LOG_ONLY((lock->duplicate_lock == NULL),
			    "hash lock returned to zone must not reference a PBN lock");
	VDO_ASSERT_LOG_ONLY((lock->state == VDO_HASH_LOCK_BYPASSING),
			    "returned hash lock must not be in use with state %s",
			    get_hash_lock_state_name(lock->state));
	VDO_ASSERT_LOG_ONLY(list_empty(&lock->pool_node),
			    "hash lock returned to zone must not be in a pool list");
	VDO_ASSERT_LOG_ONLY(list_empty(&lock->duplicate_vios),
			    "hash lock returned to zone must not reference DataVIOs");

	return_hash_lock_to_pool(zone, lock);
}

/**
 * transfer_allocation_lock() - Transfer a data_vio's downgraded allocation PBN lock to the
 *                              data_vio's hash lock, converting it to a duplicate PBN lock.
 * @data_vio: The data_vio holding the allocation lock to transfer.
 */
static void transfer_allocation_lock(struct data_vio *data_vio)
{
	struct allocation *allocation = &data_vio->allocation;
	struct hash_lock *hash_lock = data_vio->hash_lock;

	VDO_ASSERT_LOG_ONLY(data_vio->new_mapped.pbn == allocation->pbn,
			    "transferred lock must be for the block written");

	allocation->pbn = VDO_ZERO_BLOCK;

	VDO_ASSERT_LOG_ONLY(vdo_is_pbn_read_lock(allocation->lock),
			    "must have downgraded the allocation lock before transfer");

	hash_lock->duplicate = data_vio->new_mapped;
	data_vio->duplicate = data_vio->new_mapped;

	/*
	 * Since the lock is being transferred, the holder count doesn't change (and isn't even
	 * safe to examine on this thread).
	 */
	hash_lock->duplicate_lock = vdo_forget(allocation->lock);
}

/**
 * vdo_share_compressed_write_lock() - Make a data_vio's hash lock a shared holder of the PBN lock
 *                                     on the compressed block to which its data was just written.
 * @data_vio: The data_vio which was just compressed.
 * @pbn_lock: The PBN lock on the compressed block.
 *
 * If the lock is still a write lock (as it will be for the first share), it will be converted to a
 * read lock. This also reserves a reference count increment for the data_vio.
 */
void vdo_share_compressed_write_lock(struct data_vio *data_vio,
				     struct pbn_lock *pbn_lock)
{
	bool claimed;

	VDO_ASSERT_LOG_ONLY(vdo_get_duplicate_lock(data_vio) == NULL,
			    "a duplicate PBN lock should not exist when writing");
	VDO_ASSERT_LOG_ONLY(vdo_is_state_compressed(data_vio->new_mapped.state),
			    "lock transfer must be for a compressed write");
	assert_data_vio_in_new_mapped_zone(data_vio);

	/* First sharer downgrades the lock. */
	if (!vdo_is_pbn_read_lock(pbn_lock))
		vdo_downgrade_pbn_write_lock(pbn_lock, true);

	/*
	 * Get a share of the PBN lock, ensuring it cannot be released until after this data_vio
	 * has had a chance to journal a reference.
	 */
	data_vio->duplicate = data_vio->new_mapped;
	data_vio->hash_lock->duplicate = data_vio->new_mapped;
	set_duplicate_lock(data_vio->hash_lock, pbn_lock);

	/*
	 * Claim a reference for this data_vio. Necessary since another hash_lock might start
	 * deduplicating against it before our incRef.
	 */
	claimed = vdo_claim_pbn_lock_increment(pbn_lock);
	VDO_ASSERT_LOG_ONLY(claimed, "impossible to fail to claim an initial increment");
}

static void start_uds_queue(void *ptr)
{
	/*
	 * Allow the UDS dedupe worker thread to do memory allocations. It will only do allocations
	 * during the UDS calls that open or close an index, but those allocations can safely sleep
	 * while reserving a large amount of memory. We could use an allocations_allowed boolean
	 * (like the base threads do), but it would be an unnecessary embellishment.
	 */
	struct vdo_thread *thread = vdo_get_work_queue_owner(vdo_get_current_work_queue());

	vdo_register_allocating_thread(&thread->allocating_thread, NULL);
}

static void finish_uds_queue(void *ptr __always_unused)
{
	vdo_unregister_allocating_thread();
}

static void close_index(struct hash_zones *zones)
	__must_hold(&zones->lock)
{
	int result;

	/*
	 * Change the index state so that get_index_statistics() will not try to use the index
	 * session we are closing.
	 */
	zones->index_state = IS_CHANGING;
	/* Close the index session, while not holding the lock. */
	spin_unlock(&zones->lock);
	result = uds_close_index(zones->index_session);

	if (result != UDS_SUCCESS)
		vdo_log_error_strerror(result, "Error closing index");
	spin_lock(&zones->lock);
	zones->index_state = IS_CLOSED;
	zones->error_flag |= result != UDS_SUCCESS;
	/* ASSERTION: We leave in IS_CLOSED state. */
}

static void open_index(struct hash_zones *zones)
	__must_hold(&zones->lock)
{
	/* ASSERTION: We enter in IS_CLOSED state. */
	int result;
	bool create_flag = zones->create_flag;

	zones->create_flag = false;
	/*
	 * Change the index state so that the it will be reported to the outside world as
	 * "opening".
	 */
	zones->index_state = IS_CHANGING;
	zones->error_flag = false;

	/* Open the index session, while not holding the lock */
	spin_unlock(&zones->lock);
	result = uds_open_index(create_flag ? UDS_CREATE : UDS_LOAD,
				&zones->parameters, zones->index_session);
	if (result != UDS_SUCCESS)
		vdo_log_error_strerror(result, "Error opening index");

	spin_lock(&zones->lock);
	if (!create_flag) {
		switch (result) {
		case -ENOENT:
			/*
			 * Either there is no index, or there is no way we can recover the index.
			 * We will be called again and try to create a new index.
			 */
			zones->index_state = IS_CLOSED;
			zones->create_flag = true;
			return;
		default:
			break;
		}
	}
	if (result == UDS_SUCCESS) {
		zones->index_state = IS_OPENED;
	} else {
		zones->index_state = IS_CLOSED;
		zones->index_target = IS_CLOSED;
		zones->error_flag = true;
		spin_unlock(&zones->lock);
		vdo_log_info("Setting UDS index target state to error");
		spin_lock(&zones->lock);
	}
	/*
	 * ASSERTION: On success, we leave in IS_OPENED state.
	 * ASSERTION: On failure, we leave in IS_CLOSED state.
	 */
}

static void change_dedupe_state(struct vdo_completion *completion)
{
	struct hash_zones *zones = as_hash_zones(completion);

	spin_lock(&zones->lock);

	/* Loop until the index is in the target state and the create flag is clear. */
	while (vdo_is_state_normal(&zones->state) &&
	       ((zones->index_state != zones->index_target) || zones->create_flag)) {
		if (zones->index_state == IS_OPENED)
			close_index(zones);
		else
			open_index(zones);
	}

	zones->changing = false;
	spin_unlock(&zones->lock);
}

static void start_expiration_timer(struct dedupe_context *context)
{
	u64 start_time = context->submission_jiffies;
	u64 end_time;

	if (!change_timer_state(context->zone, DEDUPE_QUERY_TIMER_IDLE,
				DEDUPE_QUERY_TIMER_RUNNING))
		return;

	end_time = max(start_time + vdo_dedupe_index_timeout_jiffies,
		       jiffies + vdo_dedupe_index_min_timer_jiffies);
	mod_timer(&context->zone->timer, end_time);
}

/**
 * report_dedupe_timeouts() - Record and eventually report that some dedupe requests reached their
 *                            expiration time without getting answers, so we timed them out.
 * @zones: The hash zones.
 * @timeouts: The number of newly timed out requests.
 */
static void report_dedupe_timeouts(struct hash_zones *zones, unsigned int timeouts)
{
	atomic64_add(timeouts, &zones->timeouts);
	spin_lock(&zones->lock);
	if (__ratelimit(&zones->ratelimiter)) {
		u64 unreported = atomic64_read(&zones->timeouts);

		unreported -= zones->reported_timeouts;
		vdo_log_debug("UDS index timeout on %llu requests",
			      (unsigned long long) unreported);
		zones->reported_timeouts += unreported;
	}
	spin_unlock(&zones->lock);
}

static int initialize_index(struct vdo *vdo, struct hash_zones *zones)
{
	int result;
	off_t uds_offset;
	struct volume_geometry geometry = vdo->geometry;
	static const struct vdo_work_queue_type uds_queue_type = {
		.start = start_uds_queue,
		.finish = finish_uds_queue,
		.max_priority = UDS_Q_MAX_PRIORITY,
		.default_priority = UDS_Q_PRIORITY,
	};

	vdo_set_dedupe_index_timeout_interval(vdo_dedupe_index_timeout_interval);
	vdo_set_dedupe_index_min_timer_interval(vdo_dedupe_index_min_timer_interval);
	spin_lock_init(&zones->lock);

	/*
	 * Since we will save up the timeouts that would have been reported but were ratelimited,
	 * we don't need to report ratelimiting.
	 */
	ratelimit_default_init(&zones->ratelimiter);
	ratelimit_set_flags(&zones->ratelimiter, RATELIMIT_MSG_ON_RELEASE);
	uds_offset = ((vdo_get_index_region_start(geometry) -
		       geometry.bio_offset) * VDO_BLOCK_SIZE);
	zones->parameters = (struct uds_parameters) {
		.bdev = vdo->device_config->owned_device->bdev,
		.offset = uds_offset,
		.size = (vdo_get_index_region_size(geometry) * VDO_BLOCK_SIZE),
		.memory_size = geometry.index_config.mem,
		.sparse = geometry.index_config.sparse,
		.nonce = (u64) geometry.nonce,
	};

	result = uds_create_index_session(&zones->index_session);
	if (result != UDS_SUCCESS)
		return result;

	result = vdo_make_thread(vdo, vdo->thread_config.dedupe_thread, &uds_queue_type,
				 1, NULL);
	if (result != VDO_SUCCESS) {
		uds_destroy_index_session(vdo_forget(zones->index_session));
		vdo_log_error("UDS index queue initialization failed (%d)", result);
		return result;
	}

	vdo_initialize_completion(&zones->completion, vdo, VDO_HASH_ZONES_COMPLETION);
	vdo_set_completion_callback(&zones->completion, change_dedupe_state,
				    vdo->thread_config.dedupe_thread);
	return VDO_SUCCESS;
}

/**
 * finish_index_operation() - This is the UDS callback for index queries.
 * @request: The uds request which has just completed.
 */
static void finish_index_operation(struct uds_request *request)
{
	struct dedupe_context *context = container_of(request, struct dedupe_context,
						      request);

	if (change_context_state(context, DEDUPE_CONTEXT_PENDING,
				 DEDUPE_CONTEXT_COMPLETE)) {
		/*
		 * This query has not timed out, so send its data_vio back to its hash zone to
		 * process the results.
		 */
		continue_data_vio(context->requestor);
		return;
	}

	/*
	 * This query has timed out, so try to mark it complete and hence eligible for reuse. Its
	 * data_vio has already moved on.
	 */
	if (!change_context_state(context, DEDUPE_CONTEXT_TIMED_OUT,
				  DEDUPE_CONTEXT_TIMED_OUT_COMPLETE)) {
		VDO_ASSERT_LOG_ONLY(false, "uds request was timed out (state %d)",
				    atomic_read(&context->state));
	}

	vdo_funnel_queue_put(context->zone->timed_out_complete, &context->queue_entry);
}

/**
 * check_for_drain_complete() - Check whether this zone has drained.
 * @zone: The zone to check.
 */
static void check_for_drain_complete(struct hash_zone *zone)
{
	data_vio_count_t recycled = 0;

	if (!vdo_is_state_draining(&zone->state))
		return;

	if ((atomic_read(&zone->timer_state) == DEDUPE_QUERY_TIMER_IDLE) ||
	    change_timer_state(zone, DEDUPE_QUERY_TIMER_RUNNING,
			       DEDUPE_QUERY_TIMER_IDLE)) {
		timer_delete_sync(&zone->timer);
	} else {
		/*
		 * There is an in flight time-out, which must get processed before we can continue.
		 */
		return;
	}

	for (;;) {
		struct dedupe_context *context;
		struct funnel_queue_entry *entry;

		entry = vdo_funnel_queue_poll(zone->timed_out_complete);
		if (entry == NULL)
			break;

		context = container_of(entry, struct dedupe_context, queue_entry);
		atomic_set(&context->state, DEDUPE_CONTEXT_IDLE);
		list_add(&context->list_entry, &zone->available);
		recycled++;
	}

	if (recycled > 0)
		WRITE_ONCE(zone->active, zone->active - recycled);
	VDO_ASSERT_LOG_ONLY(READ_ONCE(zone->active) == 0, "all contexts inactive");
	vdo_finish_draining(&zone->state);
}

static void timeout_index_operations_callback(struct vdo_completion *completion)
{
	struct dedupe_context *context, *tmp;
	struct hash_zone *zone = as_hash_zone(completion);
	u64 timeout_jiffies = msecs_to_jiffies(vdo_dedupe_index_timeout_interval);
	unsigned long cutoff = jiffies - timeout_jiffies;
	unsigned int timed_out = 0;

	atomic_set(&zone->timer_state, DEDUPE_QUERY_TIMER_IDLE);
	list_for_each_entry_safe(context, tmp, &zone->pending, list_entry) {
		if (cutoff <= context->submission_jiffies) {
			/*
			 * We have reached the oldest query which has not timed out yet, so restart
			 * the timer.
			 */
			start_expiration_timer(context);
			break;
		}

		if (!change_context_state(context, DEDUPE_CONTEXT_PENDING,
					  DEDUPE_CONTEXT_TIMED_OUT)) {
			/*
			 * This context completed between the time the timeout fired, and now. We
			 * can treat it as a successful query, its requestor is already enqueued
			 * to process it.
			 */
			continue;
		}

		/*
		 * Remove this context from the pending list so we won't look at it again on a
		 * subsequent timeout. Once the index completes it, it will be reused. Meanwhile,
		 * send its requestor on its way.
		 */
		list_del_init(&context->list_entry);
		context->requestor->dedupe_context = NULL;
		continue_data_vio(context->requestor);
		timed_out++;
	}

	if (timed_out > 0)
		report_dedupe_timeouts(completion->vdo->hash_zones, timed_out);

	check_for_drain_complete(zone);
}

static void timeout_index_operations(struct timer_list *t)
{
	struct hash_zone *zone = timer_container_of(zone, t, timer);

	if (change_timer_state(zone, DEDUPE_QUERY_TIMER_RUNNING,
			       DEDUPE_QUERY_TIMER_FIRED))
		vdo_launch_completion(&zone->completion);
}

static int __must_check initialize_zone(struct vdo *vdo, struct hash_zones *zones,
					zone_count_t zone_number)
{
	int result;
	data_vio_count_t i;
	struct hash_zone *zone = &zones->zones[zone_number];

	result = vdo_int_map_create(VDO_LOCK_MAP_CAPACITY, &zone->hash_lock_map);
	if (result != VDO_SUCCESS)
		return result;

	vdo_set_admin_state_code(&zone->state, VDO_ADMIN_STATE_NORMAL_OPERATION);
	zone->zone_number = zone_number;
	zone->thread_id = vdo->thread_config.hash_zone_threads[zone_number];
	vdo_initialize_completion(&zone->completion, vdo, VDO_HASH_ZONE_COMPLETION);
	vdo_set_completion_callback(&zone->completion, timeout_index_operations_callback,
				    zone->thread_id);
	INIT_LIST_HEAD(&zone->lock_pool);
	result = vdo_allocate(LOCK_POOL_CAPACITY, "hash_lock array", &zone->lock_array);
	if (result != VDO_SUCCESS)
		return result;

	for (i = 0; i < LOCK_POOL_CAPACITY; i++)
		return_hash_lock_to_pool(zone, &zone->lock_array[i]);

	INIT_LIST_HEAD(&zone->available);
	INIT_LIST_HEAD(&zone->pending);
	result = vdo_make_funnel_queue(&zone->timed_out_complete);
	if (result != VDO_SUCCESS)
		return result;

	timer_setup(&zone->timer, timeout_index_operations, 0);

	for (i = 0; i < MAXIMUM_VDO_USER_VIOS; i++) {
		struct dedupe_context *context = &zone->contexts[i];

		context->zone = zone;
		context->request.callback = finish_index_operation;
		context->request.session = zones->index_session;
		list_add(&context->list_entry, &zone->available);
	}

	return vdo_make_default_thread(vdo, zone->thread_id);
}

/** get_thread_id_for_zone() - Implements vdo_zone_thread_getter_fn. */
static thread_id_t get_thread_id_for_zone(void *context, zone_count_t zone_number)
{
	struct hash_zones *zones = context;

	return zones->zones[zone_number].thread_id;
}

/**
 * vdo_make_hash_zones() - Create the hash zones.
 *
 * @vdo: The vdo to which the zone will belong.
 * @zones_ptr: A pointer to hold the zones.
 *
 * Return: VDO_SUCCESS or an error code.
 */
int vdo_make_hash_zones(struct vdo *vdo, struct hash_zones **zones_ptr)
{
	int result;
	struct hash_zones *zones;
	zone_count_t z;
	zone_count_t zone_count = vdo->thread_config.hash_zone_count;

	if (zone_count == 0)
		return VDO_SUCCESS;

	result = vdo_allocate_extended(zone_count, zones, __func__, &zones);
	if (result != VDO_SUCCESS)
		return result;

	result = initialize_index(vdo, zones);
	if (result != VDO_SUCCESS) {
		vdo_free(zones);
		return result;
	}

	vdo_set_admin_state_code(&zones->state, VDO_ADMIN_STATE_NEW);

	zones->zone_count = zone_count;
	for (z = 0; z < zone_count; z++) {
		result = initialize_zone(vdo, zones, z);
		if (result != VDO_SUCCESS) {
			vdo_free_hash_zones(zones);
			return result;
		}
	}

	result = vdo_make_action_manager(zones->zone_count, get_thread_id_for_zone,
					 vdo->thread_config.admin_thread, zones, NULL,
					 vdo, &zones->manager);
	if (result != VDO_SUCCESS) {
		vdo_free_hash_zones(zones);
		return result;
	}

	*zones_ptr = zones;
	return VDO_SUCCESS;
}

void vdo_finish_dedupe_index(struct hash_zones *zones)
{
	if (zones == NULL)
		return;

	uds_destroy_index_session(vdo_forget(zones->index_session));
}

/**
 * vdo_free_hash_zones() - Free the hash zones.
 * @zones: The zone to free.
 */
void vdo_free_hash_zones(struct hash_zones *zones)
{
	zone_count_t i;

	if (zones == NULL)
		return;

	vdo_free(vdo_forget(zones->manager));

	for (i = 0; i < zones->zone_count; i++) {
		struct hash_zone *zone = &zones->zones[i];

		vdo_free_funnel_queue(vdo_forget(zone->timed_out_complete));
		vdo_int_map_free(vdo_forget(zone->hash_lock_map));
		vdo_free(vdo_forget(zone->lock_array));
	}

	if (zones->index_session != NULL)
		vdo_finish_dedupe_index(zones);

	ratelimit_state_exit(&zones->ratelimiter);
	vdo_free(zones);
}

static void initiate_suspend_index(struct admin_state *state)
{
	struct hash_zones *zones = container_of(state, struct hash_zones, state);
	enum index_state index_state;

	spin_lock(&zones->lock);
	index_state = zones->index_state;
	spin_unlock(&zones->lock);

	if (index_state != IS_CLOSED) {
		bool save = vdo_is_state_saving(&zones->state);
		int result;

		result = uds_suspend_index_session(zones->index_session, save);
		if (result != UDS_SUCCESS)
			vdo_log_error_strerror(result, "Error suspending dedupe index");
	}

	vdo_finish_draining(state);
}

/**
 * suspend_index() - Suspend the UDS index prior to draining hash zones.
 * @context: Not used.
 * @completion: The completion for the suspend operation.
 *
 * Implements vdo_action_preamble_fn
 */
static void suspend_index(void *context, struct vdo_completion *completion)
{
	struct hash_zones *zones = context;

	vdo_start_draining(&zones->state,
			   vdo_get_current_manager_operation(zones->manager), completion,
			   initiate_suspend_index);
}

/** Implements vdo_admin_initiator_fn. */
static void initiate_drain(struct admin_state *state)
{
	check_for_drain_complete(container_of(state, struct hash_zone, state));
}

/** Implements vdo_zone_action_fn. */
static void drain_hash_zone(void *context, zone_count_t zone_number,
			    struct vdo_completion *parent)
{
	struct hash_zones *zones = context;

	vdo_start_draining(&zones->zones[zone_number].state,
			   vdo_get_current_manager_operation(zones->manager), parent,
			   initiate_drain);
}

/** vdo_drain_hash_zones() - Drain all hash zones. */
void vdo_drain_hash_zones(struct hash_zones *zones, struct vdo_completion *parent)
{
	vdo_schedule_operation(zones->manager, parent->vdo->suspend_type, suspend_index,
			       drain_hash_zone, NULL, parent);
}

static void launch_dedupe_state_change(struct hash_zones *zones)
	__must_hold(&zones->lock)
{
	/* ASSERTION: We enter with the lock held. */
	if (zones->changing || !vdo_is_state_normal(&zones->state))
		/* Either a change is already in progress, or changes are not allowed. */
		return;

	if (zones->create_flag || (zones->index_state != zones->index_target)) {
		zones->changing = true;
		vdo_launch_completion(&zones->completion);
		return;
	}

	/* ASSERTION: We exit with the lock held. */
}

/**
 * resume_index() - Resume the UDS index prior to resuming hash zones.
 * @context: Not used.
 * @parent: The completion for the resume operation.
 *
 * Implements vdo_action_preamble_fn
 */
static void resume_index(void *context, struct vdo_completion *parent)
{
	struct hash_zones *zones = context;
	struct device_config *config = parent->vdo->device_config;
	int result;

	zones->parameters.bdev = config->owned_device->bdev;
	result = uds_resume_index_session(zones->index_session, zones->parameters.bdev);
	if (result != UDS_SUCCESS)
		vdo_log_error_strerror(result, "Error resuming dedupe index");

	spin_lock(&zones->lock);
	vdo_resume_if_quiescent(&zones->state);

	if (config->deduplication) {
		zones->index_target = IS_OPENED;
		WRITE_ONCE(zones->dedupe_flag, true);
	} else {
		zones->index_target = IS_CLOSED;
	}

	launch_dedupe_state_change(zones);
	spin_unlock(&zones->lock);

	vdo_finish_completion(parent);
}

/** Implements vdo_zone_action_fn. */
static void resume_hash_zone(void *context, zone_count_t zone_number,
			     struct vdo_completion *parent)
{
	struct hash_zone *zone = &(((struct hash_zones *) context)->zones[zone_number]);

	vdo_fail_completion(parent, vdo_resume_if_quiescent(&zone->state));
}

/**
 * vdo_resume_hash_zones() - Resume a set of hash zones.
 * @zones: The hash zones to resume.
 * @parent: The object to notify when the zones have resumed.
 */
void vdo_resume_hash_zones(struct hash_zones *zones, struct vdo_completion *parent)
{
	if (vdo_is_read_only(parent->vdo)) {
		vdo_launch_completion(parent);
		return;
	}

	vdo_schedule_operation(zones->manager, VDO_ADMIN_STATE_RESUMING, resume_index,
			       resume_hash_zone, NULL, parent);
}

/**
 * get_hash_zone_statistics() - Add the statistics for this hash zone to the tally for all zones.
 * @zone: The hash zone to query.
 * @tally: The tally.
 */
static void get_hash_zone_statistics(const struct hash_zone *zone,
				     struct hash_lock_statistics *tally)
{
	const struct hash_lock_statistics *stats = &zone->statistics;

	tally->dedupe_advice_valid += READ_ONCE(stats->dedupe_advice_valid);
	tally->dedupe_advice_stale += READ_ONCE(stats->dedupe_advice_stale);
	tally->concurrent_data_matches += READ_ONCE(stats->concurrent_data_matches);
	tally->concurrent_hash_collisions += READ_ONCE(stats->concurrent_hash_collisions);
	tally->curr_dedupe_queries += READ_ONCE(zone->active);
}

static void get_index_statistics(struct hash_zones *zones,
				 struct index_statistics *stats)
{
	enum index_state state;
	struct uds_index_stats index_stats;
	int result;

	spin_lock(&zones->lock);
	state = zones->index_state;
	spin_unlock(&zones->lock);

	if (state != IS_OPENED)
		return;

	result = uds_get_index_session_stats(zones->index_session, &index_stats);
	if (result != UDS_SUCCESS) {
		vdo_log_error_strerror(result, "Error reading index stats");
		return;
	}

	stats->entries_indexed = index_stats.entries_indexed;
	stats->posts_found = index_stats.posts_found;
	stats->posts_not_found = index_stats.posts_not_found;
	stats->queries_found = index_stats.queries_found;
	stats->queries_not_found = index_stats.queries_not_found;
	stats->updates_found = index_stats.updates_found;
	stats->updates_not_found = index_stats.updates_not_found;
	stats->entries_discarded = index_stats.entries_discarded;
}

/**
 * vdo_get_dedupe_statistics() - Tally the statistics from all the hash zones and the UDS index.
 * @zones: The hash zones to query.
 * @stats: A structure to store the statistics.
 *
 * Return: The sum of the hash lock statistics from all hash zones plus the statistics from the UDS
 *         index
 */
void vdo_get_dedupe_statistics(struct hash_zones *zones, struct vdo_statistics *stats)

{
	zone_count_t zone;

	for (zone = 0; zone < zones->zone_count; zone++)
		get_hash_zone_statistics(&zones->zones[zone], &stats->hash_lock);

	get_index_statistics(zones, &stats->index);

	/*
	 * zones->timeouts gives the number of timeouts, and dedupe_context_busy gives the number
	 * of queries not made because of earlier timeouts.
	 */
	stats->dedupe_advice_timeouts =
		(atomic64_read(&zones->timeouts) + atomic64_read(&zones->dedupe_context_busy));
}

/**
 * vdo_select_hash_zone() - Select the hash zone responsible for locking a given record name.
 * @zones: The hash_zones from which to select.
 * @name: The record name.
 *
 * Return: The hash zone responsible for the record name.
 */
struct hash_zone *vdo_select_hash_zone(struct hash_zones *zones,
				       const struct uds_record_name *name)
{
	/*
	 * Use a fragment of the record name as a hash code. Eight bits of hash should suffice
	 * since the number of hash zones is small.
	 * TODO: Verify that the first byte is independent enough.
	 */
	u32 hash = name->name[0];

	/*
	 * Scale the 8-bit hash fragment to a zone index by treating it as a binary fraction and
	 * multiplying that by the zone count. If the hash is uniformly distributed over [0 ..
	 * 2^8-1], then (hash * count / 2^8) should be uniformly distributed over [0 .. count-1].
	 * The multiply and shift is much faster than a divide (modulus) on X86 CPUs.
	 */
	hash = (hash * zones->zone_count) >> 8;
	return &zones->zones[hash];
}

/**
 * dump_hash_lock() - Dump a compact description of hash_lock to the log if the lock is not on the
 *                    free list.
 * @lock: The hash lock to dump.
 */
static void dump_hash_lock(const struct hash_lock *lock)
{
	const char *state;

	if (!list_empty(&lock->pool_node)) {
		/* This lock is on the free list. */
		return;
	}

	/*
	 * Necessarily cryptic since we can log a lot of these. First three chars of state is
	 * unambiguous. 'U' indicates a lock not registered in the map.
	 */
	state = get_hash_lock_state_name(lock->state);
	vdo_log_info("  hl %px: %3.3s %c%llu/%u rc=%u wc=%zu agt=%px",
		     lock, state, (lock->registered ? 'D' : 'U'),
		     (unsigned long long) lock->duplicate.pbn,
		     lock->duplicate.state, lock->reference_count,
		     vdo_waitq_num_waiters(&lock->waiters), lock->agent);
}

static const char *index_state_to_string(struct hash_zones *zones,
					 enum index_state state)
{
	if (!vdo_is_state_normal(&zones->state))
		return SUSPENDED;

	switch (state) {
	case IS_CLOSED:
		return zones->error_flag ? ERROR : CLOSED;
	case IS_CHANGING:
		return zones->index_target == IS_OPENED ? OPENING : CLOSING;
	case IS_OPENED:
		return READ_ONCE(zones->dedupe_flag) ? ONLINE : OFFLINE;
	default:
		return UNKNOWN;
	}
}

/**
 * dump_hash_zone() - Dump information about a hash zone to the log for debugging.
 * @zone: The zone to dump.
 */
static void dump_hash_zone(const struct hash_zone *zone)
{
	data_vio_count_t i;

	if (zone->hash_lock_map == NULL) {
		vdo_log_info("struct hash_zone %u: NULL map", zone->zone_number);
		return;
	}

	vdo_log_info("struct hash_zone %u: mapSize=%zu",
		     zone->zone_number, vdo_int_map_size(zone->hash_lock_map));
	for (i = 0; i < LOCK_POOL_CAPACITY; i++)
		dump_hash_lock(&zone->lock_array[i]);
}

/**
 * vdo_dump_hash_zones() - Dump information about the hash zones to the log for debugging.
 * @zones: The zones to dump.
 */
void vdo_dump_hash_zones(struct hash_zones *zones)
{
	const char *state, *target;
	zone_count_t zone;

	spin_lock(&zones->lock);
	state = index_state_to_string(zones, zones->index_state);
	target = (zones->changing ? index_state_to_string(zones, zones->index_target) : NULL);
	spin_unlock(&zones->lock);

	vdo_log_info("UDS index: state: %s", state);
	if (target != NULL)
		vdo_log_info("UDS index: changing to state: %s", target);

	for (zone = 0; zone < zones->zone_count; zone++)
		dump_hash_zone(&zones->zones[zone]);
}

void vdo_set_dedupe_index_timeout_interval(unsigned int value)
{
	u64 alb_jiffies;

	/* Arbitrary maximum value is two minutes */
	if (value > 120000)
		value = 120000;
	/* Arbitrary minimum value is 2 jiffies */
	alb_jiffies = msecs_to_jiffies(value);

	if (alb_jiffies < 2) {
		alb_jiffies = 2;
		value = jiffies_to_msecs(alb_jiffies);
	}
	vdo_dedupe_index_timeout_interval = value;
	vdo_dedupe_index_timeout_jiffies = alb_jiffies;
}

void vdo_set_dedupe_index_min_timer_interval(unsigned int value)
{
	u64 min_jiffies;

	/* Arbitrary maximum value is one second */
	if (value > 1000)
		value = 1000;

	/* Arbitrary minimum value is 2 jiffies */
	min_jiffies = msecs_to_jiffies(value);

	if (min_jiffies < 2) {
		min_jiffies = 2;
		value = jiffies_to_msecs(min_jiffies);
	}

	vdo_dedupe_index_min_timer_interval = value;
	vdo_dedupe_index_min_timer_jiffies = min_jiffies;
}

/**
 * acquire_context() - Acquire a dedupe context from a hash_zone if any are available.
 * @zone: The hash zone.
 *
 * Return: A dedupe_context or NULL if none are available.
 */
static struct dedupe_context * __must_check acquire_context(struct hash_zone *zone)
{
	struct dedupe_context *context;
	struct funnel_queue_entry *entry;

	assert_in_hash_zone(zone, __func__);

	if (!list_empty(&zone->available)) {
		WRITE_ONCE(zone->active, zone->active + 1);
		context = list_first_entry(&zone->available, struct dedupe_context,
					   list_entry);
		list_del_init(&context->list_entry);
		return context;
	}

	entry = vdo_funnel_queue_poll(zone->timed_out_complete);
	return ((entry == NULL) ?
		NULL : container_of(entry, struct dedupe_context, queue_entry));
}

static void prepare_uds_request(struct uds_request *request, struct data_vio *data_vio,
				enum uds_request_type operation)
{
	request->record_name = data_vio->record_name;
	request->type = operation;
	if ((operation == UDS_POST) || (operation == UDS_UPDATE)) {
		size_t offset = 0;
		struct uds_record_data *encoding = &request->new_metadata;

		encoding->data[offset++] = UDS_ADVICE_VERSION;
		encoding->data[offset++] = data_vio->new_mapped.state;
		put_unaligned_le64(data_vio->new_mapped.pbn, &encoding->data[offset]);
		offset += sizeof(u64);
		BUG_ON(offset != UDS_ADVICE_SIZE);
	}
}

/*
 * The index operation will inquire about data_vio.record_name, providing (if the operation is
 * appropriate) advice from the data_vio's new_mapped fields. The advice found in the index (or
 * NULL if none) will be returned via receive_data_vio_dedupe_advice(). dedupe_context.status is
 * set to the return status code of any asynchronous index processing.
 */
static void query_index(struct data_vio *data_vio, enum uds_request_type operation)
{
	int result;
	struct dedupe_context *context;
	struct vdo *vdo = vdo_from_data_vio(data_vio);
	struct hash_zone *zone = data_vio->hash_zone;

	assert_data_vio_in_hash_zone(data_vio);

	if (!READ_ONCE(vdo->hash_zones->dedupe_flag)) {
		continue_data_vio(data_vio);
		return;
	}

	context = acquire_context(zone);
	if (context == NULL) {
		atomic64_inc(&vdo->hash_zones->dedupe_context_busy);
		continue_data_vio(data_vio);
		return;
	}

	data_vio->dedupe_context = context;
	context->requestor = data_vio;
	context->submission_jiffies = jiffies;
	prepare_uds_request(&context->request, data_vio, operation);
	atomic_set(&context->state, DEDUPE_CONTEXT_PENDING);
	list_add_tail(&context->list_entry, &zone->pending);
	start_expiration_timer(context);
	result = uds_launch_request(&context->request);
	if (result != UDS_SUCCESS) {
		context->request.status = result;
		finish_index_operation(&context->request);
	}
}

static void set_target_state(struct hash_zones *zones, enum index_state target,
			     bool change_dedupe, bool dedupe, bool set_create)
{
	const char *old_state, *new_state;

	spin_lock(&zones->lock);
	old_state = index_state_to_string(zones, zones->index_target);
	if (change_dedupe)
		WRITE_ONCE(zones->dedupe_flag, dedupe);

	if (set_create)
		zones->create_flag = true;

	zones->index_target = target;
	launch_dedupe_state_change(zones);
	new_state = index_state_to_string(zones, zones->index_target);
	spin_unlock(&zones->lock);

	if (old_state != new_state)
		vdo_log_info("Setting UDS index target state to %s", new_state);
}

const char *vdo_get_dedupe_index_state_name(struct hash_zones *zones)
{
	const char *state;

	spin_lock(&zones->lock);
	state = index_state_to_string(zones, zones->index_state);
	spin_unlock(&zones->lock);

	return state;
}

/* Handle a dmsetup message relevant to the index. */
int vdo_message_dedupe_index(struct hash_zones *zones, const char *name)
{
	if (strcasecmp(name, "index-close") == 0) {
		set_target_state(zones, IS_CLOSED, false, false, false);
		return 0;
	} else if (strcasecmp(name, "index-create") == 0) {
		set_target_state(zones, IS_OPENED, false, false, true);
		return 0;
	} else if (strcasecmp(name, "index-disable") == 0) {
		set_target_state(zones, IS_OPENED, true, false, false);
		return 0;
	} else if (strcasecmp(name, "index-enable") == 0) {
		set_target_state(zones, IS_OPENED, true, true, false);
		return 0;
	}

	return -EINVAL;
}

void vdo_set_dedupe_state_normal(struct hash_zones *zones)
{
	vdo_set_admin_state_code(&zones->state, VDO_ADMIN_STATE_NORMAL_OPERATION);
}

/* If create_flag, create a new index without first attempting to load an existing index. */
void vdo_start_dedupe_index(struct hash_zones *zones, bool create_flag)
{
	set_target_state(zones, IS_OPENED, true, true, create_flag);
}
