0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 #define WriteTransient 0
0039 #define ReadTransient 1
0040 #define WritePersistent 2
0041 #define ReadPersistent 3
0042 #define WriteAll 4
0043 #define ReadFixable 5
0044 #define Modes 6
0045
0046 #define ClearErrors 31
0047 #define ClearFaults 30
0048
0049 #define AllPersist 100
0050 #define NoPersist 101
0051
0052 #define ModeMask 0x1f
0053 #define ModeShift 5
0054
0055 #define MaxFault 50
0056 #include <linux/blkdev.h>
0057 #include <linux/module.h>
0058 #include <linux/raid/md_u.h>
0059 #include <linux/slab.h>
0060 #include "md.h"
0061 #include <linux/seq_file.h>
0062
0063
0064 static void faulty_fail(struct bio *bio)
0065 {
0066 struct bio *b = bio->bi_private;
0067
0068 b->bi_iter.bi_size = bio->bi_iter.bi_size;
0069 b->bi_iter.bi_sector = bio->bi_iter.bi_sector;
0070
0071 bio_put(bio);
0072
0073 bio_io_error(b);
0074 }
0075
0076 struct faulty_conf {
0077 int period[Modes];
0078 atomic_t counters[Modes];
0079 sector_t faults[MaxFault];
0080 int modes[MaxFault];
0081 int nfaults;
0082 struct md_rdev *rdev;
0083 };
0084
0085 static int check_mode(struct faulty_conf *conf, int mode)
0086 {
0087 if (conf->period[mode] == 0 &&
0088 atomic_read(&conf->counters[mode]) <= 0)
0089 return 0;
0090
0091
0092 if (atomic_dec_and_test(&conf->counters[mode])) {
0093 if (conf->period[mode])
0094 atomic_set(&conf->counters[mode], conf->period[mode]);
0095 return 1;
0096 }
0097 return 0;
0098 }
0099
0100 static int check_sector(struct faulty_conf *conf, sector_t start, sector_t end, int dir)
0101 {
0102
0103 int i;
0104 for (i=0; i<conf->nfaults; i++)
0105 if (conf->faults[i] >= start &&
0106 conf->faults[i] < end) {
0107
0108 switch (conf->modes[i] * 2 + dir) {
0109 case WritePersistent*2+WRITE: return 1;
0110 case ReadPersistent*2+READ: return 1;
0111 case ReadFixable*2+READ: return 1;
0112 case ReadFixable*2+WRITE:
0113 conf->modes[i] = NoPersist;
0114 return 0;
0115 case AllPersist*2+READ:
0116 case AllPersist*2+WRITE: return 1;
0117 default:
0118 return 0;
0119 }
0120 }
0121 return 0;
0122 }
0123
0124 static void add_sector(struct faulty_conf *conf, sector_t start, int mode)
0125 {
0126 int i;
0127 int n = conf->nfaults;
0128 for (i=0; i<conf->nfaults; i++)
0129 if (conf->faults[i] == start) {
0130 switch(mode) {
0131 case NoPersist: conf->modes[i] = mode; return;
0132 case WritePersistent:
0133 if (conf->modes[i] == ReadPersistent ||
0134 conf->modes[i] == ReadFixable)
0135 conf->modes[i] = AllPersist;
0136 else
0137 conf->modes[i] = WritePersistent;
0138 return;
0139 case ReadPersistent:
0140 if (conf->modes[i] == WritePersistent)
0141 conf->modes[i] = AllPersist;
0142 else
0143 conf->modes[i] = ReadPersistent;
0144 return;
0145 case ReadFixable:
0146 if (conf->modes[i] == WritePersistent ||
0147 conf->modes[i] == ReadPersistent)
0148 conf->modes[i] = AllPersist;
0149 else
0150 conf->modes[i] = ReadFixable;
0151 return;
0152 }
0153 } else if (conf->modes[i] == NoPersist)
0154 n = i;
0155
0156 if (n >= MaxFault)
0157 return;
0158 conf->faults[n] = start;
0159 conf->modes[n] = mode;
0160 if (conf->nfaults == n)
0161 conf->nfaults = n+1;
0162 }
0163
0164 static bool faulty_make_request(struct mddev *mddev, struct bio *bio)
0165 {
0166 struct faulty_conf *conf = mddev->private;
0167 int failit = 0;
0168
0169 if (bio_data_dir(bio) == WRITE) {
0170
0171 if (atomic_read(&conf->counters[WriteAll])) {
0172
0173
0174
0175 bio_io_error(bio);
0176 return true;
0177 }
0178
0179 if (check_sector(conf, bio->bi_iter.bi_sector,
0180 bio_end_sector(bio), WRITE))
0181 failit = 1;
0182 if (check_mode(conf, WritePersistent)) {
0183 add_sector(conf, bio->bi_iter.bi_sector,
0184 WritePersistent);
0185 failit = 1;
0186 }
0187 if (check_mode(conf, WriteTransient))
0188 failit = 1;
0189 } else {
0190
0191 if (check_sector(conf, bio->bi_iter.bi_sector,
0192 bio_end_sector(bio), READ))
0193 failit = 1;
0194 if (check_mode(conf, ReadTransient))
0195 failit = 1;
0196 if (check_mode(conf, ReadPersistent)) {
0197 add_sector(conf, bio->bi_iter.bi_sector,
0198 ReadPersistent);
0199 failit = 1;
0200 }
0201 if (check_mode(conf, ReadFixable)) {
0202 add_sector(conf, bio->bi_iter.bi_sector,
0203 ReadFixable);
0204 failit = 1;
0205 }
0206 }
0207 if (failit) {
0208 struct bio *b = bio_alloc_clone(conf->rdev->bdev, bio, GFP_NOIO,
0209 &mddev->bio_set);
0210
0211 b->bi_private = bio;
0212 b->bi_end_io = faulty_fail;
0213 bio = b;
0214 } else
0215 bio_set_dev(bio, conf->rdev->bdev);
0216
0217 submit_bio_noacct(bio);
0218 return true;
0219 }
0220
0221 static void faulty_status(struct seq_file *seq, struct mddev *mddev)
0222 {
0223 struct faulty_conf *conf = mddev->private;
0224 int n;
0225
0226 if ((n=atomic_read(&conf->counters[WriteTransient])) != 0)
0227 seq_printf(seq, " WriteTransient=%d(%d)",
0228 n, conf->period[WriteTransient]);
0229
0230 if ((n=atomic_read(&conf->counters[ReadTransient])) != 0)
0231 seq_printf(seq, " ReadTransient=%d(%d)",
0232 n, conf->period[ReadTransient]);
0233
0234 if ((n=atomic_read(&conf->counters[WritePersistent])) != 0)
0235 seq_printf(seq, " WritePersistent=%d(%d)",
0236 n, conf->period[WritePersistent]);
0237
0238 if ((n=atomic_read(&conf->counters[ReadPersistent])) != 0)
0239 seq_printf(seq, " ReadPersistent=%d(%d)",
0240 n, conf->period[ReadPersistent]);
0241
0242
0243 if ((n=atomic_read(&conf->counters[ReadFixable])) != 0)
0244 seq_printf(seq, " ReadFixable=%d(%d)",
0245 n, conf->period[ReadFixable]);
0246
0247 if ((n=atomic_read(&conf->counters[WriteAll])) != 0)
0248 seq_printf(seq, " WriteAll");
0249
0250 seq_printf(seq, " nfaults=%d", conf->nfaults);
0251 }
0252
0253
0254 static int faulty_reshape(struct mddev *mddev)
0255 {
0256 int mode = mddev->new_layout & ModeMask;
0257 int count = mddev->new_layout >> ModeShift;
0258 struct faulty_conf *conf = mddev->private;
0259
0260 if (mddev->new_layout < 0)
0261 return 0;
0262
0263
0264 if (mode == ClearFaults)
0265 conf->nfaults = 0;
0266 else if (mode == ClearErrors) {
0267 int i;
0268 for (i=0 ; i < Modes ; i++) {
0269 conf->period[i] = 0;
0270 atomic_set(&conf->counters[i], 0);
0271 }
0272 } else if (mode < Modes) {
0273 conf->period[mode] = count;
0274 if (!count) count++;
0275 atomic_set(&conf->counters[mode], count);
0276 } else
0277 return -EINVAL;
0278 mddev->new_layout = -1;
0279 mddev->layout = -1;
0280 return 0;
0281 }
0282
0283 static sector_t faulty_size(struct mddev *mddev, sector_t sectors, int raid_disks)
0284 {
0285 WARN_ONCE(raid_disks,
0286 "%s does not support generic reshape\n", __func__);
0287
0288 if (sectors == 0)
0289 return mddev->dev_sectors;
0290
0291 return sectors;
0292 }
0293
0294 static int faulty_run(struct mddev *mddev)
0295 {
0296 struct md_rdev *rdev;
0297 int i;
0298 struct faulty_conf *conf;
0299
0300 if (md_check_no_bitmap(mddev))
0301 return -EINVAL;
0302
0303 conf = kmalloc(sizeof(*conf), GFP_KERNEL);
0304 if (!conf)
0305 return -ENOMEM;
0306
0307 for (i=0; i<Modes; i++) {
0308 atomic_set(&conf->counters[i], 0);
0309 conf->period[i] = 0;
0310 }
0311 conf->nfaults = 0;
0312
0313 rdev_for_each(rdev, mddev) {
0314 conf->rdev = rdev;
0315 disk_stack_limits(mddev->gendisk, rdev->bdev,
0316 rdev->data_offset << 9);
0317 }
0318
0319 md_set_array_sectors(mddev, faulty_size(mddev, 0, 0));
0320 mddev->private = conf;
0321
0322 faulty_reshape(mddev);
0323
0324 return 0;
0325 }
0326
0327 static void faulty_free(struct mddev *mddev, void *priv)
0328 {
0329 struct faulty_conf *conf = priv;
0330
0331 kfree(conf);
0332 }
0333
0334 static struct md_personality faulty_personality =
0335 {
0336 .name = "faulty",
0337 .level = LEVEL_FAULTY,
0338 .owner = THIS_MODULE,
0339 .make_request = faulty_make_request,
0340 .run = faulty_run,
0341 .free = faulty_free,
0342 .status = faulty_status,
0343 .check_reshape = faulty_reshape,
0344 .size = faulty_size,
0345 };
0346
0347 static int __init raid_init(void)
0348 {
0349 return register_md_personality(&faulty_personality);
0350 }
0351
0352 static void raid_exit(void)
0353 {
0354 unregister_md_personality(&faulty_personality);
0355 }
0356
0357 module_init(raid_init);
0358 module_exit(raid_exit);
0359 MODULE_LICENSE("GPL");
0360 MODULE_DESCRIPTION("Fault injection personality for MD (deprecated)");
0361 MODULE_ALIAS("md-personality-10");
0362 MODULE_ALIAS("md-faulty");
0363 MODULE_ALIAS("md-level--5");