18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * faulty.c : Multiple Devices driver for Linux
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2004 Neil Brown
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * fautly-device-simulator personality for md
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci/*
128c2ecf20Sopenharmony_ci * The "faulty" personality causes some requests to fail.
138c2ecf20Sopenharmony_ci *
148c2ecf20Sopenharmony_ci * Possible failure modes are:
158c2ecf20Sopenharmony_ci *   reads fail "randomly" but succeed on retry
168c2ecf20Sopenharmony_ci *   writes fail "randomly" but succeed on retry
178c2ecf20Sopenharmony_ci *   reads for some address fail and then persist until a write
188c2ecf20Sopenharmony_ci *   reads for some address fail and then persist irrespective of write
198c2ecf20Sopenharmony_ci *   writes for some address fail and persist
208c2ecf20Sopenharmony_ci *   all writes fail
218c2ecf20Sopenharmony_ci *
228c2ecf20Sopenharmony_ci * Different modes can be active at a time, but only
238c2ecf20Sopenharmony_ci * one can be set at array creation.  Others can be added later.
248c2ecf20Sopenharmony_ci * A mode can be one-shot or recurrent with the recurrence being
258c2ecf20Sopenharmony_ci * once in every N requests.
268c2ecf20Sopenharmony_ci * The bottom 5 bits of the "layout" indicate the mode.  The
278c2ecf20Sopenharmony_ci * remainder indicate a period, or 0 for one-shot.
288c2ecf20Sopenharmony_ci *
298c2ecf20Sopenharmony_ci * There is an implementation limit on the number of concurrently
308c2ecf20Sopenharmony_ci * persisting-faulty blocks. When a new fault is requested that would
318c2ecf20Sopenharmony_ci * exceed the limit, it is ignored.
328c2ecf20Sopenharmony_ci * All current faults can be clear using a layout of "0".
338c2ecf20Sopenharmony_ci *
348c2ecf20Sopenharmony_ci * Requests are always sent to the device.  If they are to fail,
358c2ecf20Sopenharmony_ci * we clone the bio and insert a new b_end_io into the chain.
368c2ecf20Sopenharmony_ci */
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci#define	WriteTransient	0
398c2ecf20Sopenharmony_ci#define	ReadTransient	1
408c2ecf20Sopenharmony_ci#define	WritePersistent	2
418c2ecf20Sopenharmony_ci#define	ReadPersistent	3
428c2ecf20Sopenharmony_ci#define	WriteAll	4 /* doesn't go to device */
438c2ecf20Sopenharmony_ci#define	ReadFixable	5
448c2ecf20Sopenharmony_ci#define	Modes	6
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci#define	ClearErrors	31
478c2ecf20Sopenharmony_ci#define	ClearFaults	30
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci#define AllPersist	100 /* internal use only */
508c2ecf20Sopenharmony_ci#define	NoPersist	101
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci#define	ModeMask	0x1f
538c2ecf20Sopenharmony_ci#define	ModeShift	5
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci#define MaxFault	50
568c2ecf20Sopenharmony_ci#include <linux/blkdev.h>
578c2ecf20Sopenharmony_ci#include <linux/module.h>
588c2ecf20Sopenharmony_ci#include <linux/raid/md_u.h>
598c2ecf20Sopenharmony_ci#include <linux/slab.h>
608c2ecf20Sopenharmony_ci#include "md.h"
618c2ecf20Sopenharmony_ci#include <linux/seq_file.h>
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_cistatic void faulty_fail(struct bio *bio)
658c2ecf20Sopenharmony_ci{
668c2ecf20Sopenharmony_ci	struct bio *b = bio->bi_private;
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	b->bi_iter.bi_size = bio->bi_iter.bi_size;
698c2ecf20Sopenharmony_ci	b->bi_iter.bi_sector = bio->bi_iter.bi_sector;
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	bio_put(bio);
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci	bio_io_error(b);
748c2ecf20Sopenharmony_ci}
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_cistruct faulty_conf {
778c2ecf20Sopenharmony_ci	int period[Modes];
788c2ecf20Sopenharmony_ci	atomic_t counters[Modes];
798c2ecf20Sopenharmony_ci	sector_t faults[MaxFault];
808c2ecf20Sopenharmony_ci	int	modes[MaxFault];
818c2ecf20Sopenharmony_ci	int nfaults;
828c2ecf20Sopenharmony_ci	struct md_rdev *rdev;
838c2ecf20Sopenharmony_ci};
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_cistatic int check_mode(struct faulty_conf *conf, int mode)
868c2ecf20Sopenharmony_ci{
878c2ecf20Sopenharmony_ci	if (conf->period[mode] == 0 &&
888c2ecf20Sopenharmony_ci	    atomic_read(&conf->counters[mode]) <= 0)
898c2ecf20Sopenharmony_ci		return 0; /* no failure, no decrement */
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci	if (atomic_dec_and_test(&conf->counters[mode])) {
938c2ecf20Sopenharmony_ci		if (conf->period[mode])
948c2ecf20Sopenharmony_ci			atomic_set(&conf->counters[mode], conf->period[mode]);
958c2ecf20Sopenharmony_ci		return 1;
968c2ecf20Sopenharmony_ci	}
978c2ecf20Sopenharmony_ci	return 0;
988c2ecf20Sopenharmony_ci}
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_cistatic int check_sector(struct faulty_conf *conf, sector_t start, sector_t end, int dir)
1018c2ecf20Sopenharmony_ci{
1028c2ecf20Sopenharmony_ci	/* If we find a ReadFixable sector, we fix it ... */
1038c2ecf20Sopenharmony_ci	int i;
1048c2ecf20Sopenharmony_ci	for (i=0; i<conf->nfaults; i++)
1058c2ecf20Sopenharmony_ci		if (conf->faults[i] >= start &&
1068c2ecf20Sopenharmony_ci		    conf->faults[i] < end) {
1078c2ecf20Sopenharmony_ci			/* found it ... */
1088c2ecf20Sopenharmony_ci			switch (conf->modes[i] * 2 + dir) {
1098c2ecf20Sopenharmony_ci			case WritePersistent*2+WRITE: return 1;
1108c2ecf20Sopenharmony_ci			case ReadPersistent*2+READ: return 1;
1118c2ecf20Sopenharmony_ci			case ReadFixable*2+READ: return 1;
1128c2ecf20Sopenharmony_ci			case ReadFixable*2+WRITE:
1138c2ecf20Sopenharmony_ci				conf->modes[i] = NoPersist;
1148c2ecf20Sopenharmony_ci				return 0;
1158c2ecf20Sopenharmony_ci			case AllPersist*2+READ:
1168c2ecf20Sopenharmony_ci			case AllPersist*2+WRITE: return 1;
1178c2ecf20Sopenharmony_ci			default:
1188c2ecf20Sopenharmony_ci				return 0;
1198c2ecf20Sopenharmony_ci			}
1208c2ecf20Sopenharmony_ci		}
1218c2ecf20Sopenharmony_ci	return 0;
1228c2ecf20Sopenharmony_ci}
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_cistatic void add_sector(struct faulty_conf *conf, sector_t start, int mode)
1258c2ecf20Sopenharmony_ci{
1268c2ecf20Sopenharmony_ci	int i;
1278c2ecf20Sopenharmony_ci	int n = conf->nfaults;
1288c2ecf20Sopenharmony_ci	for (i=0; i<conf->nfaults; i++)
1298c2ecf20Sopenharmony_ci		if (conf->faults[i] == start) {
1308c2ecf20Sopenharmony_ci			switch(mode) {
1318c2ecf20Sopenharmony_ci			case NoPersist: conf->modes[i] = mode; return;
1328c2ecf20Sopenharmony_ci			case WritePersistent:
1338c2ecf20Sopenharmony_ci				if (conf->modes[i] == ReadPersistent ||
1348c2ecf20Sopenharmony_ci				    conf->modes[i] == ReadFixable)
1358c2ecf20Sopenharmony_ci					conf->modes[i] = AllPersist;
1368c2ecf20Sopenharmony_ci				else
1378c2ecf20Sopenharmony_ci					conf->modes[i] = WritePersistent;
1388c2ecf20Sopenharmony_ci				return;
1398c2ecf20Sopenharmony_ci			case ReadPersistent:
1408c2ecf20Sopenharmony_ci				if (conf->modes[i] == WritePersistent)
1418c2ecf20Sopenharmony_ci					conf->modes[i] = AllPersist;
1428c2ecf20Sopenharmony_ci				else
1438c2ecf20Sopenharmony_ci					conf->modes[i] = ReadPersistent;
1448c2ecf20Sopenharmony_ci				return;
1458c2ecf20Sopenharmony_ci			case ReadFixable:
1468c2ecf20Sopenharmony_ci				if (conf->modes[i] == WritePersistent ||
1478c2ecf20Sopenharmony_ci				    conf->modes[i] == ReadPersistent)
1488c2ecf20Sopenharmony_ci					conf->modes[i] = AllPersist;
1498c2ecf20Sopenharmony_ci				else
1508c2ecf20Sopenharmony_ci					conf->modes[i] = ReadFixable;
1518c2ecf20Sopenharmony_ci				return;
1528c2ecf20Sopenharmony_ci			}
1538c2ecf20Sopenharmony_ci		} else if (conf->modes[i] == NoPersist)
1548c2ecf20Sopenharmony_ci			n = i;
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci	if (n >= MaxFault)
1578c2ecf20Sopenharmony_ci		return;
1588c2ecf20Sopenharmony_ci	conf->faults[n] = start;
1598c2ecf20Sopenharmony_ci	conf->modes[n] = mode;
1608c2ecf20Sopenharmony_ci	if (conf->nfaults == n)
1618c2ecf20Sopenharmony_ci		conf->nfaults = n+1;
1628c2ecf20Sopenharmony_ci}
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_cistatic bool faulty_make_request(struct mddev *mddev, struct bio *bio)
1658c2ecf20Sopenharmony_ci{
1668c2ecf20Sopenharmony_ci	struct faulty_conf *conf = mddev->private;
1678c2ecf20Sopenharmony_ci	int failit = 0;
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci	if (bio_data_dir(bio) == WRITE) {
1708c2ecf20Sopenharmony_ci		/* write request */
1718c2ecf20Sopenharmony_ci		if (atomic_read(&conf->counters[WriteAll])) {
1728c2ecf20Sopenharmony_ci			/* special case - don't decrement, don't submit_bio_noacct,
1738c2ecf20Sopenharmony_ci			 * just fail immediately
1748c2ecf20Sopenharmony_ci			 */
1758c2ecf20Sopenharmony_ci			bio_io_error(bio);
1768c2ecf20Sopenharmony_ci			return true;
1778c2ecf20Sopenharmony_ci		}
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_ci		if (check_sector(conf, bio->bi_iter.bi_sector,
1808c2ecf20Sopenharmony_ci				 bio_end_sector(bio), WRITE))
1818c2ecf20Sopenharmony_ci			failit = 1;
1828c2ecf20Sopenharmony_ci		if (check_mode(conf, WritePersistent)) {
1838c2ecf20Sopenharmony_ci			add_sector(conf, bio->bi_iter.bi_sector,
1848c2ecf20Sopenharmony_ci				   WritePersistent);
1858c2ecf20Sopenharmony_ci			failit = 1;
1868c2ecf20Sopenharmony_ci		}
1878c2ecf20Sopenharmony_ci		if (check_mode(conf, WriteTransient))
1888c2ecf20Sopenharmony_ci			failit = 1;
1898c2ecf20Sopenharmony_ci	} else {
1908c2ecf20Sopenharmony_ci		/* read request */
1918c2ecf20Sopenharmony_ci		if (check_sector(conf, bio->bi_iter.bi_sector,
1928c2ecf20Sopenharmony_ci				 bio_end_sector(bio), READ))
1938c2ecf20Sopenharmony_ci			failit = 1;
1948c2ecf20Sopenharmony_ci		if (check_mode(conf, ReadTransient))
1958c2ecf20Sopenharmony_ci			failit = 1;
1968c2ecf20Sopenharmony_ci		if (check_mode(conf, ReadPersistent)) {
1978c2ecf20Sopenharmony_ci			add_sector(conf, bio->bi_iter.bi_sector,
1988c2ecf20Sopenharmony_ci				   ReadPersistent);
1998c2ecf20Sopenharmony_ci			failit = 1;
2008c2ecf20Sopenharmony_ci		}
2018c2ecf20Sopenharmony_ci		if (check_mode(conf, ReadFixable)) {
2028c2ecf20Sopenharmony_ci			add_sector(conf, bio->bi_iter.bi_sector,
2038c2ecf20Sopenharmony_ci				   ReadFixable);
2048c2ecf20Sopenharmony_ci			failit = 1;
2058c2ecf20Sopenharmony_ci		}
2068c2ecf20Sopenharmony_ci	}
2078c2ecf20Sopenharmony_ci	if (failit) {
2088c2ecf20Sopenharmony_ci		struct bio *b = bio_clone_fast(bio, GFP_NOIO, &mddev->bio_set);
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_ci		bio_set_dev(b, conf->rdev->bdev);
2118c2ecf20Sopenharmony_ci		b->bi_private = bio;
2128c2ecf20Sopenharmony_ci		b->bi_end_io = faulty_fail;
2138c2ecf20Sopenharmony_ci		bio = b;
2148c2ecf20Sopenharmony_ci	} else
2158c2ecf20Sopenharmony_ci		bio_set_dev(bio, conf->rdev->bdev);
2168c2ecf20Sopenharmony_ci
2178c2ecf20Sopenharmony_ci	submit_bio_noacct(bio);
2188c2ecf20Sopenharmony_ci	return true;
2198c2ecf20Sopenharmony_ci}
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_cistatic void faulty_status(struct seq_file *seq, struct mddev *mddev)
2228c2ecf20Sopenharmony_ci{
2238c2ecf20Sopenharmony_ci	struct faulty_conf *conf = mddev->private;
2248c2ecf20Sopenharmony_ci	int n;
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_ci	if ((n=atomic_read(&conf->counters[WriteTransient])) != 0)
2278c2ecf20Sopenharmony_ci		seq_printf(seq, " WriteTransient=%d(%d)",
2288c2ecf20Sopenharmony_ci			   n, conf->period[WriteTransient]);
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_ci	if ((n=atomic_read(&conf->counters[ReadTransient])) != 0)
2318c2ecf20Sopenharmony_ci		seq_printf(seq, " ReadTransient=%d(%d)",
2328c2ecf20Sopenharmony_ci			   n, conf->period[ReadTransient]);
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ci	if ((n=atomic_read(&conf->counters[WritePersistent])) != 0)
2358c2ecf20Sopenharmony_ci		seq_printf(seq, " WritePersistent=%d(%d)",
2368c2ecf20Sopenharmony_ci			   n, conf->period[WritePersistent]);
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci	if ((n=atomic_read(&conf->counters[ReadPersistent])) != 0)
2398c2ecf20Sopenharmony_ci		seq_printf(seq, " ReadPersistent=%d(%d)",
2408c2ecf20Sopenharmony_ci			   n, conf->period[ReadPersistent]);
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_ci
2438c2ecf20Sopenharmony_ci	if ((n=atomic_read(&conf->counters[ReadFixable])) != 0)
2448c2ecf20Sopenharmony_ci		seq_printf(seq, " ReadFixable=%d(%d)",
2458c2ecf20Sopenharmony_ci			   n, conf->period[ReadFixable]);
2468c2ecf20Sopenharmony_ci
2478c2ecf20Sopenharmony_ci	if ((n=atomic_read(&conf->counters[WriteAll])) != 0)
2488c2ecf20Sopenharmony_ci		seq_printf(seq, " WriteAll");
2498c2ecf20Sopenharmony_ci
2508c2ecf20Sopenharmony_ci	seq_printf(seq, " nfaults=%d", conf->nfaults);
2518c2ecf20Sopenharmony_ci}
2528c2ecf20Sopenharmony_ci
2538c2ecf20Sopenharmony_ci
2548c2ecf20Sopenharmony_cistatic int faulty_reshape(struct mddev *mddev)
2558c2ecf20Sopenharmony_ci{
2568c2ecf20Sopenharmony_ci	int mode = mddev->new_layout & ModeMask;
2578c2ecf20Sopenharmony_ci	int count = mddev->new_layout >> ModeShift;
2588c2ecf20Sopenharmony_ci	struct faulty_conf *conf = mddev->private;
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_ci	if (mddev->new_layout < 0)
2618c2ecf20Sopenharmony_ci		return 0;
2628c2ecf20Sopenharmony_ci
2638c2ecf20Sopenharmony_ci	/* new layout */
2648c2ecf20Sopenharmony_ci	if (mode == ClearFaults)
2658c2ecf20Sopenharmony_ci		conf->nfaults = 0;
2668c2ecf20Sopenharmony_ci	else if (mode == ClearErrors) {
2678c2ecf20Sopenharmony_ci		int i;
2688c2ecf20Sopenharmony_ci		for (i=0 ; i < Modes ; i++) {
2698c2ecf20Sopenharmony_ci			conf->period[i] = 0;
2708c2ecf20Sopenharmony_ci			atomic_set(&conf->counters[i], 0);
2718c2ecf20Sopenharmony_ci		}
2728c2ecf20Sopenharmony_ci	} else if (mode < Modes) {
2738c2ecf20Sopenharmony_ci		conf->period[mode] = count;
2748c2ecf20Sopenharmony_ci		if (!count) count++;
2758c2ecf20Sopenharmony_ci		atomic_set(&conf->counters[mode], count);
2768c2ecf20Sopenharmony_ci	} else
2778c2ecf20Sopenharmony_ci		return -EINVAL;
2788c2ecf20Sopenharmony_ci	mddev->new_layout = -1;
2798c2ecf20Sopenharmony_ci	mddev->layout = -1; /* makes sure further changes come through */
2808c2ecf20Sopenharmony_ci	return 0;
2818c2ecf20Sopenharmony_ci}
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_cistatic sector_t faulty_size(struct mddev *mddev, sector_t sectors, int raid_disks)
2848c2ecf20Sopenharmony_ci{
2858c2ecf20Sopenharmony_ci	WARN_ONCE(raid_disks,
2868c2ecf20Sopenharmony_ci		  "%s does not support generic reshape\n", __func__);
2878c2ecf20Sopenharmony_ci
2888c2ecf20Sopenharmony_ci	if (sectors == 0)
2898c2ecf20Sopenharmony_ci		return mddev->dev_sectors;
2908c2ecf20Sopenharmony_ci
2918c2ecf20Sopenharmony_ci	return sectors;
2928c2ecf20Sopenharmony_ci}
2938c2ecf20Sopenharmony_ci
2948c2ecf20Sopenharmony_cistatic int faulty_run(struct mddev *mddev)
2958c2ecf20Sopenharmony_ci{
2968c2ecf20Sopenharmony_ci	struct md_rdev *rdev;
2978c2ecf20Sopenharmony_ci	int i;
2988c2ecf20Sopenharmony_ci	struct faulty_conf *conf;
2998c2ecf20Sopenharmony_ci
3008c2ecf20Sopenharmony_ci	if (md_check_no_bitmap(mddev))
3018c2ecf20Sopenharmony_ci		return -EINVAL;
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_ci	conf = kmalloc(sizeof(*conf), GFP_KERNEL);
3048c2ecf20Sopenharmony_ci	if (!conf)
3058c2ecf20Sopenharmony_ci		return -ENOMEM;
3068c2ecf20Sopenharmony_ci
3078c2ecf20Sopenharmony_ci	for (i=0; i<Modes; i++) {
3088c2ecf20Sopenharmony_ci		atomic_set(&conf->counters[i], 0);
3098c2ecf20Sopenharmony_ci		conf->period[i] = 0;
3108c2ecf20Sopenharmony_ci	}
3118c2ecf20Sopenharmony_ci	conf->nfaults = 0;
3128c2ecf20Sopenharmony_ci
3138c2ecf20Sopenharmony_ci	rdev_for_each(rdev, mddev) {
3148c2ecf20Sopenharmony_ci		conf->rdev = rdev;
3158c2ecf20Sopenharmony_ci		disk_stack_limits(mddev->gendisk, rdev->bdev,
3168c2ecf20Sopenharmony_ci				  rdev->data_offset << 9);
3178c2ecf20Sopenharmony_ci	}
3188c2ecf20Sopenharmony_ci
3198c2ecf20Sopenharmony_ci	md_set_array_sectors(mddev, faulty_size(mddev, 0, 0));
3208c2ecf20Sopenharmony_ci	mddev->private = conf;
3218c2ecf20Sopenharmony_ci
3228c2ecf20Sopenharmony_ci	faulty_reshape(mddev);
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_ci	return 0;
3258c2ecf20Sopenharmony_ci}
3268c2ecf20Sopenharmony_ci
3278c2ecf20Sopenharmony_cistatic void faulty_free(struct mddev *mddev, void *priv)
3288c2ecf20Sopenharmony_ci{
3298c2ecf20Sopenharmony_ci	struct faulty_conf *conf = priv;
3308c2ecf20Sopenharmony_ci
3318c2ecf20Sopenharmony_ci	kfree(conf);
3328c2ecf20Sopenharmony_ci}
3338c2ecf20Sopenharmony_ci
3348c2ecf20Sopenharmony_cistatic struct md_personality faulty_personality =
3358c2ecf20Sopenharmony_ci{
3368c2ecf20Sopenharmony_ci	.name		= "faulty",
3378c2ecf20Sopenharmony_ci	.level		= LEVEL_FAULTY,
3388c2ecf20Sopenharmony_ci	.owner		= THIS_MODULE,
3398c2ecf20Sopenharmony_ci	.make_request	= faulty_make_request,
3408c2ecf20Sopenharmony_ci	.run		= faulty_run,
3418c2ecf20Sopenharmony_ci	.free		= faulty_free,
3428c2ecf20Sopenharmony_ci	.status		= faulty_status,
3438c2ecf20Sopenharmony_ci	.check_reshape	= faulty_reshape,
3448c2ecf20Sopenharmony_ci	.size		= faulty_size,
3458c2ecf20Sopenharmony_ci};
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_cistatic int __init raid_init(void)
3488c2ecf20Sopenharmony_ci{
3498c2ecf20Sopenharmony_ci	return register_md_personality(&faulty_personality);
3508c2ecf20Sopenharmony_ci}
3518c2ecf20Sopenharmony_ci
3528c2ecf20Sopenharmony_cistatic void raid_exit(void)
3538c2ecf20Sopenharmony_ci{
3548c2ecf20Sopenharmony_ci	unregister_md_personality(&faulty_personality);
3558c2ecf20Sopenharmony_ci}
3568c2ecf20Sopenharmony_ci
3578c2ecf20Sopenharmony_cimodule_init(raid_init);
3588c2ecf20Sopenharmony_cimodule_exit(raid_exit);
3598c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL");
3608c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Fault injection personality for MD");
3618c2ecf20Sopenharmony_ciMODULE_ALIAS("md-personality-10"); /* faulty */
3628c2ecf20Sopenharmony_ciMODULE_ALIAS("md-faulty");
3638c2ecf20Sopenharmony_ciMODULE_ALIAS("md-level--5");
364