dm-target.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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. if (ti->use < 0)
  62. BUG();
  63. up_read(&_lock);
  64. return;
  65. }
  66. static struct tt_internal *alloc_target(struct target_type *t)
  67. {
  68. struct tt_internal *ti = kmalloc(sizeof(*ti), GFP_KERNEL);
  69. if (ti) {
  70. memset(ti, 0, sizeof(*ti));
  71. ti->tt = *t;
  72. }
  73. return ti;
  74. }
  75. int dm_target_iterate(void (*iter_func)(struct target_type *tt,
  76. void *param), void *param)
  77. {
  78. struct tt_internal *ti;
  79. down_read(&_lock);
  80. list_for_each_entry (ti, &_targets, list)
  81. iter_func(&ti->tt, param);
  82. up_read(&_lock);
  83. return 0;
  84. }
  85. int dm_register_target(struct target_type *t)
  86. {
  87. int rv = 0;
  88. struct tt_internal *ti = alloc_target(t);
  89. if (!ti)
  90. return -ENOMEM;
  91. down_write(&_lock);
  92. if (__find_target_type(t->name))
  93. rv = -EEXIST;
  94. else
  95. list_add(&ti->list, &_targets);
  96. up_write(&_lock);
  97. if (rv)
  98. kfree(ti);
  99. return rv;
  100. }
  101. int dm_unregister_target(struct target_type *t)
  102. {
  103. struct tt_internal *ti;
  104. down_write(&_lock);
  105. if (!(ti = __find_target_type(t->name))) {
  106. up_write(&_lock);
  107. return -EINVAL;
  108. }
  109. if (ti->use) {
  110. up_write(&_lock);
  111. return -ETXTBSY;
  112. }
  113. list_del(&ti->list);
  114. kfree(ti);
  115. up_write(&_lock);
  116. return 0;
  117. }
  118. /*
  119. * io-err: always fails an io, useful for bringing
  120. * up LVs that have holes in them.
  121. */
  122. static int io_err_ctr(struct dm_target *ti, unsigned int argc, char **args)
  123. {
  124. return 0;
  125. }
  126. static void io_err_dtr(struct dm_target *ti)
  127. {
  128. /* empty */
  129. }
  130. static int io_err_map(struct dm_target *ti, struct bio *bio,
  131. union map_info *map_context)
  132. {
  133. return -EIO;
  134. }
  135. static struct target_type error_target = {
  136. .name = "error",
  137. .version = {1, 0, 1},
  138. .ctr = io_err_ctr,
  139. .dtr = io_err_dtr,
  140. .map = io_err_map,
  141. };
  142. int __init dm_target_init(void)
  143. {
  144. return dm_register_target(&error_target);
  145. }
  146. void dm_target_exit(void)
  147. {
  148. if (dm_unregister_target(&error_target))
  149. DMWARN("error target unregistration failed");
  150. }
  151. EXPORT_SYMBOL(dm_register_target);
  152. EXPORT_SYMBOL(dm_unregister_target);