Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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