1 /* 2 * Copyright (C) 2001 Sistina Software (UK) Limited 3 * 4 * This file is released under the GPL. 5 */ 6 7 #include "dm.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/slab.h> 14 15 #define DM_MSG_PREFIX "target" 16 17 struct tt_internal { 18 struct target_type tt; 19 20 struct list_head list; 21 long use; 22 }; 23 24 static LIST_HEAD(_targets); 25 static DECLARE_RWSEM(_lock); 26 27 #define DM_MOD_NAME_SIZE 32 28 29 static inline struct tt_internal *__find_target_type(const char *name) 30 { 31 struct tt_internal *ti; 32 33 list_for_each_entry (ti, &_targets, list) 34 if (!strcmp(name, ti->tt.name)) 35 return ti; 36 37 return NULL; 38 } 39 40 static struct tt_internal *get_target_type(const char *name) 41 { 42 struct tt_internal *ti; 43 44 down_read(&_lock); 45 46 ti = __find_target_type(name); 47 if (ti) { 48 if ((ti->use == 0) && !try_module_get(ti->tt.module)) 49 ti = NULL; 50 else 51 ti->use++; 52 } 53 54 up_read(&_lock); 55 return ti; 56 } 57 58 static void load_module(const char *name) 59 { 60 request_module("dm-%s", name); 61 } 62 63 struct target_type *dm_get_target_type(const char *name) 64 { 65 struct tt_internal *ti = get_target_type(name); 66 67 if (!ti) { 68 load_module(name); 69 ti = get_target_type(name); 70 } 71 72 return ti ? &ti->tt : NULL; 73 } 74 75 void dm_put_target_type(struct target_type *t) 76 { 77 struct tt_internal *ti = (struct tt_internal *) t; 78 79 down_read(&_lock); 80 if (--ti->use == 0) 81 module_put(ti->tt.module); 82 83 BUG_ON(ti->use < 0); 84 up_read(&_lock); 85 86 return; 87 } 88 89 static struct tt_internal *alloc_target(struct target_type *t) 90 { 91 struct tt_internal *ti = kmalloc(sizeof(*ti), GFP_KERNEL); 92 93 if (ti) { 94 memset(ti, 0, sizeof(*ti)); 95 ti->tt = *t; 96 } 97 98 return ti; 99 } 100 101 102 int dm_target_iterate(void (*iter_func)(struct target_type *tt, 103 void *param), void *param) 104 { 105 struct tt_internal *ti; 106 107 down_read(&_lock); 108 list_for_each_entry (ti, &_targets, list) 109 iter_func(&ti->tt, param); 110 up_read(&_lock); 111 112 return 0; 113 } 114 115 int dm_register_target(struct target_type *t) 116 { 117 int rv = 0; 118 struct tt_internal *ti = alloc_target(t); 119 120 if (!ti) 121 return -ENOMEM; 122 123 down_write(&_lock); 124 if (__find_target_type(t->name)) 125 rv = -EEXIST; 126 else 127 list_add(&ti->list, &_targets); 128 129 up_write(&_lock); 130 if (rv) 131 kfree(ti); 132 return rv; 133 } 134 135 int dm_unregister_target(struct target_type *t) 136 { 137 struct tt_internal *ti; 138 139 down_write(&_lock); 140 if (!(ti = __find_target_type(t->name))) { 141 up_write(&_lock); 142 return -EINVAL; 143 } 144 145 if (ti->use) { 146 up_write(&_lock); 147 return -ETXTBSY; 148 } 149 150 list_del(&ti->list); 151 kfree(ti); 152 153 up_write(&_lock); 154 return 0; 155 } 156 157 /* 158 * io-err: always fails an io, useful for bringing 159 * up LVs that have holes in them. 160 */ 161 static int io_err_ctr(struct dm_target *ti, unsigned int argc, char **args) 162 { 163 return 0; 164 } 165 166 static void io_err_dtr(struct dm_target *ti) 167 { 168 /* empty */ 169 } 170 171 static int io_err_map(struct dm_target *ti, struct bio *bio, 172 union map_info *map_context) 173 { 174 return -EIO; 175 } 176 177 static struct target_type error_target = { 178 .name = "error", 179 .version = {1, 0, 1}, 180 .ctr = io_err_ctr, 181 .dtr = io_err_dtr, 182 .map = io_err_map, 183 }; 184 185 int __init dm_target_init(void) 186 { 187 return dm_register_target(&error_target); 188 } 189 190 void dm_target_exit(void) 191 { 192 if (dm_unregister_target(&error_target)) 193 DMWARN("error target unregistration failed"); 194 } 195 196 EXPORT_SYMBOL(dm_register_target); 197 EXPORT_SYMBOL(dm_unregister_target); 198