cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dm-target.c (3244B)


      1/*
      2 * Copyright (C) 2001 Sistina Software (UK) Limited
      3 *
      4 * This file is released under the GPL.
      5 */
      6
      7#include "dm-core.h"
      8
      9#include <linux/module.h>
     10#include <linux/init.h>
     11#include <linux/kmod.h>
     12#include <linux/bio.h>
     13#include <linux/dax.h>
     14
     15#define DM_MSG_PREFIX "target"
     16
     17static LIST_HEAD(_targets);
     18static DECLARE_RWSEM(_lock);
     19
     20static inline struct target_type *__find_target_type(const char *name)
     21{
     22	struct target_type *tt;
     23
     24	list_for_each_entry(tt, &_targets, list)
     25		if (!strcmp(name, tt->name))
     26			return tt;
     27
     28	return NULL;
     29}
     30
     31static struct target_type *get_target_type(const char *name)
     32{
     33	struct target_type *tt;
     34
     35	down_read(&_lock);
     36
     37	tt = __find_target_type(name);
     38	if (tt && !try_module_get(tt->module))
     39		tt = NULL;
     40
     41	up_read(&_lock);
     42	return tt;
     43}
     44
     45static void load_module(const char *name)
     46{
     47	request_module("dm-%s", name);
     48}
     49
     50struct target_type *dm_get_target_type(const char *name)
     51{
     52	struct target_type *tt = get_target_type(name);
     53
     54	if (!tt) {
     55		load_module(name);
     56		tt = get_target_type(name);
     57	}
     58
     59	return tt;
     60}
     61
     62void dm_put_target_type(struct target_type *tt)
     63{
     64	down_read(&_lock);
     65	module_put(tt->module);
     66	up_read(&_lock);
     67}
     68
     69int dm_target_iterate(void (*iter_func)(struct target_type *tt,
     70					void *param), void *param)
     71{
     72	struct target_type *tt;
     73
     74	down_read(&_lock);
     75	list_for_each_entry(tt, &_targets, list)
     76		iter_func(tt, param);
     77	up_read(&_lock);
     78
     79	return 0;
     80}
     81
     82int dm_register_target(struct target_type *tt)
     83{
     84	int rv = 0;
     85
     86	down_write(&_lock);
     87	if (__find_target_type(tt->name))
     88		rv = -EEXIST;
     89	else
     90		list_add(&tt->list, &_targets);
     91
     92	up_write(&_lock);
     93	return rv;
     94}
     95
     96void dm_unregister_target(struct target_type *tt)
     97{
     98	down_write(&_lock);
     99	if (!__find_target_type(tt->name)) {
    100		DMCRIT("Unregistering unrecognised target: %s", tt->name);
    101		BUG();
    102	}
    103
    104	list_del(&tt->list);
    105
    106	up_write(&_lock);
    107}
    108
    109/*
    110 * io-err: always fails an io, useful for bringing
    111 * up LVs that have holes in them.
    112 */
    113static int io_err_ctr(struct dm_target *tt, unsigned int argc, char **args)
    114{
    115	/*
    116	 * Return error for discards instead of -EOPNOTSUPP
    117	 */
    118	tt->num_discard_bios = 1;
    119
    120	return 0;
    121}
    122
    123static void io_err_dtr(struct dm_target *tt)
    124{
    125	/* empty */
    126}
    127
    128static int io_err_map(struct dm_target *tt, struct bio *bio)
    129{
    130	return DM_MAPIO_KILL;
    131}
    132
    133static int io_err_clone_and_map_rq(struct dm_target *ti, struct request *rq,
    134				   union map_info *map_context,
    135				   struct request **clone)
    136{
    137	return DM_MAPIO_KILL;
    138}
    139
    140static void io_err_release_clone_rq(struct request *clone,
    141				    union map_info *map_context)
    142{
    143}
    144
    145static long io_err_dax_direct_access(struct dm_target *ti, pgoff_t pgoff,
    146		long nr_pages, enum dax_access_mode mode, void **kaddr,
    147		pfn_t *pfn)
    148{
    149	return -EIO;
    150}
    151
    152static struct target_type error_target = {
    153	.name = "error",
    154	.version = {1, 5, 0},
    155	.features = DM_TARGET_WILDCARD,
    156	.ctr  = io_err_ctr,
    157	.dtr  = io_err_dtr,
    158	.map  = io_err_map,
    159	.clone_and_map_rq = io_err_clone_and_map_rq,
    160	.release_clone_rq = io_err_release_clone_rq,
    161	.direct_access = io_err_dax_direct_access,
    162};
    163
    164int __init dm_target_init(void)
    165{
    166	return dm_register_target(&error_target);
    167}
    168
    169void dm_target_exit(void)
    170{
    171	dm_unregister_target(&error_target);
    172}
    173
    174EXPORT_SYMBOL(dm_register_target);
    175EXPORT_SYMBOL(dm_unregister_target);