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

#include <linux/atomic.h>
#include <linux/bitops.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/device-mapper.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>

#include "admin-state.h"
#include "block-map.h"
#include "completion.h"
#include "constants.h"
#include "data-vio.h"
#include "dedupe.h"
#include "dump.h"
#include "encodings.h"
#include "errors.h"
#include "flush.h"
#include "io-submitter.h"
#include "logger.h"
#include "memory-alloc.h"
#include "message-stats.h"
#include "recovery-journal.h"
#include "repair.h"
#include "slab-depot.h"
#include "status-codes.h"
#include "string-utils.h"
#include "thread-device.h"
#include "thread-registry.h"
#include "thread-utils.h"
#include "types.h"
#include "vdo.h"
#include "vio.h"

enum admin_phases {
	GROW_LOGICAL_PHASE_START,
	GROW_LOGICAL_PHASE_GROW_BLOCK_MAP,
	GROW_LOGICAL_PHASE_END,
	GROW_LOGICAL_PHASE_ERROR,
	GROW_PHYSICAL_PHASE_START,
	GROW_PHYSICAL_PHASE_COPY_SUMMARY,
	GROW_PHYSICAL_PHASE_UPDATE_COMPONENTS,
	GROW_PHYSICAL_PHASE_USE_NEW_SLABS,
	GROW_PHYSICAL_PHASE_END,
	GROW_PHYSICAL_PHASE_ERROR,
	LOAD_PHASE_START,
	LOAD_PHASE_LOAD_DEPOT,
	LOAD_PHASE_MAKE_DIRTY,
	LOAD_PHASE_PREPARE_TO_ALLOCATE,
	LOAD_PHASE_SCRUB_SLABS,
	LOAD_PHASE_DATA_REDUCTION,
	LOAD_PHASE_FINISHED,
	LOAD_PHASE_DRAIN_JOURNAL,
	LOAD_PHASE_WAIT_FOR_READ_ONLY,
	PRE_LOAD_PHASE_START,
	PRE_LOAD_PHASE_LOAD_COMPONENTS,
	PRE_LOAD_PHASE_END,
	PREPARE_GROW_PHYSICAL_PHASE_START,
	RESUME_PHASE_START,
	RESUME_PHASE_ALLOW_READ_ONLY_MODE,
	RESUME_PHASE_DEDUPE,
	RESUME_PHASE_DEPOT,
	RESUME_PHASE_JOURNAL,
	RESUME_PHASE_BLOCK_MAP,
	RESUME_PHASE_LOGICAL_ZONES,
	RESUME_PHASE_PACKER,
	RESUME_PHASE_FLUSHER,
	RESUME_PHASE_DATA_VIOS,
	RESUME_PHASE_END,
	SUSPEND_PHASE_START,
	SUSPEND_PHASE_PACKER,
	SUSPEND_PHASE_DATA_VIOS,
	SUSPEND_PHASE_DEDUPE,
	SUSPEND_PHASE_FLUSHES,
	SUSPEND_PHASE_LOGICAL_ZONES,
	SUSPEND_PHASE_BLOCK_MAP,
	SUSPEND_PHASE_JOURNAL,
	SUSPEND_PHASE_DEPOT,
	SUSPEND_PHASE_READ_ONLY_WAIT,
	SUSPEND_PHASE_WRITE_SUPER_BLOCK,
	SUSPEND_PHASE_END,
};

static const char * const ADMIN_PHASE_NAMES[] = {
	"GROW_LOGICAL_PHASE_START",
	"GROW_LOGICAL_PHASE_GROW_BLOCK_MAP",
	"GROW_LOGICAL_PHASE_END",
	"GROW_LOGICAL_PHASE_ERROR",
	"GROW_PHYSICAL_PHASE_START",
	"GROW_PHYSICAL_PHASE_COPY_SUMMARY",
	"GROW_PHYSICAL_PHASE_UPDATE_COMPONENTS",
	"GROW_PHYSICAL_PHASE_USE_NEW_SLABS",
	"GROW_PHYSICAL_PHASE_END",
	"GROW_PHYSICAL_PHASE_ERROR",
	"LOAD_PHASE_START",
	"LOAD_PHASE_LOAD_DEPOT",
	"LOAD_PHASE_MAKE_DIRTY",
	"LOAD_PHASE_PREPARE_TO_ALLOCATE",
	"LOAD_PHASE_SCRUB_SLABS",
	"LOAD_PHASE_DATA_REDUCTION",
	"LOAD_PHASE_FINISHED",
	"LOAD_PHASE_DRAIN_JOURNAL",
	"LOAD_PHASE_WAIT_FOR_READ_ONLY",
	"PRE_LOAD_PHASE_START",
	"PRE_LOAD_PHASE_LOAD_COMPONENTS",
	"PRE_LOAD_PHASE_END",
	"PREPARE_GROW_PHYSICAL_PHASE_START",
	"RESUME_PHASE_START",
	"RESUME_PHASE_ALLOW_READ_ONLY_MODE",
	"RESUME_PHASE_DEDUPE",
	"RESUME_PHASE_DEPOT",
	"RESUME_PHASE_JOURNAL",
	"RESUME_PHASE_BLOCK_MAP",
	"RESUME_PHASE_LOGICAL_ZONES",
	"RESUME_PHASE_PACKER",
	"RESUME_PHASE_FLUSHER",
	"RESUME_PHASE_DATA_VIOS",
	"RESUME_PHASE_END",
	"SUSPEND_PHASE_START",
	"SUSPEND_PHASE_PACKER",
	"SUSPEND_PHASE_DATA_VIOS",
	"SUSPEND_PHASE_DEDUPE",
	"SUSPEND_PHASE_FLUSHES",
	"SUSPEND_PHASE_LOGICAL_ZONES",
	"SUSPEND_PHASE_BLOCK_MAP",
	"SUSPEND_PHASE_JOURNAL",
	"SUSPEND_PHASE_DEPOT",
	"SUSPEND_PHASE_READ_ONLY_WAIT",
	"SUSPEND_PHASE_WRITE_SUPER_BLOCK",
	"SUSPEND_PHASE_END",
};

/* If we bump this, update the arrays below */
#define TABLE_VERSION 4

/* arrays for handling different table versions */
static const u8 REQUIRED_ARGC[] = { 10, 12, 9, 7, 6 };
/* pool name no longer used. only here for verification of older versions */
static const u8 POOL_NAME_ARG_INDEX[] = { 8, 10, 8 };

/*
 * Track in-use instance numbers using a flat bit array.
 *
 * O(n) run time isn't ideal, but if we have 1000 VDO devices in use simultaneously we still only
 * need to scan 16 words, so it's not likely to be a big deal compared to other resource usage.
 */

/*
 * This minimum size for the bit array creates a numbering space of 0-999, which allows
 * successive starts of the same volume to have different instance numbers in any
 * reasonably-sized test. Changing instances on restart allows vdoMonReport to detect that
 * the ephemeral stats have reset to zero.
 */
#define BIT_COUNT_MINIMUM 1000
/* Grow the bit array by this many bits when needed */
#define BIT_COUNT_INCREMENT 100

struct instance_tracker {
	unsigned int bit_count;
	unsigned long *words;
	unsigned int count;
	unsigned int next;
};

static DEFINE_MUTEX(instances_lock);
static struct instance_tracker instances;

/**
 * free_device_config() - Free a device config created by parse_device_config().
 * @config: The config to free.
 */
static void free_device_config(struct device_config *config)
{
	if (config == NULL)
		return;

	if (config->owned_device != NULL)
		dm_put_device(config->owning_target, config->owned_device);

	vdo_free(config->parent_device_name);
	vdo_free(config->original_string);

	/* Reduce the chance a use-after-free (as in BZ 1669960) happens to work. */
	memset(config, 0, sizeof(*config));
	vdo_free(config);
}

/**
 * get_version_number() - Decide the version number from argv.
 *
 * @argc: The number of table values.
 * @argv: The array of table values.
 * @error_ptr: A pointer to return a error string in.
 * @version_ptr: A pointer to return the version.
 *
 * Return: VDO_SUCCESS or an error code.
 */
static int get_version_number(int argc, char **argv, char **error_ptr,
			      unsigned int *version_ptr)
{
	/* version, if it exists, is in a form of V<n> */
	if (sscanf(argv[0], "V%u", version_ptr) == 1) {
		if (*version_ptr < 1 || *version_ptr > TABLE_VERSION) {
			*error_ptr = "Unknown version number detected";
			return VDO_BAD_CONFIGURATION;
		}
	} else {
		/* V0 actually has no version number in the table string */
		*version_ptr = 0;
	}

	/*
	 * V0 and V1 have no optional parameters. There will always be a parameter for thread
	 * config, even if it's a "." to show it's an empty list.
	 */
	if (*version_ptr <= 1) {
		if (argc != REQUIRED_ARGC[*version_ptr]) {
			*error_ptr = "Incorrect number of arguments for version";
			return VDO_BAD_CONFIGURATION;
		}
	} else if (argc < REQUIRED_ARGC[*version_ptr]) {
		*error_ptr = "Incorrect number of arguments for version";
		return VDO_BAD_CONFIGURATION;
	}

	if (*version_ptr != TABLE_VERSION) {
		vdo_log_warning("Detected version mismatch between kernel module and tools kernel: %d, tool: %d",
				TABLE_VERSION, *version_ptr);
		vdo_log_warning("Please consider upgrading management tools to match kernel.");
	}
	return VDO_SUCCESS;
}

/* Free a list of non-NULL string pointers, and then the list itself. */
static void free_string_array(char **string_array)
{
	unsigned int offset;

	for (offset = 0; string_array[offset] != NULL; offset++)
		vdo_free(string_array[offset]);
	vdo_free(string_array);
}

/*
 * Split the input string into substrings, separated at occurrences of the indicated character,
 * returning a null-terminated list of string pointers.
 *
 * The string pointers and the pointer array itself should both be freed with vdo_free() when no
 * longer needed. This can be done with vdo_free_string_array (below) if the pointers in the array
 * are not changed. Since the array and copied strings are allocated by this function, it may only
 * be used in contexts where allocation is permitted.
 *
 * Empty substrings are not ignored; that is, returned substrings may be empty strings if the
 * separator occurs twice in a row.
 */
static int split_string(const char *string, char separator, char ***substring_array_ptr)
{
	unsigned int current_substring = 0, substring_count = 1;
	const char *s;
	char **substrings;
	int result;
	ptrdiff_t length;

	for (s = string; *s != 0; s++) {
		if (*s == separator)
			substring_count++;
	}

	result = vdo_allocate(substring_count + 1, char *, "string-splitting array",
			      &substrings);
	if (result != VDO_SUCCESS)
		return result;

	for (s = string; *s != 0; s++) {
		if (*s == separator) {
			ptrdiff_t length = s - string;

			result = vdo_allocate(length + 1, char, "split string",
					      &substrings[current_substring]);
			if (result != VDO_SUCCESS) {
				free_string_array(substrings);
				return result;
			}
			/*
			 * Trailing NUL is already in place after allocation; deal with the zero or
			 * more non-NUL bytes in the string.
			 */
			if (length > 0)
				memcpy(substrings[current_substring], string, length);
			string = s + 1;
			current_substring++;
			BUG_ON(current_substring >= substring_count);
		}
	}
	/* Process final string, with no trailing separator. */
	BUG_ON(current_substring != (substring_count - 1));
	length = strlen(string);

	result = vdo_allocate(length + 1, char, "split string",
			      &substrings[current_substring]);
	if (result != VDO_SUCCESS) {
		free_string_array(substrings);
		return result;
	}
	memcpy(substrings[current_substring], string, length);
	current_substring++;
	/* substrings[current_substring] is NULL already */
	*substring_array_ptr = substrings;
	return VDO_SUCCESS;
}

/*
 * Join the input substrings into one string, joined with the indicated character, returning a
 * string. array_length is a bound on the number of valid elements in substring_array, in case it
 * is not NULL-terminated.
 */
static int join_strings(char **substring_array, size_t array_length, char separator,
			char **string_ptr)
{
	size_t string_length = 0;
	size_t i;
	int result;
	char *output, *current_position;

	for (i = 0; (i < array_length) && (substring_array[i] != NULL); i++)
		string_length += strlen(substring_array[i]) + 1;

	result = vdo_allocate(string_length, char, __func__, &output);
	if (result != VDO_SUCCESS)
		return result;

	current_position = &output[0];

	for (i = 0; (i < array_length) && (substring_array[i] != NULL); i++) {
		current_position = vdo_append_to_buffer(current_position,
							output + string_length, "%s",
							substring_array[i]);
		*current_position = separator;
		current_position++;
	}

	/* We output one too many separators; replace the last with a zero byte. */
	if (current_position != output)
		*(current_position - 1) = '\0';

	*string_ptr = output;
	return VDO_SUCCESS;
}

/**
 * parse_bool() - Parse a two-valued option into a bool.
 * @bool_str: The string value to convert to a bool.
 * @true_str: The string value which should be converted to true.
 * @false_str: The string value which should be converted to false.
 * @bool_ptr: A pointer to return the bool value in.
 *
 * Return: VDO_SUCCESS or an error if bool_str is neither true_str nor false_str.
 */
static inline int __must_check parse_bool(const char *bool_str, const char *true_str,
					  const char *false_str, bool *bool_ptr)
{
	bool value = false;

	if (strcmp(bool_str, true_str) == 0)
		value = true;
	else if (strcmp(bool_str, false_str) == 0)
		value = false;
	else
		return VDO_BAD_CONFIGURATION;

	*bool_ptr = value;
	return VDO_SUCCESS;
}

/**
 * process_one_thread_config_spec() - Process one component of a thread parameter configuration
 *				      string and update the configuration data structure.
 * @thread_param_type: The type of thread specified.
 * @count: The thread count requested.
 * @config: The configuration data structure to update.
 *
 * If the thread count requested is invalid, a message is logged and -EINVAL returned. If the
 * thread name is unknown, a message is logged but no error is returned.
 *
 * Return: VDO_SUCCESS or -EINVAL
 */
static int process_one_thread_config_spec(const char *thread_param_type,
					  unsigned int count,
					  struct thread_count_config *config)
{
	/* Handle limited thread parameters */
	if (strcmp(thread_param_type, "bioRotationInterval") == 0) {
		if (count == 0) {
			vdo_log_error("thread config string error:  'bioRotationInterval' of at least 1 is required");
			return -EINVAL;
		} else if (count > VDO_BIO_ROTATION_INTERVAL_LIMIT) {
			vdo_log_error("thread config string error: 'bioRotationInterval' cannot be higher than %d",
				      VDO_BIO_ROTATION_INTERVAL_LIMIT);
			return -EINVAL;
		}
		config->bio_rotation_interval = count;
		return VDO_SUCCESS;
	}
	if (strcmp(thread_param_type, "logical") == 0) {
		if (count > MAX_VDO_LOGICAL_ZONES) {
			vdo_log_error("thread config string error: at most %d 'logical' threads are allowed",
				      MAX_VDO_LOGICAL_ZONES);
			return -EINVAL;
		}
		config->logical_zones = count;
		return VDO_SUCCESS;
	}
	if (strcmp(thread_param_type, "physical") == 0) {
		if (count > MAX_VDO_PHYSICAL_ZONES) {
			vdo_log_error("thread config string error: at most %d 'physical' threads are allowed",
				      MAX_VDO_PHYSICAL_ZONES);
			return -EINVAL;
		}
		config->physical_zones = count;
		return VDO_SUCCESS;
	}
	/* Handle other thread count parameters */
	if (count > MAXIMUM_VDO_THREADS) {
		vdo_log_error("thread config string error: at most %d '%s' threads are allowed",
			      MAXIMUM_VDO_THREADS, thread_param_type);
		return -EINVAL;
	}
	if (strcmp(thread_param_type, "hash") == 0) {
		config->hash_zones = count;
		return VDO_SUCCESS;
	}
	if (strcmp(thread_param_type, "cpu") == 0) {
		if (count == 0) {
			vdo_log_error("thread config string error: at least one 'cpu' thread required");
			return -EINVAL;
		}
		config->cpu_threads = count;
		return VDO_SUCCESS;
	}
	if (strcmp(thread_param_type, "ack") == 0) {
		config->bio_ack_threads = count;
		return VDO_SUCCESS;
	}
	if (strcmp(thread_param_type, "bio") == 0) {
		if (count == 0) {
			vdo_log_error("thread config string error: at least one 'bio' thread required");
			return -EINVAL;
		}
		config->bio_threads = count;
		return VDO_SUCCESS;
	}

	/*
	 * Don't fail, just log. This will handle version mismatches between user mode tools and
	 * kernel.
	 */
	vdo_log_info("unknown thread parameter type \"%s\"", thread_param_type);
	return VDO_SUCCESS;
}

/**
 * parse_one_thread_config_spec() - Parse one component of a thread parameter configuration string
 *				    and update the configuration data structure.
 * @spec: The thread parameter specification string.
 * @config: The configuration data to be updated.
 */
static int parse_one_thread_config_spec(const char *spec,
					struct thread_count_config *config)
{
	unsigned int count;
	char **fields;
	int result;

	result = split_string(spec, '=', &fields);
	if (result != VDO_SUCCESS)
		return result;

	if ((fields[0] == NULL) || (fields[1] == NULL) || (fields[2] != NULL)) {
		vdo_log_error("thread config string error: expected thread parameter assignment, saw \"%s\"",
			      spec);
		free_string_array(fields);
		return -EINVAL;
	}

	result = kstrtouint(fields[1], 10, &count);
	if (result) {
		vdo_log_error("thread config string error: integer value needed, found \"%s\"",
			      fields[1]);
		free_string_array(fields);
		return result;
	}

	result = process_one_thread_config_spec(fields[0], count, config);
	free_string_array(fields);
	return result;
}

/**
 * parse_thread_config_string() - Parse the configuration string passed and update the specified
 *				  counts and other parameters of various types of threads to be
 *				  created.
 * @string: Thread parameter configuration string.
 * @config: The thread configuration data to update.
 *
 * The configuration string should contain one or more comma-separated specs of the form
 * "typename=number"; the supported type names are "cpu", "ack", "bio", "bioRotationInterval",
 * "logical", "physical", and "hash".
 *
 * If an error occurs during parsing of a single key/value pair, we deem it serious enough to stop
 * further parsing.
 *
 * This function can't set the "reason" value the caller wants to pass back, because we'd want to
 * format it to say which field was invalid, and we can't allocate the "reason" strings
 * dynamically. So if an error occurs, we'll log the details and pass back an error.
 *
 * Return: VDO_SUCCESS or -EINVAL or -ENOMEM
 */
static int parse_thread_config_string(const char *string,
				      struct thread_count_config *config)
{
	int result = VDO_SUCCESS;
	char **specs;

	if (strcmp(".", string) != 0) {
		unsigned int i;

		result = split_string(string, ',', &specs);
		if (result != VDO_SUCCESS)
			return result;

		for (i = 0; specs[i] != NULL; i++) {
			result = parse_one_thread_config_spec(specs[i], config);
			if (result != VDO_SUCCESS)
				break;
		}
		free_string_array(specs);
	}
	return result;
}

/**
 * process_one_key_value_pair() - Process one component of an optional parameter string and update
 *				  the configuration data structure.
 * @key: The optional parameter key name.
 * @value: The optional parameter value.
 * @config: The configuration data structure to update.
 *
 * If the value requested is invalid, a message is logged and -EINVAL returned. If the key is
 * unknown, a message is logged but no error is returned.
 *
 * Return: VDO_SUCCESS or -EINVAL
 */
static int process_one_key_value_pair(const char *key, unsigned int value,
				      struct device_config *config)
{
	/* Non thread optional parameters */
	if (strcmp(key, "maxDiscard") == 0) {
		if (value == 0) {
			vdo_log_error("optional parameter error: at least one max discard block required");
			return -EINVAL;
		}
		/* Max discard sectors in blkdev_issue_discard is UINT_MAX >> 9 */
		if (value > (UINT_MAX / VDO_BLOCK_SIZE)) {
			vdo_log_error("optional parameter error: at most %d max discard	 blocks are allowed",
				      UINT_MAX / VDO_BLOCK_SIZE);
			return -EINVAL;
		}
		config->max_discard_blocks = value;
		return VDO_SUCCESS;
	}
	/* Handles unknown key names */
	return process_one_thread_config_spec(key, value, &config->thread_counts);
}

/**
 * parse_one_key_value_pair() - Parse one key/value pair and update the configuration data
 *				structure.
 * @key: The optional key name.
 * @value: The optional value.
 * @config: The configuration data to be updated.
 *
 * Return: VDO_SUCCESS or error.
 */
static int parse_one_key_value_pair(const char *key, const char *value,
				    struct device_config *config)
{
	unsigned int count;
	int result;

	if (strcmp(key, "deduplication") == 0)
		return parse_bool(value, "on", "off", &config->deduplication);

	if (strcmp(key, "compression") == 0)
		return parse_bool(value, "on", "off", &config->compression);

	/* The remaining arguments must have integral values. */
	result = kstrtouint(value, 10, &count);
	if (result) {
		vdo_log_error("optional config string error: integer value needed, found \"%s\"",
			      value);
		return result;
	}
	return process_one_key_value_pair(key, count, config);
}

/**
 * parse_key_value_pairs() - Parse all key/value pairs from a list of arguments.
 * @argc: The total number of arguments in list.
 * @argv: The list of key/value pairs.
 * @config: The device configuration data to update.
 *
 * If an error occurs during parsing of a single key/value pair, we deem it serious enough to stop
 * further parsing.
 *
 * This function can't set the "reason" value the caller wants to pass back, because we'd want to
 * format it to say which field was invalid, and we can't allocate the "reason" strings
 * dynamically. So if an error occurs, we'll log the details and return the error.
 *
 * Return: VDO_SUCCESS or error
 */
static int parse_key_value_pairs(int argc, char **argv, struct device_config *config)
{
	int result = VDO_SUCCESS;

	while (argc) {
		result = parse_one_key_value_pair(argv[0], argv[1], config);
		if (result != VDO_SUCCESS)
			break;

		argc -= 2;
		argv += 2;
	}

	return result;
}

/**
 * parse_optional_arguments() - Parse the configuration string passed in for optional arguments.
 * @arg_set: The structure holding the arguments to parse.
 * @error_ptr: Pointer to a buffer to hold the error string.
 * @config: Pointer to device configuration data to update.
 *
 * For V0/V1 configurations, there will only be one optional parameter; the thread configuration.
 * The configuration string should contain one or more comma-separated specs of the form
 * "typename=number"; the supported type names are "cpu", "ack", "bio", "bioRotationInterval",
 * "logical", "physical", and "hash".
 *
 * For V2 configurations and beyond, there could be any number of arguments. They should contain
 * one or more key/value pairs separated by a space.
 *
 * Return: VDO_SUCCESS or error
 */
static int parse_optional_arguments(struct dm_arg_set *arg_set, char **error_ptr,
				    struct device_config *config)
{
	int result = VDO_SUCCESS;

	if (config->version == 0 || config->version == 1) {
		result = parse_thread_config_string(arg_set->argv[0],
						    &config->thread_counts);
		if (result != VDO_SUCCESS) {
			*error_ptr = "Invalid thread-count configuration";
			return VDO_BAD_CONFIGURATION;
		}
	} else {
		if ((arg_set->argc % 2) != 0) {
			*error_ptr = "Odd number of optional arguments given but they should be <key> <value> pairs";
			return VDO_BAD_CONFIGURATION;
		}
		result = parse_key_value_pairs(arg_set->argc, arg_set->argv, config);
		if (result != VDO_SUCCESS) {
			*error_ptr = "Invalid optional argument configuration";
			return VDO_BAD_CONFIGURATION;
		}
	}
	return result;
}

/**
 * handle_parse_error() - Handle a parsing error.
 * @config: The config to free.
 * @error_ptr: A place to store a constant string about the error.
 * @error_str: A constant string to store in error_ptr.
 */
static void handle_parse_error(struct device_config *config, char **error_ptr,
			       char *error_str)
{
	free_device_config(config);
	*error_ptr = error_str;
}

/**
 * parse_device_config() - Convert the dmsetup table into a struct device_config.
 * @argc: The number of table values.
 * @argv: The array of table values.
 * @ti: The target structure for this table.
 * @config_ptr: A pointer to return the allocated config.
 *
 * Return: VDO_SUCCESS or an error code.
 */
static int parse_device_config(int argc, char **argv, struct dm_target *ti,
			       struct device_config **config_ptr)
{
	bool enable_512e;
	size_t logical_bytes = to_bytes(ti->len);
	struct dm_arg_set arg_set;
	char **error_ptr = &ti->error;
	struct device_config *config = NULL;
	int result;

	if ((logical_bytes % VDO_BLOCK_SIZE) != 0) {
		handle_parse_error(config, error_ptr,
				   "Logical size must be a multiple of 4096");
		return VDO_BAD_CONFIGURATION;
	}

	if (argc == 0) {
		handle_parse_error(config, error_ptr, "Incorrect number of arguments");
		return VDO_BAD_CONFIGURATION;
	}

	result = vdo_allocate(1, struct device_config, "device_config", &config);
	if (result != VDO_SUCCESS) {
		handle_parse_error(config, error_ptr,
				   "Could not allocate config structure");
		return VDO_BAD_CONFIGURATION;
	}

	config->owning_target = ti;
	config->logical_blocks = logical_bytes / VDO_BLOCK_SIZE;
	INIT_LIST_HEAD(&config->config_list);

	/* Save the original string. */
	result = join_strings(argv, argc, ' ', &config->original_string);
	if (result != VDO_SUCCESS) {
		handle_parse_error(config, error_ptr, "Could not populate string");
		return VDO_BAD_CONFIGURATION;
	}

	vdo_log_info("table line: %s", config->original_string);

	config->thread_counts = (struct thread_count_config) {
		.bio_ack_threads = 1,
		.bio_threads = DEFAULT_VDO_BIO_SUBMIT_QUEUE_COUNT,
		.bio_rotation_interval = DEFAULT_VDO_BIO_SUBMIT_QUEUE_ROTATE_INTERVAL,
		.cpu_threads = 1,
		.logical_zones = 0,
		.physical_zones = 0,
		.hash_zones = 0,
	};
	config->max_discard_blocks = 1;
	config->deduplication = true;
	config->compression = false;

	arg_set.argc = argc;
	arg_set.argv = argv;

	result = get_version_number(argc, argv, error_ptr, &config->version);
	if (result != VDO_SUCCESS) {
		/* get_version_number sets error_ptr itself. */
		handle_parse_error(config, error_ptr, *error_ptr);
		return result;
	}
	/* Move the arg pointer forward only if the argument was there. */
	if (config->version >= 1)
		dm_shift_arg(&arg_set);

	result = vdo_duplicate_string(dm_shift_arg(&arg_set), "parent device name",
				      &config->parent_device_name);
	if (result != VDO_SUCCESS) {
		handle_parse_error(config, error_ptr,
				   "Could not copy parent device name");
		return VDO_BAD_CONFIGURATION;
	}

	/* Get the physical blocks, if known. */
	if (config->version >= 1) {
		result = kstrtoull(dm_shift_arg(&arg_set), 10, &config->physical_blocks);
		if (result != VDO_SUCCESS) {
			handle_parse_error(config, error_ptr,
					   "Invalid physical block count");
			return VDO_BAD_CONFIGURATION;
		}
	}

	/* Get the logical block size and validate */
	result = parse_bool(dm_shift_arg(&arg_set), "512", "4096", &enable_512e);
	if (result != VDO_SUCCESS) {
		handle_parse_error(config, error_ptr, "Invalid logical block size");
		return VDO_BAD_CONFIGURATION;
	}
	config->logical_block_size = (enable_512e ? 512 : 4096);

	/* Skip past the two no longer used read cache options. */
	if (config->version <= 1)
		dm_consume_args(&arg_set, 2);

	/* Get the page cache size. */
	result = kstrtouint(dm_shift_arg(&arg_set), 10, &config->cache_size);
	if (result != VDO_SUCCESS) {
		handle_parse_error(config, error_ptr,
				   "Invalid block map page cache size");
		return VDO_BAD_CONFIGURATION;
	}

	/* Get the block map era length. */
	result = kstrtouint(dm_shift_arg(&arg_set), 10, &config->block_map_maximum_age);
	if (result != VDO_SUCCESS) {
		handle_parse_error(config, error_ptr, "Invalid block map maximum age");
		return VDO_BAD_CONFIGURATION;
	}

	/* Skip past the no longer used MD RAID5 optimization mode */
	if (config->version <= 2)
		dm_consume_args(&arg_set, 1);

	/* Skip past the no longer used write policy setting */
	if (config->version <= 3)
		dm_consume_args(&arg_set, 1);

	/* Skip past the no longer used pool name for older table lines */
	if (config->version <= 2) {
		/*
		 * Make sure the enum to get the pool name from argv directly is still in sync with
		 * the parsing of the table line.
		 */
		if (&arg_set.argv[0] != &argv[POOL_NAME_ARG_INDEX[config->version]]) {
			handle_parse_error(config, error_ptr,
					   "Pool name not in expected location");
			return VDO_BAD_CONFIGURATION;
		}
		dm_shift_arg(&arg_set);
	}

	/* Get the optional arguments and validate. */
	result = parse_optional_arguments(&arg_set, error_ptr, config);
	if (result != VDO_SUCCESS) {
		/* parse_optional_arguments sets error_ptr itself. */
		handle_parse_error(config, error_ptr, *error_ptr);
		return result;
	}

	/*
	 * Logical, physical, and hash zone counts can all be zero; then we get one thread doing
	 * everything, our older configuration. If any zone count is non-zero, the others must be
	 * as well.
	 */
	if (((config->thread_counts.logical_zones == 0) !=
	     (config->thread_counts.physical_zones == 0)) ||
	    ((config->thread_counts.physical_zones == 0) !=
	     (config->thread_counts.hash_zones == 0))) {
		handle_parse_error(config, error_ptr,
				   "Logical, physical, and hash zones counts must all be zero or all non-zero");
		return VDO_BAD_CONFIGURATION;
	}

	if (config->cache_size <
	    (2 * MAXIMUM_VDO_USER_VIOS * config->thread_counts.logical_zones)) {
		handle_parse_error(config, error_ptr,
				   "Insufficient block map cache for logical zones");
		return VDO_BAD_CONFIGURATION;
	}

	result = dm_get_device(ti, config->parent_device_name,
			       dm_table_get_mode(ti->table), &config->owned_device);
	if (result != 0) {
		vdo_log_error("couldn't open device \"%s\": error %d",
			      config->parent_device_name, result);
		handle_parse_error(config, error_ptr, "Unable to open storage device");
		return VDO_BAD_CONFIGURATION;
	}

	if (config->version == 0) {
		u64 device_size = i_size_read(config->owned_device->bdev->bd_inode);

		config->physical_blocks = device_size / VDO_BLOCK_SIZE;
	}

	*config_ptr = config;
	return result;
}

static struct vdo *get_vdo_for_target(struct dm_target *ti)
{
	return ((struct device_config *) ti->private)->vdo;
}


static int vdo_map_bio(struct dm_target *ti, struct bio *bio)
{
	struct vdo *vdo = get_vdo_for_target(ti);
	struct vdo_work_queue *current_work_queue;
	const struct admin_state_code *code = vdo_get_admin_state_code(&vdo->admin.state);

	VDO_ASSERT_LOG_ONLY(code->normal, "vdo should not receive bios while in state %s",
			    code->name);

	/* Count all incoming bios. */
	vdo_count_bios(&vdo->stats.bios_in, bio);


	/* Handle empty bios.  Empty flush bios are not associated with a vio. */
	if ((bio_op(bio) == REQ_OP_FLUSH) || ((bio->bi_opf & REQ_PREFLUSH) != 0)) {
		vdo_launch_flush(vdo, bio);
		return DM_MAPIO_SUBMITTED;
	}

	/* This could deadlock, */
	current_work_queue = vdo_get_current_work_queue();
	BUG_ON((current_work_queue != NULL) &&
	       (vdo == vdo_get_work_queue_owner(current_work_queue)->vdo));
	vdo_launch_bio(vdo->data_vio_pool, bio);
	return DM_MAPIO_SUBMITTED;
}

static void vdo_io_hints(struct dm_target *ti, struct queue_limits *limits)
{
	struct vdo *vdo = get_vdo_for_target(ti);

	limits->logical_block_size = vdo->device_config->logical_block_size;
	limits->physical_block_size = VDO_BLOCK_SIZE;

	/* The minimum io size for random io */
	blk_limits_io_min(limits, VDO_BLOCK_SIZE);
	/* The optimal io size for streamed/sequential io */
	blk_limits_io_opt(limits, VDO_BLOCK_SIZE);

	/*
	 * Sets the maximum discard size that will be passed into VDO. This value comes from a
	 * table line value passed in during dmsetup create.
	 *
	 * The value 1024 is the largest usable value on HD systems. A 2048 sector discard on a
	 * busy HD system takes 31 seconds. We should use a value no higher than 1024, which takes
	 * 15 to 16 seconds on a busy HD system. However, using large values results in 120 second
	 * blocked task warnings in kernel logs. In order to avoid these warnings, we choose to
	 * use the smallest reasonable value.
	 *
	 * The value is used by dm-thin to determine whether to pass down discards. The block layer
	 * splits large discards on this boundary when this is set.
	 */
	limits->max_discard_sectors =
		(vdo->device_config->max_discard_blocks * VDO_SECTORS_PER_BLOCK);

	/*
	 * Force discards to not begin or end with a partial block by stating the granularity is
	 * 4k.
	 */
	limits->discard_granularity = VDO_BLOCK_SIZE;
}

static int vdo_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn,
			       void *data)
{
	struct device_config *config = get_vdo_for_target(ti)->device_config;

	return fn(ti, config->owned_device, 0,
		  config->physical_blocks * VDO_SECTORS_PER_BLOCK, data);
}

/*
 * Status line is:
 *    <device> <operating mode> <in recovery> <index state> <compression state>
 *    <used physical blocks> <total physical blocks>
 */

static void vdo_status(struct dm_target *ti, status_type_t status_type,
		       unsigned int status_flags, char *result, unsigned int maxlen)
{
	struct vdo *vdo = get_vdo_for_target(ti);
	struct vdo_statistics *stats;
	struct device_config *device_config;
	/* N.B.: The DMEMIT macro uses the variables named "sz", "result", "maxlen". */
	int sz = 0;

	switch (status_type) {
	case STATUSTYPE_INFO:
		/* Report info for dmsetup status */
		mutex_lock(&vdo->stats_mutex);
		vdo_fetch_statistics(vdo, &vdo->stats_buffer);
		stats = &vdo->stats_buffer;

		DMEMIT("/dev/%pg %s %s %s %s %llu %llu",
		       vdo_get_backing_device(vdo), stats->mode,
		       stats->in_recovery_mode ? "recovering" : "-",
		       vdo_get_dedupe_index_state_name(vdo->hash_zones),
		       vdo_get_compressing(vdo) ? "online" : "offline",
		       stats->data_blocks_used + stats->overhead_blocks_used,
		       stats->physical_blocks);
		mutex_unlock(&vdo->stats_mutex);
		break;

	case STATUSTYPE_TABLE:
		/* Report the string actually specified in the beginning. */
		device_config = (struct device_config *) ti->private;
		DMEMIT("%s", device_config->original_string);
		break;

	case STATUSTYPE_IMA:
		/* FIXME: We ought to be more detailed here, but this is what thin does. */
		*result = '\0';
		break;
	}
}

static block_count_t __must_check get_underlying_device_block_count(const struct vdo *vdo)
{
	return i_size_read(vdo_get_backing_device(vdo)->bd_inode) / VDO_BLOCK_SIZE;
}

static int __must_check process_vdo_message_locked(struct vdo *vdo, unsigned int argc,
						   char **argv)
{
	if ((argc == 2) && (strcasecmp(argv[0], "compression") == 0)) {
		if (strcasecmp(argv[1], "on") == 0) {
			vdo_set_compressing(vdo, true);
			return 0;
		}

		if (strcasecmp(argv[1], "off") == 0) {
			vdo_set_compressing(vdo, false);
			return 0;
		}

		vdo_log_warning("invalid argument '%s' to dmsetup compression message",
				argv[1]);
		return -EINVAL;
	}

	vdo_log_warning("unrecognized dmsetup message '%s' received", argv[0]);
	return -EINVAL;
}

/*
 * If the message is a dump, just do it. Otherwise, check that no other message is being processed,
 * and only proceed if so.
 * Returns -EBUSY if another message is being processed
 */
static int __must_check process_vdo_message(struct vdo *vdo, unsigned int argc,
					    char **argv)
{
	int result;

	/*
	 * All messages which may be processed in parallel with other messages should be handled
	 * here before the atomic check below. Messages which should be exclusive should be
	 * processed in process_vdo_message_locked().
	 */

	/* Dump messages should always be processed */
	if (strcasecmp(argv[0], "dump") == 0)
		return vdo_dump(vdo, argc, argv, "dmsetup message");

	if (argc == 1) {
		if (strcasecmp(argv[0], "dump-on-shutdown") == 0) {
			vdo->dump_on_shutdown = true;
			return 0;
		}

		/* Index messages should always be processed */
		if ((strcasecmp(argv[0], "index-close") == 0) ||
		    (strcasecmp(argv[0], "index-create") == 0) ||
		    (strcasecmp(argv[0], "index-disable") == 0) ||
		    (strcasecmp(argv[0], "index-enable") == 0))
			return vdo_message_dedupe_index(vdo->hash_zones, argv[0]);
	}

	if (atomic_cmpxchg(&vdo->processing_message, 0, 1) != 0)
		return -EBUSY;

	result = process_vdo_message_locked(vdo, argc, argv);

	/* Pairs with the implicit barrier in cmpxchg just above */
	smp_wmb();
	atomic_set(&vdo->processing_message, 0);
	return result;
}

static int vdo_message(struct dm_target *ti, unsigned int argc, char **argv,
		       char *result_buffer, unsigned int maxlen)
{
	struct registered_thread allocating_thread, instance_thread;
	struct vdo *vdo;
	int result;

	if (argc == 0) {
		vdo_log_warning("unspecified dmsetup message");
		return -EINVAL;
	}

	vdo = get_vdo_for_target(ti);
	vdo_register_allocating_thread(&allocating_thread, NULL);
	vdo_register_thread_device_id(&instance_thread, &vdo->instance);

	/*
	 * Must be done here so we don't map return codes. The code in dm-ioctl expects a 1 for a
	 * return code to look at the buffer and see if it is full or not.
	 */
	if ((argc == 1) && (strcasecmp(argv[0], "stats") == 0)) {
		vdo_write_stats(vdo, result_buffer, maxlen);
		result = 1;
	} else {
		result = vdo_status_to_errno(process_vdo_message(vdo, argc, argv));
	}

	vdo_unregister_thread_device_id();
	vdo_unregister_allocating_thread();
	return result;
}

static void configure_target_capabilities(struct dm_target *ti)
{
	ti->discards_supported = 1;
	ti->flush_supported = true;
	ti->num_discard_bios = 1;
	ti->num_flush_bios = 1;

	/*
	 * If this value changes, please make sure to update the value for max_discard_sectors
	 * accordingly.
	 */
	BUG_ON(dm_set_target_max_io_len(ti, VDO_SECTORS_PER_BLOCK) != 0);
}

/*
 * Implements vdo_filter_fn.
 */
static bool vdo_uses_device(struct vdo *vdo, const void *context)
{
	const struct device_config *config = context;

	return vdo_get_backing_device(vdo)->bd_dev == config->owned_device->bdev->bd_dev;
}

/**
 * get_thread_id_for_phase() - Get the thread id for the current phase of the admin operation in
 *                             progress.
 */
static thread_id_t __must_check get_thread_id_for_phase(struct vdo *vdo)
{
	switch (vdo->admin.phase) {
	case RESUME_PHASE_PACKER:
	case RESUME_PHASE_FLUSHER:
	case SUSPEND_PHASE_PACKER:
	case SUSPEND_PHASE_FLUSHES:
		return vdo->thread_config.packer_thread;

	case RESUME_PHASE_DATA_VIOS:
	case SUSPEND_PHASE_DATA_VIOS:
		return vdo->thread_config.cpu_thread;

	case LOAD_PHASE_DRAIN_JOURNAL:
	case RESUME_PHASE_JOURNAL:
	case SUSPEND_PHASE_JOURNAL:
		return vdo->thread_config.journal_thread;

	default:
		return vdo->thread_config.admin_thread;
	}
}

static struct vdo_completion *prepare_admin_completion(struct vdo *vdo,
						       vdo_action_fn callback,
						       vdo_action_fn error_handler)
{
	struct vdo_completion *completion = &vdo->admin.completion;

	/*
	 * We can't use vdo_prepare_completion_for_requeue() here because we don't want to reset
	 * any error in the completion.
	 */
	completion->callback = callback;
	completion->error_handler = error_handler;
	completion->callback_thread_id = get_thread_id_for_phase(vdo);
	completion->requeue = true;
	return completion;
}

/**
 * advance_phase() - Increment the phase of the current admin operation and prepare the admin
 *                   completion to run on the thread for the next phase.
 * @vdo: The on which an admin operation is being performed
 *
 * Return: The current phase
 */
static u32 advance_phase(struct vdo *vdo)
{
	u32 phase = vdo->admin.phase++;

	vdo->admin.completion.callback_thread_id = get_thread_id_for_phase(vdo);
	vdo->admin.completion.requeue = true;
	return phase;
}

/*
 * Perform an administrative operation (load, suspend, grow logical, or grow physical). This method
 * should not be called from vdo threads.
 */
static int perform_admin_operation(struct vdo *vdo, u32 starting_phase,
				   vdo_action_fn callback, vdo_action_fn error_handler,
				   const char *type)
{
	int result;
	struct vdo_administrator *admin = &vdo->admin;

	if (atomic_cmpxchg(&admin->busy, 0, 1) != 0) {
		return vdo_log_error_strerror(VDO_COMPONENT_BUSY,
					      "Can't start %s operation, another operation is already in progress",
					      type);
	}

	admin->phase = starting_phase;
	reinit_completion(&admin->callback_sync);
	vdo_reset_completion(&admin->completion);
	vdo_launch_completion(prepare_admin_completion(vdo, callback, error_handler));

	/*
	 * Using the "interruptible" interface means that Linux will not log a message when we wait
	 * for more than 120 seconds.
	 */
	while (wait_for_completion_interruptible(&admin->callback_sync)) {
		/* However, if we get a signal in a user-mode process, we could spin... */
		fsleep(1000);
	}

	result = admin->completion.result;
	/* pairs with implicit barrier in cmpxchg above */
	smp_wmb();
	atomic_set(&admin->busy, 0);
	return result;
}

/* Assert that we are operating on the correct thread for the current phase. */
static void assert_admin_phase_thread(struct vdo *vdo, const char *what)
{
	VDO_ASSERT_LOG_ONLY(vdo_get_callback_thread_id() == get_thread_id_for_phase(vdo),
			    "%s on correct thread for %s", what,
			    ADMIN_PHASE_NAMES[vdo->admin.phase]);
}

/**
 * finish_operation_callback() - Callback to finish an admin operation.
 * @completion: The admin_completion.
 */
static void finish_operation_callback(struct vdo_completion *completion)
{
	struct vdo_administrator *admin = &completion->vdo->admin;

	vdo_finish_operation(&admin->state, completion->result);
	complete(&admin->callback_sync);
}

/**
 * decode_from_super_block() - Decode the VDO state from the super block and validate that it is
 *                             correct.
 * @vdo: The vdo being loaded.
 *
 * On error from this method, the component states must be destroyed explicitly. If this method
 * returns successfully, the component states must not be destroyed.
 *
 * Return: VDO_SUCCESS or an error.
 */
static int __must_check decode_from_super_block(struct vdo *vdo)
{
	const struct device_config *config = vdo->device_config;
	int result;

	result = vdo_decode_component_states(vdo->super_block.buffer, &vdo->geometry,
					     &vdo->states);
	if (result != VDO_SUCCESS)
		return result;

	vdo_set_state(vdo, vdo->states.vdo.state);
	vdo->load_state = vdo->states.vdo.state;

	/*
	 * If the device config specifies a larger logical size than was recorded in the super
	 * block, just accept it.
	 */
	if (vdo->states.vdo.config.logical_blocks < config->logical_blocks) {
		vdo_log_warning("Growing logical size: a logical size of %llu blocks was specified, but that differs from the %llu blocks configured in the vdo super block",
				(unsigned long long) config->logical_blocks,
				(unsigned long long) vdo->states.vdo.config.logical_blocks);
		vdo->states.vdo.config.logical_blocks = config->logical_blocks;
	}

	result = vdo_validate_component_states(&vdo->states, vdo->geometry.nonce,
					       config->physical_blocks,
					       config->logical_blocks);
	if (result != VDO_SUCCESS)
		return result;

	vdo->layout = vdo->states.layout;
	return VDO_SUCCESS;
}

/**
 * decode_vdo() - Decode the component data portion of a super block and fill in the corresponding
 *                portions of the vdo being loaded.
 * @vdo: The vdo being loaded.
 *
 * This will also allocate the recovery journal and slab depot. If this method is called with an
 * asynchronous layer (i.e. a thread config which specifies at least one base thread), the block
 * map and packer will be constructed as well.
 *
 * Return: VDO_SUCCESS or an error.
 */
static int __must_check decode_vdo(struct vdo *vdo)
{
	block_count_t maximum_age, journal_length;
	struct partition *partition;
	int result;

	result = decode_from_super_block(vdo);
	if (result != VDO_SUCCESS) {
		vdo_destroy_component_states(&vdo->states);
		return result;
	}

	maximum_age = vdo_convert_maximum_age(vdo->device_config->block_map_maximum_age);
	journal_length =
		vdo_get_recovery_journal_length(vdo->states.vdo.config.recovery_journal_size);
	if (maximum_age > (journal_length / 2)) {
		return vdo_log_error_strerror(VDO_BAD_CONFIGURATION,
					      "maximum age: %llu exceeds limit %llu",
					      (unsigned long long) maximum_age,
					      (unsigned long long) (journal_length / 2));
	}

	if (maximum_age == 0) {
		return vdo_log_error_strerror(VDO_BAD_CONFIGURATION,
					      "maximum age must be greater than 0");
	}

	result = vdo_enable_read_only_entry(vdo);
	if (result != VDO_SUCCESS)
		return result;

	partition = vdo_get_known_partition(&vdo->layout,
					    VDO_RECOVERY_JOURNAL_PARTITION);
	result = vdo_decode_recovery_journal(vdo->states.recovery_journal,
					     vdo->states.vdo.nonce, vdo, partition,
					     vdo->states.vdo.complete_recoveries,
					     vdo->states.vdo.config.recovery_journal_size,
					     &vdo->recovery_journal);
	if (result != VDO_SUCCESS)
		return result;

	partition = vdo_get_known_partition(&vdo->layout, VDO_SLAB_SUMMARY_PARTITION);
	result = vdo_decode_slab_depot(vdo->states.slab_depot, vdo, partition,
				       &vdo->depot);
	if (result != VDO_SUCCESS)
		return result;

	result = vdo_decode_block_map(vdo->states.block_map,
				      vdo->states.vdo.config.logical_blocks, vdo,
				      vdo->recovery_journal, vdo->states.vdo.nonce,
				      vdo->device_config->cache_size, maximum_age,
				      &vdo->block_map);
	if (result != VDO_SUCCESS)
		return result;

	result = vdo_make_physical_zones(vdo, &vdo->physical_zones);
	if (result != VDO_SUCCESS)
		return result;

	/* The logical zones depend on the physical zones already existing. */
	result = vdo_make_logical_zones(vdo, &vdo->logical_zones);
	if (result != VDO_SUCCESS)
		return result;

	return vdo_make_hash_zones(vdo, &vdo->hash_zones);
}

/**
 * pre_load_callback() - Callback to initiate a pre-load, registered in vdo_initialize().
 * @completion: The admin completion.
 */
static void pre_load_callback(struct vdo_completion *completion)
{
	struct vdo *vdo = completion->vdo;
	int result;

	assert_admin_phase_thread(vdo, __func__);

	switch (advance_phase(vdo)) {
	case PRE_LOAD_PHASE_START:
		result = vdo_start_operation(&vdo->admin.state,
					     VDO_ADMIN_STATE_PRE_LOADING);
		if (result != VDO_SUCCESS) {
			vdo_continue_completion(completion, result);
			return;
		}

		vdo_load_super_block(vdo, completion);
		return;

	case PRE_LOAD_PHASE_LOAD_COMPONENTS:
		vdo_continue_completion(completion, decode_vdo(vdo));
		return;

	case PRE_LOAD_PHASE_END:
		break;

	default:
		vdo_set_completion_result(completion, UDS_BAD_STATE);
	}

	finish_operation_callback(completion);
}

static void release_instance(unsigned int instance)
{
	mutex_lock(&instances_lock);
	if (instance >= instances.bit_count) {
		VDO_ASSERT_LOG_ONLY(false,
				    "instance number %u must be less than bit count %u",
				    instance, instances.bit_count);
	} else if (test_bit(instance, instances.words) == 0) {
		VDO_ASSERT_LOG_ONLY(false, "instance number %u must be allocated", instance);
	} else {
		__clear_bit(instance, instances.words);
		instances.count -= 1;
	}
	mutex_unlock(&instances_lock);
}

static void set_device_config(struct dm_target *ti, struct vdo *vdo,
			      struct device_config *config)
{
	list_del_init(&config->config_list);
	list_add_tail(&config->config_list, &vdo->device_config_list);
	config->vdo = vdo;
	ti->private = config;
	configure_target_capabilities(ti);
}

static int vdo_initialize(struct dm_target *ti, unsigned int instance,
			  struct device_config *config)
{
	struct vdo *vdo;
	int result;
	u64 block_size = VDO_BLOCK_SIZE;
	u64 logical_size = to_bytes(ti->len);
	block_count_t logical_blocks = logical_size / block_size;

	vdo_log_info("loading device '%s'", vdo_get_device_name(ti));
	vdo_log_debug("Logical block size     = %llu", (u64) config->logical_block_size);
	vdo_log_debug("Logical blocks         = %llu", logical_blocks);
	vdo_log_debug("Physical block size    = %llu", (u64) block_size);
	vdo_log_debug("Physical blocks        = %llu", config->physical_blocks);
	vdo_log_debug("Block map cache blocks = %u", config->cache_size);
	vdo_log_debug("Block map maximum age  = %u", config->block_map_maximum_age);
	vdo_log_debug("Deduplication          = %s", (config->deduplication ? "on" : "off"));
	vdo_log_debug("Compression            = %s", (config->compression ? "on" : "off"));

	vdo = vdo_find_matching(vdo_uses_device, config);
	if (vdo != NULL) {
		vdo_log_error("Existing vdo already uses device %s",
			      vdo->device_config->parent_device_name);
		ti->error = "Cannot share storage device with already-running VDO";
		return VDO_BAD_CONFIGURATION;
	}

	result = vdo_make(instance, config, &ti->error, &vdo);
	if (result != VDO_SUCCESS) {
		vdo_log_error("Could not create VDO device. (VDO error %d, message %s)",
			      result, ti->error);
		vdo_destroy(vdo);
		return result;
	}

	result = perform_admin_operation(vdo, PRE_LOAD_PHASE_START, pre_load_callback,
					 finish_operation_callback, "pre-load");
	if (result != VDO_SUCCESS) {
		ti->error = ((result == VDO_INVALID_ADMIN_STATE) ?
			     "Pre-load is only valid immediately after initialization" :
			     "Cannot load metadata from device");
		vdo_log_error("Could not start VDO device. (VDO error %d, message %s)",
			      result, ti->error);
		vdo_destroy(vdo);
		return result;
	}

	set_device_config(ti, vdo, config);
	vdo->device_config = config;
	return VDO_SUCCESS;
}

/* Implements vdo_filter_fn. */
static bool __must_check vdo_is_named(struct vdo *vdo, const void *context)
{
	struct dm_target *ti = vdo->device_config->owning_target;
	const char *device_name = vdo_get_device_name(ti);

	return strcmp(device_name, context) == 0;
}

/**
 * get_bit_array_size() - Return the number of bytes needed to store a bit array of the specified
 *                        capacity in an array of unsigned longs.
 * @bit_count: The number of bits the array must hold.
 *
 * Return: the number of bytes needed for the array representation.
 */
static size_t get_bit_array_size(unsigned int bit_count)
{
	/* Round up to a multiple of the word size and convert to a byte count. */
	return (BITS_TO_LONGS(bit_count) * sizeof(unsigned long));
}

/**
 * grow_bit_array() - Re-allocate the bitmap word array so there will more instance numbers that
 *                    can be allocated.
 *
 * Since the array is initially NULL, this also initializes the array the first time we allocate an
 * instance number.
 *
 * Return: VDO_SUCCESS or an error code from the allocation
 */
static int grow_bit_array(void)
{
	unsigned int new_count = max(instances.bit_count + BIT_COUNT_INCREMENT,
				     (unsigned int) BIT_COUNT_MINIMUM);
	unsigned long *new_words;
	int result;

	result = vdo_reallocate_memory(instances.words,
				       get_bit_array_size(instances.bit_count),
				       get_bit_array_size(new_count),
				       "instance number bit array", &new_words);
	if (result != VDO_SUCCESS)
		return result;

	instances.bit_count = new_count;
	instances.words = new_words;
	return VDO_SUCCESS;
}

/**
 * allocate_instance() - Allocate an instance number.
 * @instance_ptr: A point to hold the instance number
 *
 * Return: VDO_SUCCESS or an error code
 *
 * This function must be called while holding the instances lock.
 */
static int allocate_instance(unsigned int *instance_ptr)
{
	unsigned int instance;
	int result;

	/* If there are no unallocated instances, grow the bit array. */
	if (instances.count >= instances.bit_count) {
		result = grow_bit_array();
		if (result != VDO_SUCCESS)
			return result;
	}

	/*
	 * There must be a zero bit somewhere now. Find it, starting just after the last instance
	 * allocated.
	 */
	instance = find_next_zero_bit(instances.words, instances.bit_count,
				      instances.next);
	if (instance >= instances.bit_count) {
		/* Nothing free after next, so wrap around to instance zero. */
		instance = find_first_zero_bit(instances.words, instances.bit_count);
		result = VDO_ASSERT(instance < instances.bit_count,
				    "impossibly, no zero bit found");
		if (result != VDO_SUCCESS)
			return result;
	}

	__set_bit(instance, instances.words);
	instances.count++;
	instances.next = instance + 1;
	*instance_ptr = instance;
	return VDO_SUCCESS;
}

static int construct_new_vdo_registered(struct dm_target *ti, unsigned int argc,
					char **argv, unsigned int instance)
{
	int result;
	struct device_config *config;

	result = parse_device_config(argc, argv, ti, &config);
	if (result != VDO_SUCCESS) {
		vdo_log_error_strerror(result, "parsing failed: %s", ti->error);
		release_instance(instance);
		return -EINVAL;
	}

	/* Beyond this point, the instance number will be cleaned up for us if needed */
	result = vdo_initialize(ti, instance, config);
	if (result != VDO_SUCCESS) {
		release_instance(instance);
		free_device_config(config);
		return vdo_status_to_errno(result);
	}

	return VDO_SUCCESS;
}

static int construct_new_vdo(struct dm_target *ti, unsigned int argc, char **argv)
{
	int result;
	unsigned int instance;
	struct registered_thread instance_thread;

	mutex_lock(&instances_lock);
	result = allocate_instance(&instance);
	mutex_unlock(&instances_lock);
	if (result != VDO_SUCCESS)
		return -ENOMEM;

	vdo_register_thread_device_id(&instance_thread, &instance);
	result = construct_new_vdo_registered(ti, argc, argv, instance);
	vdo_unregister_thread_device_id();
	return result;
}

/**
 * check_may_grow_physical() - Callback to check that we're not in recovery mode, used in
 *                             vdo_prepare_to_grow_physical().
 * @completion: The admin completion.
 */
static void check_may_grow_physical(struct vdo_completion *completion)
{
	struct vdo *vdo = completion->vdo;

	assert_admin_phase_thread(vdo, __func__);

	/* These checks can only be done from a vdo thread. */
	if (vdo_is_read_only(vdo))
		vdo_set_completion_result(completion, VDO_READ_ONLY);

	if (vdo_in_recovery_mode(vdo))
		vdo_set_completion_result(completion, VDO_RETRY_AFTER_REBUILD);

	finish_operation_callback(completion);
}

static block_count_t get_partition_size(struct layout *layout, enum partition_id id)
{
	return vdo_get_known_partition(layout, id)->count;
}

/**
 * grow_layout() - Make the layout for growing a vdo.
 * @vdo: The vdo preparing to grow.
 * @old_size: The current size of the vdo.
 * @new_size: The size to which the vdo will be grown.
 *
 * Return: VDO_SUCCESS or an error code.
 */
static int grow_layout(struct vdo *vdo, block_count_t old_size, block_count_t new_size)
{
	int result;
	block_count_t min_new_size;

	if (vdo->next_layout.size == new_size) {
		/* We are already prepared to grow to the new size, so we're done. */
		return VDO_SUCCESS;
	}

	/* Make a copy completion if there isn't one */
	if (vdo->partition_copier == NULL) {
		vdo->partition_copier = dm_kcopyd_client_create(NULL);
		if (IS_ERR(vdo->partition_copier)) {
			result = PTR_ERR(vdo->partition_copier);
			vdo->partition_copier = NULL;
			return result;
		}
	}

	/* Free any unused preparation. */
	vdo_uninitialize_layout(&vdo->next_layout);

	/*
	 * Make a new layout with the existing partition sizes for everything but the slab depot
	 * partition.
	 */
	result = vdo_initialize_layout(new_size, vdo->layout.start,
				       get_partition_size(&vdo->layout,
							  VDO_BLOCK_MAP_PARTITION),
				       get_partition_size(&vdo->layout,
							  VDO_RECOVERY_JOURNAL_PARTITION),
				       get_partition_size(&vdo->layout,
							  VDO_SLAB_SUMMARY_PARTITION),
				       &vdo->next_layout);
	if (result != VDO_SUCCESS) {
		dm_kcopyd_client_destroy(vdo_forget(vdo->partition_copier));
		return result;
	}

	/* Ensure the new journal and summary are entirely within the added blocks. */
	min_new_size = (old_size +
			get_partition_size(&vdo->next_layout,
					   VDO_SLAB_SUMMARY_PARTITION) +
			get_partition_size(&vdo->next_layout,
					   VDO_RECOVERY_JOURNAL_PARTITION));
	if (min_new_size > new_size) {
		/* Copying the journal and summary would destroy some old metadata. */
		vdo_uninitialize_layout(&vdo->next_layout);
		dm_kcopyd_client_destroy(vdo_forget(vdo->partition_copier));
		return VDO_INCREMENT_TOO_SMALL;
	}

	return VDO_SUCCESS;
}

static int prepare_to_grow_physical(struct vdo *vdo, block_count_t new_physical_blocks)
{
	int result;
	block_count_t current_physical_blocks = vdo->states.vdo.config.physical_blocks;

	vdo_log_info("Preparing to resize physical to %llu",
		     (unsigned long long) new_physical_blocks);
	VDO_ASSERT_LOG_ONLY((new_physical_blocks > current_physical_blocks),
			    "New physical size is larger than current physical size");
	result = perform_admin_operation(vdo, PREPARE_GROW_PHYSICAL_PHASE_START,
					 check_may_grow_physical,
					 finish_operation_callback,
					 "prepare grow-physical");
	if (result != VDO_SUCCESS)
		return result;

	result = grow_layout(vdo, current_physical_blocks, new_physical_blocks);
	if (result != VDO_SUCCESS)
		return result;

	result = vdo_prepare_to_grow_slab_depot(vdo->depot,
						vdo_get_known_partition(&vdo->next_layout,
									VDO_SLAB_DEPOT_PARTITION));
	if (result != VDO_SUCCESS) {
		vdo_uninitialize_layout(&vdo->next_layout);
		return result;
	}

	vdo_log_info("Done preparing to resize physical");
	return VDO_SUCCESS;
}

/**
 * validate_new_device_config() - Check whether a new device config represents a valid modification
 *				  to an existing config.
 * @to_validate: The new config to validate.
 * @config: The existing config.
 * @may_grow: Set to true if growing the logical and physical size of the vdo is currently
 *	      permitted.
 * @error_ptr: A pointer to hold the reason for any error.
 *
 * Return: VDO_SUCCESS or an error.
 */
static int validate_new_device_config(struct device_config *to_validate,
				      struct device_config *config, bool may_grow,
				      char **error_ptr)
{
	if (to_validate->owning_target->begin != config->owning_target->begin) {
		*error_ptr = "Starting sector cannot change";
		return VDO_PARAMETER_MISMATCH;
	}

	if (to_validate->logical_block_size != config->logical_block_size) {
		*error_ptr = "Logical block size cannot change";
		return VDO_PARAMETER_MISMATCH;
	}

	if (to_validate->logical_blocks < config->logical_blocks) {
		*error_ptr = "Can't shrink VDO logical size";
		return VDO_PARAMETER_MISMATCH;
	}

	if (to_validate->cache_size != config->cache_size) {
		*error_ptr = "Block map cache size cannot change";
		return VDO_PARAMETER_MISMATCH;
	}

	if (to_validate->block_map_maximum_age != config->block_map_maximum_age) {
		*error_ptr = "Block map maximum age cannot change";
		return VDO_PARAMETER_MISMATCH;
	}

	if (memcmp(&to_validate->thread_counts, &config->thread_counts,
		   sizeof(struct thread_count_config)) != 0) {
		*error_ptr = "Thread configuration cannot change";
		return VDO_PARAMETER_MISMATCH;
	}

	if (to_validate->physical_blocks < config->physical_blocks) {
		*error_ptr = "Removing physical storage from a VDO is not supported";
		return VDO_NOT_IMPLEMENTED;
	}

	if (!may_grow && (to_validate->physical_blocks > config->physical_blocks)) {
		*error_ptr = "VDO physical size may not grow in current state";
		return VDO_NOT_IMPLEMENTED;
	}

	return VDO_SUCCESS;
}

static int prepare_to_modify(struct dm_target *ti, struct device_config *config,
			     struct vdo *vdo)
{
	int result;
	bool may_grow = (vdo_get_admin_state(vdo) != VDO_ADMIN_STATE_PRE_LOADED);

	result = validate_new_device_config(config, vdo->device_config, may_grow,
					    &ti->error);
	if (result != VDO_SUCCESS)
		return -EINVAL;

	if (config->logical_blocks > vdo->device_config->logical_blocks) {
		block_count_t logical_blocks = vdo->states.vdo.config.logical_blocks;

		vdo_log_info("Preparing to resize logical to %llu",
			     (unsigned long long) config->logical_blocks);
		VDO_ASSERT_LOG_ONLY((config->logical_blocks > logical_blocks),
				    "New logical size is larger than current size");

		result = vdo_prepare_to_grow_block_map(vdo->block_map,
						       config->logical_blocks);
		if (result != VDO_SUCCESS) {
			ti->error = "Device vdo_prepare_to_grow_logical failed";
			return result;
		}

		vdo_log_info("Done preparing to resize logical");
	}

	if (config->physical_blocks > vdo->device_config->physical_blocks) {
		result = prepare_to_grow_physical(vdo, config->physical_blocks);
		if (result != VDO_SUCCESS) {
			if (result == VDO_PARAMETER_MISMATCH) {
				/*
				 * If we don't trap this case, vdo_status_to_errno() will remap
				 * it to -EIO, which is misleading and ahistorical.
				 */
				result = -EINVAL;
			}

			if (result == VDO_TOO_MANY_SLABS)
				ti->error = "Device vdo_prepare_to_grow_physical failed (specified physical size too big based on formatted slab size)";
			else
				ti->error = "Device vdo_prepare_to_grow_physical failed";

			return result;
		}
	}

	if (strcmp(config->parent_device_name, vdo->device_config->parent_device_name) != 0) {
		const char *device_name = vdo_get_device_name(config->owning_target);

		vdo_log_info("Updating backing device of %s from %s to %s", device_name,
			     vdo->device_config->parent_device_name,
			     config->parent_device_name);
	}

	return VDO_SUCCESS;
}

static int update_existing_vdo(const char *device_name, struct dm_target *ti,
			       unsigned int argc, char **argv, struct vdo *vdo)
{
	int result;
	struct device_config *config;

	result = parse_device_config(argc, argv, ti, &config);
	if (result != VDO_SUCCESS)
		return -EINVAL;

	vdo_log_info("preparing to modify device '%s'", device_name);
	result = prepare_to_modify(ti, config, vdo);
	if (result != VDO_SUCCESS) {
		free_device_config(config);
		return vdo_status_to_errno(result);
	}

	set_device_config(ti, vdo, config);
	return VDO_SUCCESS;
}

static int vdo_ctr(struct dm_target *ti, unsigned int argc, char **argv)
{
	int result;
	struct registered_thread allocating_thread, instance_thread;
	const char *device_name;
	struct vdo *vdo;

	vdo_register_allocating_thread(&allocating_thread, NULL);
	device_name = vdo_get_device_name(ti);
	vdo = vdo_find_matching(vdo_is_named, device_name);
	if (vdo == NULL) {
		result = construct_new_vdo(ti, argc, argv);
	} else {
		vdo_register_thread_device_id(&instance_thread, &vdo->instance);
		result = update_existing_vdo(device_name, ti, argc, argv, vdo);
		vdo_unregister_thread_device_id();
	}

	vdo_unregister_allocating_thread();
	return result;
}

static void vdo_dtr(struct dm_target *ti)
{
	struct device_config *config = ti->private;
	struct vdo *vdo = vdo_forget(config->vdo);

	list_del_init(&config->config_list);
	if (list_empty(&vdo->device_config_list)) {
		const char *device_name;

		/* This was the last config referencing the VDO. Free it. */
		unsigned int instance = vdo->instance;
		struct registered_thread allocating_thread, instance_thread;

		vdo_register_thread_device_id(&instance_thread, &instance);
		vdo_register_allocating_thread(&allocating_thread, NULL);

		device_name = vdo_get_device_name(ti);
		vdo_log_info("stopping device '%s'", device_name);
		if (vdo->dump_on_shutdown)
			vdo_dump_all(vdo, "device shutdown");

		vdo_destroy(vdo_forget(vdo));
		vdo_log_info("device '%s' stopped", device_name);
		vdo_unregister_thread_device_id();
		vdo_unregister_allocating_thread();
		release_instance(instance);
	} else if (config == vdo->device_config) {
		/*
		 * The VDO still references this config. Give it a reference to a config that isn't
		 * being destroyed.
		 */
		vdo->device_config = list_first_entry(&vdo->device_config_list,
						      struct device_config, config_list);
	}

	free_device_config(config);
	ti->private = NULL;
}

static void vdo_presuspend(struct dm_target *ti)
{
	get_vdo_for_target(ti)->suspend_type =
		(dm_noflush_suspending(ti) ? VDO_ADMIN_STATE_SUSPENDING : VDO_ADMIN_STATE_SAVING);
}

/**
 * write_super_block_for_suspend() - Update the VDO state and save the super block.
 * @completion: The admin completion
 */
static void write_super_block_for_suspend(struct vdo_completion *completion)
{
	struct vdo *vdo = completion->vdo;

	switch (vdo_get_state(vdo)) {
	case VDO_DIRTY:
	case VDO_NEW:
		vdo_set_state(vdo, VDO_CLEAN);
		break;

	case VDO_CLEAN:
	case VDO_READ_ONLY_MODE:
	case VDO_FORCE_REBUILD:
	case VDO_RECOVERING:
	case VDO_REBUILD_FOR_UPGRADE:
		break;

	case VDO_REPLAYING:
	default:
		vdo_continue_completion(completion, UDS_BAD_STATE);
		return;
	}

	vdo_save_components(vdo, completion);
}

/**
 * suspend_callback() - Callback to initiate a suspend, registered in vdo_postsuspend().
 * @completion: The sub-task completion.
 */
static void suspend_callback(struct vdo_completion *completion)
{
	struct vdo *vdo = completion->vdo;
	struct admin_state *state = &vdo->admin.state;
	int result;

	assert_admin_phase_thread(vdo, __func__);

	switch (advance_phase(vdo)) {
	case SUSPEND_PHASE_START:
		if (vdo_get_admin_state_code(state)->quiescent) {
			/* Already suspended */
			break;
		}

		vdo_continue_completion(completion,
					vdo_start_operation(state, vdo->suspend_type));
		return;

	case SUSPEND_PHASE_PACKER:
		/*
		 * If the VDO was already resumed from a prior suspend while read-only, some of the
		 * components may not have been resumed. By setting a read-only error here, we
		 * guarantee that the result of this suspend will be VDO_READ_ONLY and not
		 * VDO_INVALID_ADMIN_STATE in that case.
		 */
		if (vdo_in_read_only_mode(vdo))
			vdo_set_completion_result(completion, VDO_READ_ONLY);

		vdo_drain_packer(vdo->packer, completion);
		return;

	case SUSPEND_PHASE_DATA_VIOS:
		drain_data_vio_pool(vdo->data_vio_pool, completion);
		return;

	case SUSPEND_PHASE_DEDUPE:
		vdo_drain_hash_zones(vdo->hash_zones, completion);
		return;

	case SUSPEND_PHASE_FLUSHES:
		vdo_drain_flusher(vdo->flusher, completion);
		return;

	case SUSPEND_PHASE_LOGICAL_ZONES:
		/*
		 * Attempt to flush all I/O before completing post suspend work. We believe a
		 * suspended device is expected to have persisted all data written before the
		 * suspend, even if it hasn't been flushed yet.
		 */
		result = vdo_synchronous_flush(vdo);
		if (result != VDO_SUCCESS)
			vdo_enter_read_only_mode(vdo, result);

		vdo_drain_logical_zones(vdo->logical_zones,
					vdo_get_admin_state_code(state), completion);
		return;

	case SUSPEND_PHASE_BLOCK_MAP:
		vdo_drain_block_map(vdo->block_map, vdo_get_admin_state_code(state),
				    completion);
		return;

	case SUSPEND_PHASE_JOURNAL:
		vdo_drain_recovery_journal(vdo->recovery_journal,
					   vdo_get_admin_state_code(state), completion);
		return;

	case SUSPEND_PHASE_DEPOT:
		vdo_drain_slab_depot(vdo->depot, vdo_get_admin_state_code(state),
				     completion);
		return;

	case SUSPEND_PHASE_READ_ONLY_WAIT:
		vdo_wait_until_not_entering_read_only_mode(completion);
		return;

	case SUSPEND_PHASE_WRITE_SUPER_BLOCK:
		if (vdo_is_state_suspending(state) || (completion->result != VDO_SUCCESS)) {
			/* If we didn't save the VDO or there was an error, we're done. */
			break;
		}

		write_super_block_for_suspend(completion);
		return;

	case SUSPEND_PHASE_END:
		break;

	default:
		vdo_set_completion_result(completion, UDS_BAD_STATE);
	}

	finish_operation_callback(completion);
}

static void vdo_postsuspend(struct dm_target *ti)
{
	struct vdo *vdo = get_vdo_for_target(ti);
	struct registered_thread instance_thread;
	const char *device_name;
	int result;

	vdo_register_thread_device_id(&instance_thread, &vdo->instance);
	device_name = vdo_get_device_name(vdo->device_config->owning_target);
	vdo_log_info("suspending device '%s'", device_name);

	/*
	 * It's important to note any error here does not actually stop device-mapper from
	 * suspending the device. All this work is done post suspend.
	 */
	result = perform_admin_operation(vdo, SUSPEND_PHASE_START, suspend_callback,
					 suspend_callback, "suspend");

	if ((result == VDO_SUCCESS) || (result == VDO_READ_ONLY)) {
		/*
		 * Treat VDO_READ_ONLY as a success since a read-only suspension still leaves the
		 * VDO suspended.
		 */
		vdo_log_info("device '%s' suspended", device_name);
	} else if (result == VDO_INVALID_ADMIN_STATE) {
		vdo_log_error("Suspend invoked while in unexpected state: %s",
			      vdo_get_admin_state(vdo)->name);
	} else {
		vdo_log_error_strerror(result, "Suspend of device '%s' failed",
				       device_name);
	}

	vdo_unregister_thread_device_id();
}

/**
 * was_new() - Check whether the vdo was new when it was loaded.
 * @vdo: The vdo to query.
 *
 * Return: true if the vdo was new.
 */
static bool was_new(const struct vdo *vdo)
{
	return (vdo->load_state == VDO_NEW);
}

/**
 * requires_repair() - Check whether a vdo requires recovery or rebuild.
 * @vdo: The vdo to query.
 *
 * Return: true if the vdo must be repaired.
 */
static bool __must_check requires_repair(const struct vdo *vdo)
{
	switch (vdo_get_state(vdo)) {
	case VDO_DIRTY:
	case VDO_FORCE_REBUILD:
	case VDO_REPLAYING:
	case VDO_REBUILD_FOR_UPGRADE:
		return true;

	default:
		return false;
	}
}

/**
 * get_load_type() - Determine how the slab depot was loaded.
 * @vdo: The vdo.
 *
 * Return: How the depot was loaded.
 */
static enum slab_depot_load_type get_load_type(struct vdo *vdo)
{
	if (vdo_state_requires_read_only_rebuild(vdo->load_state))
		return VDO_SLAB_DEPOT_REBUILD_LOAD;

	if (vdo_state_requires_recovery(vdo->load_state))
		return VDO_SLAB_DEPOT_RECOVERY_LOAD;

	return VDO_SLAB_DEPOT_NORMAL_LOAD;
}

/**
 * load_callback() - Callback to do the destructive parts of loading a VDO.
 * @completion: The sub-task completion.
 */
static void load_callback(struct vdo_completion *completion)
{
	struct vdo *vdo = completion->vdo;
	int result;

	assert_admin_phase_thread(vdo, __func__);

	switch (advance_phase(vdo)) {
	case LOAD_PHASE_START:
		result = vdo_start_operation(&vdo->admin.state, VDO_ADMIN_STATE_LOADING);
		if (result != VDO_SUCCESS) {
			vdo_continue_completion(completion, result);
			return;
		}

		/* Prepare the recovery journal for new entries. */
		vdo_open_recovery_journal(vdo->recovery_journal, vdo->depot,
					  vdo->block_map);
		vdo_allow_read_only_mode_entry(completion);
		return;

	case LOAD_PHASE_LOAD_DEPOT:
		vdo_set_dedupe_state_normal(vdo->hash_zones);
		if (vdo_is_read_only(vdo)) {
			/*
			 * In read-only mode we don't use the allocator and it may not even be
			 * readable, so don't bother trying to load it.
			 */
			vdo_set_completion_result(completion, VDO_READ_ONLY);
			break;
		}

		if (requires_repair(vdo)) {
			vdo_repair(completion);
			return;
		}

		vdo_load_slab_depot(vdo->depot,
				    (was_new(vdo) ? VDO_ADMIN_STATE_FORMATTING :
				     VDO_ADMIN_STATE_LOADING),
				    completion, NULL);
		return;

	case LOAD_PHASE_MAKE_DIRTY:
		vdo_set_state(vdo, VDO_DIRTY);
		vdo_save_components(vdo, completion);
		return;

	case LOAD_PHASE_PREPARE_TO_ALLOCATE:
		vdo_initialize_block_map_from_journal(vdo->block_map,
						      vdo->recovery_journal);
		vdo_prepare_slab_depot_to_allocate(vdo->depot, get_load_type(vdo),
						   completion);
		return;

	case LOAD_PHASE_SCRUB_SLABS:
		if (vdo_state_requires_recovery(vdo->load_state))
			vdo_enter_recovery_mode(vdo);

		vdo_scrub_all_unrecovered_slabs(vdo->depot, completion);
		return;

	case LOAD_PHASE_DATA_REDUCTION:
		WRITE_ONCE(vdo->compressing, vdo->device_config->compression);
		if (vdo->device_config->deduplication) {
			/*
			 * Don't try to load or rebuild the index first (and log scary error
			 * messages) if this is known to be a newly-formatted volume.
			 */
			vdo_start_dedupe_index(vdo->hash_zones, was_new(vdo));
		}

		vdo->allocations_allowed = false;
		fallthrough;

	case LOAD_PHASE_FINISHED:
		break;

	case LOAD_PHASE_DRAIN_JOURNAL:
		vdo_drain_recovery_journal(vdo->recovery_journal, VDO_ADMIN_STATE_SAVING,
					   completion);
		return;

	case LOAD_PHASE_WAIT_FOR_READ_ONLY:
		/* Avoid an infinite loop */
		completion->error_handler = NULL;
		vdo->admin.phase = LOAD_PHASE_FINISHED;
		vdo_wait_until_not_entering_read_only_mode(completion);
		return;

	default:
		vdo_set_completion_result(completion, UDS_BAD_STATE);
	}

	finish_operation_callback(completion);
}

/**
 * handle_load_error() - Handle an error during the load operation.
 * @completion: The admin completion.
 *
 * If at all possible, brings the vdo online in read-only mode. This handler is registered in
 * vdo_preresume_registered().
 */
static void handle_load_error(struct vdo_completion *completion)
{
	struct vdo *vdo = completion->vdo;

	if (vdo_requeue_completion_if_needed(completion,
					     vdo->thread_config.admin_thread))
		return;

	if (vdo_state_requires_read_only_rebuild(vdo->load_state) &&
	    (vdo->admin.phase == LOAD_PHASE_MAKE_DIRTY)) {
		vdo_log_error_strerror(completion->result, "aborting load");
		vdo->admin.phase = LOAD_PHASE_DRAIN_JOURNAL;
		load_callback(vdo_forget(completion));
		return;
	}

	vdo_log_error_strerror(completion->result,
			       "Entering read-only mode due to load error");
	vdo->admin.phase = LOAD_PHASE_WAIT_FOR_READ_ONLY;
	vdo_enter_read_only_mode(vdo, completion->result);
	completion->result = VDO_READ_ONLY;
	load_callback(completion);
}

/**
 * write_super_block_for_resume() - Update the VDO state and save the super block.
 * @completion: The admin completion
 */
static void write_super_block_for_resume(struct vdo_completion *completion)
{
	struct vdo *vdo = completion->vdo;

	switch (vdo_get_state(vdo)) {
	case VDO_CLEAN:
	case VDO_NEW:
		vdo_set_state(vdo, VDO_DIRTY);
		vdo_save_components(vdo, completion);
		return;

	case VDO_DIRTY:
	case VDO_READ_ONLY_MODE:
	case VDO_FORCE_REBUILD:
	case VDO_RECOVERING:
	case VDO_REBUILD_FOR_UPGRADE:
		/* No need to write the super block in these cases */
		vdo_launch_completion(completion);
		return;

	case VDO_REPLAYING:
	default:
		vdo_continue_completion(completion, UDS_BAD_STATE);
	}
}

/**
 * resume_callback() - Callback to resume a VDO.
 * @completion: The admin completion.
 */
static void resume_callback(struct vdo_completion *completion)
{
	struct vdo *vdo = completion->vdo;
	int result;

	assert_admin_phase_thread(vdo, __func__);

	switch (advance_phase(vdo)) {
	case RESUME_PHASE_START:
		result = vdo_start_operation(&vdo->admin.state,
					     VDO_ADMIN_STATE_RESUMING);
		if (result != VDO_SUCCESS) {
			vdo_continue_completion(completion, result);
			return;
		}

		write_super_block_for_resume(completion);
		return;

	case RESUME_PHASE_ALLOW_READ_ONLY_MODE:
		vdo_allow_read_only_mode_entry(completion);
		return;

	case RESUME_PHASE_DEDUPE:
		vdo_resume_hash_zones(vdo->hash_zones, completion);
		return;

	case RESUME_PHASE_DEPOT:
		vdo_resume_slab_depot(vdo->depot, completion);
		return;

	case RESUME_PHASE_JOURNAL:
		vdo_resume_recovery_journal(vdo->recovery_journal, completion);
		return;

	case RESUME_PHASE_BLOCK_MAP:
		vdo_resume_block_map(vdo->block_map, completion);
		return;

	case RESUME_PHASE_LOGICAL_ZONES:
		vdo_resume_logical_zones(vdo->logical_zones, completion);
		return;

	case RESUME_PHASE_PACKER:
	{
		bool was_enabled = vdo_get_compressing(vdo);
		bool enable = vdo->device_config->compression;

		if (enable != was_enabled)
			WRITE_ONCE(vdo->compressing, enable);
		vdo_log_info("compression is %s", (enable ? "enabled" : "disabled"));

		vdo_resume_packer(vdo->packer, completion);
		return;
	}

	case RESUME_PHASE_FLUSHER:
		vdo_resume_flusher(vdo->flusher, completion);
		return;

	case RESUME_PHASE_DATA_VIOS:
		resume_data_vio_pool(vdo->data_vio_pool, completion);
		return;

	case RESUME_PHASE_END:
		break;

	default:
		vdo_set_completion_result(completion, UDS_BAD_STATE);
	}

	finish_operation_callback(completion);
}

/**
 * grow_logical_callback() - Callback to initiate a grow logical.
 * @completion: The admin completion.
 *
 * Registered in perform_grow_logical().
 */
static void grow_logical_callback(struct vdo_completion *completion)
{
	struct vdo *vdo = completion->vdo;
	int result;

	assert_admin_phase_thread(vdo, __func__);

	switch (advance_phase(vdo)) {
	case GROW_LOGICAL_PHASE_START:
		if (vdo_is_read_only(vdo)) {
			vdo_log_error_strerror(VDO_READ_ONLY,
					       "Can't grow logical size of a read-only VDO");
			vdo_set_completion_result(completion, VDO_READ_ONLY);
			break;
		}

		result = vdo_start_operation(&vdo->admin.state,
					     VDO_ADMIN_STATE_SUSPENDED_OPERATION);
		if (result != VDO_SUCCESS) {
			vdo_continue_completion(completion, result);
			return;
		}

		vdo->states.vdo.config.logical_blocks = vdo->block_map->next_entry_count;
		vdo_save_components(vdo, completion);
		return;

	case GROW_LOGICAL_PHASE_GROW_BLOCK_MAP:
		vdo_grow_block_map(vdo->block_map, completion);
		return;

	case GROW_LOGICAL_PHASE_END:
		break;

	case GROW_LOGICAL_PHASE_ERROR:
		vdo_enter_read_only_mode(vdo, completion->result);
		break;

	default:
		vdo_set_completion_result(completion, UDS_BAD_STATE);
	}

	finish_operation_callback(completion);
}

/**
 * handle_logical_growth_error() - Handle an error during the grow physical process.
 * @completion: The admin completion.
 */
static void handle_logical_growth_error(struct vdo_completion *completion)
{
	struct vdo *vdo = completion->vdo;

	if (vdo->admin.phase == GROW_LOGICAL_PHASE_GROW_BLOCK_MAP) {
		/*
		 * We've failed to write the new size in the super block, so set our in memory
		 * config back to the old size.
		 */
		vdo->states.vdo.config.logical_blocks = vdo->block_map->entry_count;
		vdo_abandon_block_map_growth(vdo->block_map);
	}

	vdo->admin.phase = GROW_LOGICAL_PHASE_ERROR;
	grow_logical_callback(completion);
}

/**
 * perform_grow_logical() - Grow the logical size of the vdo.
 * @vdo: The vdo to grow.
 * @new_logical_blocks: The size to which the vdo should be grown.
 *
 * Context: This method may only be called when the vdo has been suspended and must not be called
 * from a base thread.
 *
 * Return: VDO_SUCCESS or an error.
 */
static int perform_grow_logical(struct vdo *vdo, block_count_t new_logical_blocks)
{
	int result;

	if (vdo->device_config->logical_blocks == new_logical_blocks) {
		/*
		 * A table was loaded for which we prepared to grow, but a table without that
		 * growth was what we are resuming with.
		 */
		vdo_abandon_block_map_growth(vdo->block_map);
		return VDO_SUCCESS;
	}

	vdo_log_info("Resizing logical to %llu",
		     (unsigned long long) new_logical_blocks);
	if (vdo->block_map->next_entry_count != new_logical_blocks)
		return VDO_PARAMETER_MISMATCH;

	result = perform_admin_operation(vdo, GROW_LOGICAL_PHASE_START,
					 grow_logical_callback,
					 handle_logical_growth_error, "grow logical");
	if (result != VDO_SUCCESS)
		return result;

	vdo_log_info("Logical blocks now %llu", (unsigned long long) new_logical_blocks);
	return VDO_SUCCESS;
}

static void copy_callback(int read_err, unsigned long write_err, void *context)
{
	struct vdo_completion *completion = context;
	int result = (((read_err == 0) && (write_err == 0)) ? VDO_SUCCESS : -EIO);

	vdo_continue_completion(completion, result);
}

static void partition_to_region(struct partition *partition, struct vdo *vdo,
				struct dm_io_region *region)
{
	physical_block_number_t pbn = partition->offset - vdo->geometry.bio_offset;

	*region = (struct dm_io_region) {
		.bdev = vdo_get_backing_device(vdo),
		.sector = pbn * VDO_SECTORS_PER_BLOCK,
		.count = partition->count * VDO_SECTORS_PER_BLOCK,
	};
}

/**
 * copy_partition() - Copy a partition from the location specified in the current layout to that in
 *                    the next layout.
 * @vdo: The vdo preparing to grow.
 * @id: The ID of the partition to copy.
 * @parent: The completion to notify when the copy is complete.
 */
static void copy_partition(struct vdo *vdo, enum partition_id id,
			   struct vdo_completion *parent)
{
	struct dm_io_region read_region, write_regions[1];
	struct partition *from = vdo_get_known_partition(&vdo->layout, id);
	struct partition *to = vdo_get_known_partition(&vdo->next_layout, id);

	partition_to_region(from, vdo, &read_region);
	partition_to_region(to, vdo, &write_regions[0]);
	dm_kcopyd_copy(vdo->partition_copier, &read_region, 1, write_regions, 0,
		       copy_callback, parent);
}

/**
 * grow_physical_callback() - Callback to initiate a grow physical.
 * @completion: The admin completion.
 *
 * Registered in perform_grow_physical().
 */
static void grow_physical_callback(struct vdo_completion *completion)
{
	struct vdo *vdo = completion->vdo;
	int result;

	assert_admin_phase_thread(vdo, __func__);

	switch (advance_phase(vdo)) {
	case GROW_PHYSICAL_PHASE_START:
		if (vdo_is_read_only(vdo)) {
			vdo_log_error_strerror(VDO_READ_ONLY,
					       "Can't grow physical size of a read-only VDO");
			vdo_set_completion_result(completion, VDO_READ_ONLY);
			break;
		}

		result = vdo_start_operation(&vdo->admin.state,
					     VDO_ADMIN_STATE_SUSPENDED_OPERATION);
		if (result != VDO_SUCCESS) {
			vdo_continue_completion(completion, result);
			return;
		}

		/* Copy the journal into the new layout. */
		copy_partition(vdo, VDO_RECOVERY_JOURNAL_PARTITION, completion);
		return;

	case GROW_PHYSICAL_PHASE_COPY_SUMMARY:
		copy_partition(vdo, VDO_SLAB_SUMMARY_PARTITION, completion);
		return;

	case GROW_PHYSICAL_PHASE_UPDATE_COMPONENTS:
		vdo_uninitialize_layout(&vdo->layout);
		vdo->layout = vdo->next_layout;
		vdo_forget(vdo->next_layout.head);
		vdo->states.vdo.config.physical_blocks = vdo->layout.size;
		vdo_update_slab_depot_size(vdo->depot);
		vdo_save_components(vdo, completion);
		return;

	case GROW_PHYSICAL_PHASE_USE_NEW_SLABS:
		vdo_use_new_slabs(vdo->depot, completion);
		return;

	case GROW_PHYSICAL_PHASE_END:
		vdo->depot->summary_origin =
			vdo_get_known_partition(&vdo->layout,
						VDO_SLAB_SUMMARY_PARTITION)->offset;
		vdo->recovery_journal->origin =
			vdo_get_known_partition(&vdo->layout,
						VDO_RECOVERY_JOURNAL_PARTITION)->offset;
		break;

	case GROW_PHYSICAL_PHASE_ERROR:
		vdo_enter_read_only_mode(vdo, completion->result);
		break;

	default:
		vdo_set_completion_result(completion, UDS_BAD_STATE);
	}

	vdo_uninitialize_layout(&vdo->next_layout);
	finish_operation_callback(completion);
}

/**
 * handle_physical_growth_error() - Handle an error during the grow physical process.
 * @completion: The sub-task completion.
 */
static void handle_physical_growth_error(struct vdo_completion *completion)
{
	completion->vdo->admin.phase = GROW_PHYSICAL_PHASE_ERROR;
	grow_physical_callback(completion);
}

/**
 * perform_grow_physical() - Grow the physical size of the vdo.
 * @vdo: The vdo to resize.
 * @new_physical_blocks: The new physical size in blocks.
 *
 * Context: This method may only be called when the vdo has been suspended and must not be called
 * from a base thread.
 *
 * Return: VDO_SUCCESS or an error.
 */
static int perform_grow_physical(struct vdo *vdo, block_count_t new_physical_blocks)
{
	int result;
	block_count_t new_depot_size, prepared_depot_size;
	block_count_t old_physical_blocks = vdo->states.vdo.config.physical_blocks;

	/* Skip any noop grows. */
	if (old_physical_blocks == new_physical_blocks)
		return VDO_SUCCESS;

	if (new_physical_blocks != vdo->next_layout.size) {
		/*
		 * Either the VDO isn't prepared to grow, or it was prepared to grow to a different
		 * size. Doing this check here relies on the fact that the call to this method is
		 * done under the dmsetup message lock.
		 */
		vdo_uninitialize_layout(&vdo->next_layout);
		vdo_abandon_new_slabs(vdo->depot);
		return VDO_PARAMETER_MISMATCH;
	}

	/* Validate that we are prepared to grow appropriately. */
	new_depot_size =
		vdo_get_known_partition(&vdo->next_layout, VDO_SLAB_DEPOT_PARTITION)->count;
	prepared_depot_size = (vdo->depot->new_slabs == NULL) ? 0 : vdo->depot->new_size;
	if (prepared_depot_size != new_depot_size)
		return VDO_PARAMETER_MISMATCH;

	result = perform_admin_operation(vdo, GROW_PHYSICAL_PHASE_START,
					 grow_physical_callback,
					 handle_physical_growth_error, "grow physical");
	if (result != VDO_SUCCESS)
		return result;

	vdo_log_info("Physical block count was %llu, now %llu",
		     (unsigned long long) old_physical_blocks,
		     (unsigned long long) new_physical_blocks);
	return VDO_SUCCESS;
}

/**
 * apply_new_vdo_configuration() - Attempt to make any configuration changes from the table being
 *                                 resumed.
 * @vdo: The vdo being resumed.
 * @config: The new device configuration derived from the table with which the vdo is being
 *          resumed.
 *
 * Return: VDO_SUCCESS or an error.
 */
static int __must_check apply_new_vdo_configuration(struct vdo *vdo,
						    struct device_config *config)
{
	int result;

	result = perform_grow_logical(vdo, config->logical_blocks);
	if (result != VDO_SUCCESS) {
		vdo_log_error("grow logical operation failed, result = %d", result);
		return result;
	}

	result = perform_grow_physical(vdo, config->physical_blocks);
	if (result != VDO_SUCCESS)
		vdo_log_error("resize operation failed, result = %d", result);

	return result;
}

static int vdo_preresume_registered(struct dm_target *ti, struct vdo *vdo)
{
	struct device_config *config = ti->private;
	const char *device_name = vdo_get_device_name(ti);
	block_count_t backing_blocks;
	int result;

	backing_blocks = get_underlying_device_block_count(vdo);
	if (backing_blocks < config->physical_blocks) {
		/* FIXME: can this still happen? */
		vdo_log_error("resume of device '%s' failed: backing device has %llu blocks but VDO physical size is %llu blocks",
			      device_name, (unsigned long long) backing_blocks,
			      (unsigned long long) config->physical_blocks);
		return -EINVAL;
	}

	if (vdo_get_admin_state(vdo) == VDO_ADMIN_STATE_PRE_LOADED) {
		vdo_log_info("starting device '%s'", device_name);
		result = perform_admin_operation(vdo, LOAD_PHASE_START, load_callback,
						 handle_load_error, "load");
		if ((result != VDO_SUCCESS) && (result != VDO_READ_ONLY)) {
			/*
			 * Something has gone very wrong. Make sure everything has drained and
			 * leave the device in an unresumable state.
			 */
			vdo_log_error_strerror(result,
					       "Start failed, could not load VDO metadata");
			vdo->suspend_type = VDO_ADMIN_STATE_STOPPING;
			perform_admin_operation(vdo, SUSPEND_PHASE_START,
						suspend_callback, suspend_callback,
						"suspend");
			return result;
		}

		/* Even if the VDO is read-only, it is now able to handle read requests. */
		vdo_log_info("device '%s' started", device_name);
	}

	vdo_log_info("resuming device '%s'", device_name);

	/* If this fails, the VDO was not in a state to be resumed. This should never happen. */
	result = apply_new_vdo_configuration(vdo, config);
	BUG_ON(result == VDO_INVALID_ADMIN_STATE);

	/*
	 * Now that we've tried to modify the vdo, the new config *is* the config, whether the
	 * modifications worked or not.
	 */
	vdo->device_config = config;

	/*
	 * Any error here is highly unexpected and the state of the vdo is questionable, so we mark
	 * it read-only in memory. Because we are suspended, the read-only state will not be
	 * written to disk.
	 */
	if (result != VDO_SUCCESS) {
		vdo_log_error_strerror(result,
				       "Commit of modifications to device '%s' failed",
				       device_name);
		vdo_enter_read_only_mode(vdo, result);
		return result;
	}

	if (vdo_get_admin_state(vdo)->normal) {
		/* The VDO was just started, so we don't need to resume it. */
		return VDO_SUCCESS;
	}

	result = perform_admin_operation(vdo, RESUME_PHASE_START, resume_callback,
					 resume_callback, "resume");
	BUG_ON(result == VDO_INVALID_ADMIN_STATE);
	if (result == VDO_READ_ONLY) {
		/* Even if the vdo is read-only, it has still resumed. */
		result = VDO_SUCCESS;
	}

	if (result != VDO_SUCCESS)
		vdo_log_error("resume of device '%s' failed with error: %d", device_name,
			      result);

	return result;
}

static int vdo_preresume(struct dm_target *ti)
{
	struct registered_thread instance_thread;
	struct vdo *vdo = get_vdo_for_target(ti);
	int result;

	vdo_register_thread_device_id(&instance_thread, &vdo->instance);
	result = vdo_preresume_registered(ti, vdo);
	if ((result == VDO_PARAMETER_MISMATCH) || (result == VDO_INVALID_ADMIN_STATE))
		result = -EINVAL;
	vdo_unregister_thread_device_id();
	return vdo_status_to_errno(result);
}

static void vdo_resume(struct dm_target *ti)
{
	struct registered_thread instance_thread;

	vdo_register_thread_device_id(&instance_thread,
				      &get_vdo_for_target(ti)->instance);
	vdo_log_info("device '%s' resumed", vdo_get_device_name(ti));
	vdo_unregister_thread_device_id();
}

/*
 * If anything changes that affects how user tools will interact with vdo, update the version
 * number and make sure documentation about the change is complete so tools can properly update
 * their management code.
 */
static struct target_type vdo_target_bio = {
	.features = DM_TARGET_SINGLETON,
	.name = "vdo",
	.version = { 9, 0, 0 },
	.module = THIS_MODULE,
	.ctr = vdo_ctr,
	.dtr = vdo_dtr,
	.io_hints = vdo_io_hints,
	.iterate_devices = vdo_iterate_devices,
	.map = vdo_map_bio,
	.message = vdo_message,
	.status = vdo_status,
	.presuspend = vdo_presuspend,
	.postsuspend = vdo_postsuspend,
	.preresume = vdo_preresume,
	.resume = vdo_resume,
};

static bool dm_registered;

static void vdo_module_destroy(void)
{
	vdo_log_debug("unloading");

	if (dm_registered)
		dm_unregister_target(&vdo_target_bio);

	VDO_ASSERT_LOG_ONLY(instances.count == 0,
			    "should have no instance numbers still in use, but have %u",
			    instances.count);
	vdo_free(instances.words);
	memset(&instances, 0, sizeof(struct instance_tracker));
}

static int __init vdo_init(void)
{
	int result = 0;

	/* Memory tracking must be initialized first for accurate accounting. */
	vdo_memory_init();
	vdo_initialize_threads_mutex();
	vdo_initialize_thread_device_registry();
	vdo_initialize_device_registry_once();

	/* Add VDO errors to the set of errors registered by the indexer. */
	result = vdo_register_status_codes();
	if (result != VDO_SUCCESS) {
		vdo_log_error("vdo_register_status_codes failed %d", result);
		vdo_module_destroy();
		return result;
	}

	result = dm_register_target(&vdo_target_bio);
	if (result < 0) {
		vdo_log_error("dm_register_target failed %d", result);
		vdo_module_destroy();
		return result;
	}
	dm_registered = true;

	return result;
}

static void __exit vdo_exit(void)
{
	vdo_module_destroy();
	/* Memory tracking cleanup must be done last. */
	vdo_memory_exit();
}

module_init(vdo_init);
module_exit(vdo_exit);

module_param_named(log_level, vdo_log_level, uint, 0644);
MODULE_PARM_DESC(log_level, "Log level for log messages");

MODULE_DESCRIPTION(DM_NAME " target for transparent deduplication");
MODULE_AUTHOR("Red Hat, Inc.");
MODULE_LICENSE("GPL");
