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