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