dm-target.c 3.2 KB

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