// 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[];
};

/* 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, struct hash_lock, "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(struct hash_zones, zone_count, struct hash_zone,
				       __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);
}
