md-faulty.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * faulty.c : Multiple Devices driver for Linux
  4. *
  5. * Copyright (C) 2004 Neil Brown
  6. *
  7. * fautly-device-simulator personality for md
  8. */
  9. /*
  10. * The "faulty" personality causes some requests to fail.
  11. *
  12. * Possible failure modes are:
  13. * reads fail "randomly" but succeed on retry
  14. * writes fail "randomly" but succeed on retry
  15. * reads for some address fail and then persist until a write
  16. * reads for some address fail and then persist irrespective of write
  17. * writes for some address fail and persist
  18. * all writes fail
  19. *
  20. * Different modes can be active at a time, but only
  21. * one can be set at array creation. Others can be added later.
  22. * A mode can be one-shot or recurrent with the recurrence being
  23. * once in every N requests.
  24. * The bottom 5 bits of the "layout" indicate the mode. The
  25. * remainder indicate a period, or 0 for one-shot.
  26. *
  27. * There is an implementation limit on the number of concurrently
  28. * persisting-faulty blocks. When a new fault is requested that would
  29. * exceed the limit, it is ignored.
  30. * All current faults can be clear using a layout of "0".
  31. *
  32. * Requests are always sent to the device. If they are to fail,
  33. * we clone the bio and insert a new b_end_io into the chain.
  34. */
  35. #define WriteTransient 0
  36. #define ReadTransient 1
  37. #define WritePersistent 2
  38. #define ReadPersistent 3
  39. #define WriteAll 4 /* doesn't go to device */
  40. #define ReadFixable 5
  41. #define Modes 6
  42. #define ClearErrors 31
  43. #define ClearFaults 30
  44. #define AllPersist 100 /* internal use only */
  45. #define NoPersist 101
  46. #define ModeMask 0x1f
  47. #define ModeShift 5
  48. #define MaxFault 50
  49. #include <linux/blkdev.h>
  50. #include <linux/module.h>
  51. #include <linux/raid/md_u.h>
  52. #include <linux/slab.h>
  53. #include "md.h"
  54. #include <linux/seq_file.h>
  55. static void faulty_fail(struct bio *bio)
  56. {
  57. struct bio *b = bio->bi_private;
  58. b->bi_iter.bi_size = bio->bi_iter.bi_size;
  59. b->bi_iter.bi_sector = bio->bi_iter.bi_sector;
  60. bio_put(bio);
  61. bio_io_error(b);
  62. }
  63. struct faulty_conf {
  64. int period[Modes];
  65. atomic_t counters[Modes];
  66. sector_t faults[MaxFault];
  67. int modes[MaxFault];
  68. int nfaults;
  69. struct md_rdev *rdev;
  70. };
  71. static int check_mode(struct faulty_conf *conf, int mode)
  72. {
  73. if (conf->period[mode] == 0 &&
  74. atomic_read(&conf->counters[mode]) <= 0)
  75. return 0; /* no failure, no decrement */
  76. if (atomic_dec_and_test(&conf->counters[mode])) {
  77. if (conf->period[mode])
  78. atomic_set(&conf->counters[mode], conf->period[mode]);
  79. return 1;
  80. }
  81. return 0;
  82. }
  83. static int check_sector(struct faulty_conf *conf, sector_t start, sector_t end, int dir)
  84. {
  85. /* If we find a ReadFixable sector, we fix it ... */
  86. int i;
  87. for (i=0; i<conf->nfaults; i++)
  88. if (conf->faults[i] >= start &&
  89. conf->faults[i] < end) {
  90. /* found it ... */
  91. switch (conf->modes[i] * 2 + dir) {
  92. case WritePersistent*2+WRITE: return 1;
  93. case ReadPersistent*2+READ: return 1;
  94. case ReadFixable*2+READ: return 1;
  95. case ReadFixable*2+WRITE:
  96. conf->modes[i] = NoPersist;
  97. return 0;
  98. case AllPersist*2+READ:
  99. case AllPersist*2+WRITE: return 1;
  100. default:
  101. return 0;
  102. }
  103. }
  104. return 0;
  105. }
  106. static void add_sector(struct faulty_conf *conf, sector_t start, int mode)
  107. {
  108. int i;
  109. int n = conf->nfaults;
  110. for (i=0; i<conf->nfaults; i++)
  111. if (conf->faults[i] == start) {
  112. switch(mode) {
  113. case NoPersist: conf->modes[i] = mode; return;
  114. case WritePersistent:
  115. if (conf->modes[i] == ReadPersistent ||
  116. conf->modes[i] == ReadFixable)
  117. conf->modes[i] = AllPersist;
  118. else
  119. conf->modes[i] = WritePersistent;
  120. return;
  121. case ReadPersistent:
  122. if (conf->modes[i] == WritePersistent)
  123. conf->modes[i] = AllPersist;
  124. else
  125. conf->modes[i] = ReadPersistent;
  126. return;
  127. case ReadFixable:
  128. if (conf->modes[i] == WritePersistent ||
  129. conf->modes[i] == ReadPersistent)
  130. conf->modes[i] = AllPersist;
  131. else
  132. conf->modes[i] = ReadFixable;
  133. return;
  134. }
  135. } else if (conf->modes[i] == NoPersist)
  136. n = i;
  137. if (n >= MaxFault)
  138. return;
  139. conf->faults[n] = start;
  140. conf->modes[n] = mode;
  141. if (conf->nfaults == n)
  142. conf->nfaults = n+1;
  143. }
  144. static bool faulty_make_request(struct mddev *mddev, struct bio *bio)
  145. {
  146. struct faulty_conf *conf = mddev->private;
  147. int failit = 0;
  148. if (bio_data_dir(bio) == WRITE) {
  149. /* write request */
  150. if (atomic_read(&conf->counters[WriteAll])) {
  151. /* special case - don't decrement, don't generic_make_request,
  152. * just fail immediately
  153. */
  154. bio_io_error(bio);
  155. return true;
  156. }
  157. if (check_sector(conf, bio->bi_iter.bi_sector,
  158. bio_end_sector(bio), WRITE))
  159. failit = 1;
  160. if (check_mode(conf, WritePersistent)) {
  161. add_sector(conf, bio->bi_iter.bi_sector,
  162. WritePersistent);
  163. failit = 1;
  164. }
  165. if (check_mode(conf, WriteTransient))
  166. failit = 1;
  167. } else {
  168. /* read request */
  169. if (check_sector(conf, bio->bi_iter.bi_sector,
  170. bio_end_sector(bio), READ))
  171. failit = 1;
  172. if (check_mode(conf, ReadTransient))
  173. failit = 1;
  174. if (check_mode(conf, ReadPersistent)) {
  175. add_sector(conf, bio->bi_iter.bi_sector,
  176. ReadPersistent);
  177. failit = 1;
  178. }
  179. if (check_mode(conf, ReadFixable)) {
  180. add_sector(conf, bio->bi_iter.bi_sector,
  181. ReadFixable);
  182. failit = 1;
  183. }
  184. }
  185. if (failit) {
  186. struct bio *b = bio_clone_fast(bio, GFP_NOIO, &mddev->bio_set);
  187. bio_set_dev(b, conf->rdev->bdev);
  188. b->bi_private = bio;
  189. b->bi_end_io = faulty_fail;
  190. bio = b;
  191. } else
  192. bio_set_dev(bio, conf->rdev->bdev);
  193. generic_make_request(bio);
  194. return true;
  195. }
  196. static void faulty_status(struct seq_file *seq, struct mddev *mddev)
  197. {
  198. struct faulty_conf *conf = mddev->private;
  199. int n;
  200. if ((n=atomic_read(&conf->counters[WriteTransient])) != 0)
  201. seq_printf(seq, " WriteTransient=%d(%d)",
  202. n, conf->period[WriteTransient]);
  203. if ((n=atomic_read(&conf->counters[ReadTransient])) != 0)
  204. seq_printf(seq, " ReadTransient=%d(%d)",
  205. n, conf->period[ReadTransient]);
  206. if ((n=atomic_read(&conf->counters[WritePersistent])) != 0)
  207. seq_printf(seq, " WritePersistent=%d(%d)",
  208. n, conf->period[WritePersistent]);
  209. if ((n=atomic_read(&conf->counters[ReadPersistent])) != 0)
  210. seq_printf(seq, " ReadPersistent=%d(%d)",
  211. n, conf->period[ReadPersistent]);
  212. if ((n=atomic_read(&conf->counters[ReadFixable])) != 0)
  213. seq_printf(seq, " ReadFixable=%d(%d)",
  214. n, conf->period[ReadFixable]);
  215. if ((n=atomic_read(&conf->counters[WriteAll])) != 0)
  216. seq_printf(seq, " WriteAll");
  217. seq_printf(seq, " nfaults=%d", conf->nfaults);
  218. }
  219. static int faulty_reshape(struct mddev *mddev)
  220. {
  221. int mode = mddev->new_layout & ModeMask;
  222. int count = mddev->new_layout >> ModeShift;
  223. struct faulty_conf *conf = mddev->private;
  224. if (mddev->new_layout < 0)
  225. return 0;
  226. /* new layout */
  227. if (mode == ClearFaults)
  228. conf->nfaults = 0;
  229. else if (mode == ClearErrors) {
  230. int i;
  231. for (i=0 ; i < Modes ; i++) {
  232. conf->period[i] = 0;
  233. atomic_set(&conf->counters[i], 0);
  234. }
  235. } else if (mode < Modes) {
  236. conf->period[mode] = count;
  237. if (!count) count++;
  238. atomic_set(&conf->counters[mode], count);
  239. } else
  240. return -EINVAL;
  241. mddev->new_layout = -1;
  242. mddev->layout = -1; /* makes sure further changes come through */
  243. return 0;
  244. }
  245. static sector_t faulty_size(struct mddev *mddev, sector_t sectors, int raid_disks)
  246. {
  247. WARN_ONCE(raid_disks,
  248. "%s does not support generic reshape\n", __func__);
  249. if (sectors == 0)
  250. return mddev->dev_sectors;
  251. return sectors;
  252. }
  253. static int faulty_run(struct mddev *mddev)
  254. {
  255. struct md_rdev *rdev;
  256. int i;
  257. struct faulty_conf *conf;
  258. if (md_check_no_bitmap(mddev))
  259. return -EINVAL;
  260. conf = kmalloc(sizeof(*conf), GFP_KERNEL);
  261. if (!conf)
  262. return -ENOMEM;
  263. for (i=0; i<Modes; i++) {
  264. atomic_set(&conf->counters[i], 0);
  265. conf->period[i] = 0;
  266. }
  267. conf->nfaults = 0;
  268. rdev_for_each(rdev, mddev) {
  269. conf->rdev = rdev;
  270. disk_stack_limits(mddev->gendisk, rdev->bdev,
  271. rdev->data_offset << 9);
  272. }
  273. md_set_array_sectors(mddev, faulty_size(mddev, 0, 0));
  274. mddev->private = conf;
  275. faulty_reshape(mddev);
  276. return 0;
  277. }
  278. static void faulty_free(struct mddev *mddev, void *priv)
  279. {
  280. struct faulty_conf *conf = priv;
  281. kfree(conf);
  282. }
  283. static struct md_personality faulty_personality =
  284. {
  285. .name = "faulty",
  286. .level = LEVEL_FAULTY,
  287. .owner = THIS_MODULE,
  288. .make_request = faulty_make_request,
  289. .run = faulty_run,
  290. .free = faulty_free,
  291. .status = faulty_status,
  292. .check_reshape = faulty_reshape,
  293. .size = faulty_size,
  294. };
  295. static int __init raid_init(void)
  296. {
  297. return register_md_personality(&faulty_personality);
  298. }
  299. static void raid_exit(void)
  300. {
  301. unregister_md_personality(&faulty_personality);
  302. }
  303. module_init(raid_init);
  304. module_exit(raid_exit);
  305. MODULE_LICENSE("GPL");
  306. MODULE_DESCRIPTION("Fault injection personality for MD");
  307. MODULE_ALIAS("md-personality-10"); /* faulty */
  308. MODULE_ALIAS("md-faulty");
  309. MODULE_ALIAS("md-level--5");