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