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 = kzalloc(sizeof(*ti), GFP_KERNEL); 92 93 if (ti) 94 ti->tt = *t; 95 96 return ti; 97 } 98 99 100 int dm_target_iterate(void (*iter_func)(struct target_type *tt, 101 void *param), void *param) 102 { 103 struct tt_internal *ti; 104 105 down_read(&_lock); 106 list_for_each_entry (ti, &_targets, list) 107 iter_func(&ti->tt, param); 108 up_read(&_lock); 109 110 return 0; 111 } 112 113 int dm_register_target(struct target_type *t) 114 { 115 int rv = 0; 116 struct tt_internal *ti = alloc_target(t); 117 118 if (!ti) 119 return -ENOMEM; 120 121 down_write(&_lock); 122 if (__find_target_type(t->name)) 123 rv = -EEXIST; 124 else 125 list_add(&ti->list, &_targets); 126 127 up_write(&_lock); 128 if (rv) 129 kfree(ti); 130 return rv; 131 } 132 133 void dm_unregister_target(struct target_type *t) 134 { 135 struct tt_internal *ti; 136 137 down_write(&_lock); 138 if (!(ti = __find_target_type(t->name))) { 139 DMCRIT("Unregistering unrecognised target: %s", t->name); 140 BUG(); 141 } 142 143 if (ti->use) { 144 DMCRIT("Attempt to unregister target still in use: %s", 145 t->name); 146 BUG(); 147 } 148 149 list_del(&ti->list); 150 kfree(ti); 151 152 up_write(&_lock); 153 } 154 155 /* 156 * io-err: always fails an io, useful for bringing 157 * up LVs that have holes in them. 158 */ 159 static int io_err_ctr(struct dm_target *ti, unsigned int argc, char **args) 160 { 161 return 0; 162 } 163 164 static void io_err_dtr(struct dm_target *ti) 165 { 166 /* empty */ 167 } 168 169 static int io_err_map(struct dm_target *ti, struct bio *bio, 170 union map_info *map_context) 171 { 172 return -EIO; 173 } 174 175 static struct target_type error_target = { 176 .name = "error", 177 .version = {1, 0, 1}, 178 .ctr = io_err_ctr, 179 .dtr = io_err_dtr, 180 .map = io_err_map, 181 }; 182 183 int __init dm_target_init(void) 184 { 185 return dm_register_target(&error_target); 186 } 187 188 void dm_target_exit(void) 189 { 190 dm_unregister_target(&error_target); 191 } 192 193 EXPORT_SYMBOL(dm_register_target); 194 EXPORT_SYMBOL(dm_unregister_target); 195