// 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"

struct uds_attribute {
	struct attribute attr;
	const char *(*show_string)(struct hash_zones *hash_zones);
};

#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_ring;

	/* 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_ring);
	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 ring 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 ring 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_ring);
		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 *context __always_unused)
{
	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;

	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.
 *
 * 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);
		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.
 * @data_vio: The data_vio 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_ring))
		return false;

	lock_holder = list_first_entry(&lock->duplicate_ring, 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 ring");
	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.
 * @data_vio: The data_vio 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 ring");
	VDO_ASSERT_LOG_ONLY(list_empty(&lock->duplicate_ring),
			    "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);

	/*
	 * 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)) {
		del_timer_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);
		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 = from_timer(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.
 *
 * 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);
}

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

/**
 * drain_hash_zone() - Drain a hash zone.
 *
 * 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.
 *
 * 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);
}

/**
 * resume_hash_zone() - Resume a hash zone.
 *
 * 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.
 * @hash_zones: The hash zones to query
 *
 * 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);
}
