// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2001 Sistina Software (UK) Limited
 *
 * This file is released under the GPL.
 */

#include "dm-core.h"

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kmod.h>
#include <linux/bio.h>
#include <linux/dax.h>

#define DM_MSG_PREFIX "target"

static LIST_HEAD(_targets);
static DECLARE_RWSEM(_lock);

static inline struct target_type *__find_target_type(const char *name)
{
	struct target_type *tt;

	list_for_each_entry(tt, &_targets, list)
		if (!strcmp(name, tt->name))
			return tt;

	return NULL;
}

static struct target_type *get_target_type(const char *name)
{
	struct target_type *tt;

	down_read(&_lock);

	tt = __find_target_type(name);
	if (tt && !try_module_get(tt->module))
		tt = NULL;

	up_read(&_lock);
	return tt;
}

static void load_module(const char *name)
{
	request_module("dm-%s", name);
}

struct target_type *dm_get_target_type(const char *name)
{
	struct target_type *tt = get_target_type(name);

	if (!tt) {
		load_module(name);
		tt = get_target_type(name);
	}

	return tt;
}

void dm_put_target_type(struct target_type *tt)
{
	down_read(&_lock);
	module_put(tt->module);
	up_read(&_lock);
}

int dm_target_iterate(void (*iter_func)(struct target_type *tt,
					void *param), void *param)
{
	struct target_type *tt;

	down_read(&_lock);
	list_for_each_entry(tt, &_targets, list)
		iter_func(tt, param);
	up_read(&_lock);

	return 0;
}

int dm_register_target(struct target_type *tt)
{
	int rv = 0;

	down_write(&_lock);
	if (__find_target_type(tt->name)) {
		DMERR("%s: '%s' target already registered",
		      __func__, tt->name);
		rv = -EEXIST;
	} else {
		list_add(&tt->list, &_targets);
	}
	up_write(&_lock);

	return rv;
}
EXPORT_SYMBOL(dm_register_target);

void dm_unregister_target(struct target_type *tt)
{
	down_write(&_lock);
	if (!__find_target_type(tt->name)) {
		DMCRIT("Unregistering unrecognised target: %s", tt->name);
		BUG();
	}

	list_del(&tt->list);

	up_write(&_lock);
}
EXPORT_SYMBOL(dm_unregister_target);

/*
 * io-err: always fails an io, useful for bringing
 * up LVs that have holes in them.
 */
struct io_err_c {
	struct dm_dev *dev;
	sector_t start;
};

static int io_err_get_args(struct dm_target *tt, unsigned int argc, char **args)
{
	unsigned long long start;
	struct io_err_c *ioec;
	char dummy;
	int ret;

	ioec = kmalloc(sizeof(*ioec), GFP_KERNEL);
	if (!ioec) {
		tt->error = "Cannot allocate io_err context";
		return -ENOMEM;
	}

	ret = -EINVAL;
	if (sscanf(args[1], "%llu%c", &start, &dummy) != 1 ||
	    start != (sector_t)start) {
		tt->error = "Invalid device sector";
		goto bad;
	}
	ioec->start = start;

	ret = dm_get_device(tt, args[0], dm_table_get_mode(tt->table), &ioec->dev);
	if (ret) {
		tt->error = "Device lookup failed";
		goto bad;
	}

	tt->private = ioec;

	return 0;

bad:
	kfree(ioec);

	return ret;
}

static int io_err_ctr(struct dm_target *tt, unsigned int argc, char **args)
{
	/*
	 * If we have arguments, assume it is the path to the backing
	 * block device and its mapping start sector (same as dm-linear).
	 * In this case, get the device so that we can get its limits.
	 */
	if (argc == 2) {
		int ret = io_err_get_args(tt, argc, args);

		if (ret)
			return ret;
	}

	/*
	 * Return error for discards instead of -EOPNOTSUPP
	 */
	tt->num_discard_bios = 1;
	tt->discards_supported = true;

	return 0;
}

static void io_err_dtr(struct dm_target *tt)
{
	struct io_err_c *ioec = tt->private;

	if (ioec) {
		dm_put_device(tt, ioec->dev);
		kfree(ioec);
	}
}

static int io_err_map(struct dm_target *tt, struct bio *bio)
{
	return DM_MAPIO_KILL;
}

static int io_err_clone_and_map_rq(struct dm_target *ti, struct request *rq,
				   union map_info *map_context,
				   struct request **clone)
{
	return DM_MAPIO_KILL;
}

static void io_err_release_clone_rq(struct request *clone,
				    union map_info *map_context)
{
}

#ifdef CONFIG_BLK_DEV_ZONED
static sector_t io_err_map_sector(struct dm_target *ti, sector_t bi_sector)
{
	struct io_err_c *ioec = ti->private;

	return ioec->start + dm_target_offset(ti, bi_sector);
}

static int io_err_report_zones(struct dm_target *ti,
		struct dm_report_zones_args *args, unsigned int nr_zones)
{
	struct io_err_c *ioec = ti->private;

	/*
	 * This should never be called when we do not have a backing device
	 * as that mean the target is not a zoned one.
	 */
	if (WARN_ON_ONCE(!ioec))
		return -EIO;

	return dm_report_zones(ioec->dev->bdev, ioec->start,
			       io_err_map_sector(ti, args->next_sector),
			       args, nr_zones);
}
#else
#define io_err_report_zones NULL
#endif

static int io_err_iterate_devices(struct dm_target *ti,
				  iterate_devices_callout_fn fn, void *data)
{
	struct io_err_c *ioec = ti->private;

	if (!ioec)
		return 0;

	return fn(ti, ioec->dev, ioec->start, ti->len, data);
}

static void io_err_io_hints(struct dm_target *ti, struct queue_limits *limits)
{
	limits->max_discard_sectors = UINT_MAX;
	limits->max_hw_discard_sectors = UINT_MAX;
	limits->discard_granularity = 512;
}

static long io_err_dax_direct_access(struct dm_target *ti, pgoff_t pgoff,
		long nr_pages, enum dax_access_mode mode, void **kaddr,
		pfn_t *pfn)
{
	return -EIO;
}

static struct target_type error_target = {
	.name = "error",
	.version = {1, 7, 0},
	.features = DM_TARGET_WILDCARD | DM_TARGET_ZONED_HM,
	.ctr  = io_err_ctr,
	.dtr  = io_err_dtr,
	.map  = io_err_map,
	.clone_and_map_rq = io_err_clone_and_map_rq,
	.release_clone_rq = io_err_release_clone_rq,
	.iterate_devices = io_err_iterate_devices,
	.io_hints = io_err_io_hints,
	.direct_access = io_err_dax_direct_access,
	.report_zones = io_err_report_zones,
};

int __init dm_target_init(void)
{
	return dm_register_target(&error_target);
}

void dm_target_exit(void)
{
	dm_unregister_target(&error_target);
}
