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