Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * Copyright (C) 2003 Sistina Software (UK) Limited.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (C) 2004, 2010-2011 Red Hat, Inc. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * This file is released under the GPL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/device-mapper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/bio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #define DM_MSG_PREFIX "flakey"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #define all_corrupt_bio_flags_match(bio, fc)	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	(((bio)->bi_opf & (fc)->corrupt_bio_flags) == (fc)->corrupt_bio_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * Flakey: Used for testing only, simulates intermittent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * catastrophic device failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) struct flakey_c {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	struct dm_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	unsigned long start_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	sector_t start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	unsigned up_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	unsigned down_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	unsigned corrupt_bio_byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	unsigned corrupt_bio_rw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	unsigned corrupt_bio_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	unsigned corrupt_bio_flags;
^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) enum feature_flag_bits {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	DROP_WRITES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	ERROR_WRITES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) struct per_bio_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	bool bio_submitted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 			  struct dm_target *ti)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	unsigned argc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	const char *arg_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	static const struct dm_arg _args[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		{0, 6, "Invalid number of feature args"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		{1, UINT_MAX, "Invalid corrupt bio byte"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		{0, 255, "Invalid corrupt value to write into bio byte (0-255)"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		{0, UINT_MAX, "Invalid corrupt bio flags mask"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	/* No feature arguments supplied. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	if (!as->argc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	r = dm_read_arg_group(_args, as, &argc, &ti->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	while (argc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		arg_name = dm_shift_arg(as);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		argc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		if (!arg_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 			ti->error = "Insufficient feature arguments";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		 * drop_writes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		if (!strcasecmp(arg_name, "drop_writes")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 			if (test_and_set_bit(DROP_WRITES, &fc->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 				ti->error = "Feature drop_writes duplicated";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 			} else if (test_bit(ERROR_WRITES, &fc->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 				ti->error = "Feature drop_writes conflicts with feature error_writes";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		 * error_writes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		if (!strcasecmp(arg_name, "error_writes")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 			if (test_and_set_bit(ERROR_WRITES, &fc->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 				ti->error = "Feature error_writes duplicated";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 			} else if (test_bit(DROP_WRITES, &fc->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 				ti->error = "Feature error_writes conflicts with feature drop_writes";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		 * corrupt_bio_byte <Nth_byte> <direction> <value> <bio_flags>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		if (!strcasecmp(arg_name, "corrupt_bio_byte")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 			if (!argc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 				ti->error = "Feature corrupt_bio_byte requires parameters";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 			r = dm_read_arg(_args + 1, as, &fc->corrupt_bio_byte, &ti->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 			if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 				return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 			argc--;
^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) 			 * Direction r or w?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 			arg_name = dm_shift_arg(as);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 			if (!strcasecmp(arg_name, "w"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 				fc->corrupt_bio_rw = WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 			else if (!strcasecmp(arg_name, "r"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 				fc->corrupt_bio_rw = READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 				ti->error = "Invalid corrupt bio direction (r or w)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 			argc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 			 * Value of byte (0-255) to write in place of correct one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 			r = dm_read_arg(_args + 2, as, &fc->corrupt_bio_value, &ti->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 			if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 				return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 			argc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 			 * Only corrupt bios with these flags set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 			r = dm_read_arg(_args + 3, as, &fc->corrupt_bio_flags, &ti->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 			if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 				return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 			argc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		ti->error = "Unrecognised flakey feature requested";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	if (test_bit(DROP_WRITES, &fc->flags) && (fc->corrupt_bio_rw == WRITE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		ti->error = "drop_writes is incompatible with corrupt_bio_byte with the WRITE flag set";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	} else if (test_bit(ERROR_WRITES, &fc->flags) && (fc->corrupt_bio_rw == WRITE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		ti->error = "error_writes is incompatible with corrupt_bio_byte with the WRITE flag set";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)  * Construct a flakey mapping:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)  * <dev_path> <offset> <up interval> <down interval> [<#feature args> [<arg>]*]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)  *   Feature args:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)  *     [drop_writes]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)  *     [corrupt_bio_byte <Nth_byte> <direction> <value> <bio_flags>]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)  *   Nth_byte starts from 1 for the first byte.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)  *   Direction is r for READ or w for WRITE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)  *   bio_flags is ignored if 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	static const struct dm_arg _args[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		{0, UINT_MAX, "Invalid up interval"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		{0, UINT_MAX, "Invalid down interval"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	struct flakey_c *fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	unsigned long long tmpll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	struct dm_arg_set as;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	const char *devname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	char dummy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	as.argc = argc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	as.argv = argv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	if (argc < 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		ti->error = "Invalid argument count";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	fc = kzalloc(sizeof(*fc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	if (!fc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		ti->error = "Cannot allocate context";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	fc->start_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	devname = dm_shift_arg(&as);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	r = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	if (sscanf(dm_shift_arg(&as), "%llu%c", &tmpll, &dummy) != 1 || tmpll != (sector_t)tmpll) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		ti->error = "Invalid device sector";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	fc->start = tmpll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	r = dm_read_arg(_args, &as, &fc->up_interval, &ti->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	r = dm_read_arg(_args, &as, &fc->down_interval, &ti->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	if (!(fc->up_interval + fc->down_interval)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		ti->error = "Total (up + down) interval is zero";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		r = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	if (fc->up_interval + fc->down_interval < fc->up_interval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		ti->error = "Interval overflow";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		r = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	r = parse_features(&as, fc, ti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	r = dm_get_device(ti, devname, dm_table_get_mode(ti->table), &fc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		ti->error = "Device lookup failed";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	ti->num_flush_bios = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	ti->num_discard_bios = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	ti->per_io_data_size = sizeof(struct per_bio_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	ti->private = fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) bad:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	kfree(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static void flakey_dtr(struct dm_target *ti)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	struct flakey_c *fc = ti->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	dm_put_device(ti, fc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	kfree(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static sector_t flakey_map_sector(struct dm_target *ti, sector_t bi_sector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	struct flakey_c *fc = ti->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	return fc->start + dm_target_offset(ti, bi_sector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static void flakey_map_bio(struct dm_target *ti, struct bio *bio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	struct flakey_c *fc = ti->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	bio_set_dev(bio, fc->dev->bdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	if (bio_sectors(bio) || op_is_zone_mgmt(bio_op(bio)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		bio->bi_iter.bi_sector =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 			flakey_map_sector(ti, bio->bi_iter.bi_sector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static void corrupt_bio_data(struct bio *bio, struct flakey_c *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	unsigned int corrupt_bio_byte = fc->corrupt_bio_byte - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	struct bvec_iter iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	struct bio_vec bvec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	if (!bio_has_data(bio))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	 * Overwrite the Nth byte of the bio's data, on whichever page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	 * it falls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	bio_for_each_segment(bvec, bio, iter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		if (bio_iter_len(bio, iter) > corrupt_bio_byte) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 			char *segment = (page_address(bio_iter_page(bio, iter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 					 + bio_iter_offset(bio, iter));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 			segment[corrupt_bio_byte] = fc->corrupt_bio_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 			DMDEBUG("Corrupting data bio=%p by writing %u to byte %u "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 				"(rw=%c bi_opf=%u bi_sector=%llu size=%u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 				bio, fc->corrupt_bio_value, fc->corrupt_bio_byte,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 				(bio_data_dir(bio) == WRITE) ? 'w' : 'r', bio->bi_opf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 				(unsigned long long)bio->bi_iter.bi_sector, bio->bi_iter.bi_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		corrupt_bio_byte -= bio_iter_len(bio, iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static int flakey_map(struct dm_target *ti, struct bio *bio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	struct flakey_c *fc = ti->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	unsigned elapsed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	pb->bio_submitted = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	if (op_is_zone_mgmt(bio_op(bio)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		goto map_bio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	/* Are we alive ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	elapsed = (jiffies - fc->start_time) / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	if (elapsed % (fc->up_interval + fc->down_interval) >= fc->up_interval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		 * Flag this bio as submitted while down.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		pb->bio_submitted = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		 * Error reads if neither corrupt_bio_byte or drop_writes or error_writes are set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		 * Otherwise, flakey_end_io() will decide if the reads should be modified.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		if (bio_data_dir(bio) == READ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 			if (!fc->corrupt_bio_byte && !test_bit(DROP_WRITES, &fc->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 			    !test_bit(ERROR_WRITES, &fc->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 				return DM_MAPIO_KILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 			goto map_bio;
^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) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		 * Drop or error writes?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		if (test_bit(DROP_WRITES, &fc->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 			bio_endio(bio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 			return DM_MAPIO_SUBMITTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		else if (test_bit(ERROR_WRITES, &fc->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 			bio_io_error(bio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 			return DM_MAPIO_SUBMITTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		 * Corrupt matching writes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw == WRITE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 			if (all_corrupt_bio_flags_match(bio, fc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 				corrupt_bio_data(bio, fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 			goto map_bio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		 * By default, error all I/O.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		return DM_MAPIO_KILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) map_bio:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	flakey_map_bio(ti, bio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	return DM_MAPIO_REMAPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) static int flakey_end_io(struct dm_target *ti, struct bio *bio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 			 blk_status_t *error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	struct flakey_c *fc = ti->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	if (op_is_zone_mgmt(bio_op(bio)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 		return DM_ENDIO_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	if (!*error && pb->bio_submitted && (bio_data_dir(bio) == READ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 		if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw == READ) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		    all_corrupt_bio_flags_match(bio, fc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 			 * Corrupt successful matching READs while in down state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 			corrupt_bio_data(bio, fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		} else if (!test_bit(DROP_WRITES, &fc->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 			   !test_bit(ERROR_WRITES, &fc->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 			 * Error read during the down_interval if drop_writes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 			 * and error_writes were not configured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 			*error = BLK_STS_IOERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	return DM_ENDIO_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) static void flakey_status(struct dm_target *ti, status_type_t type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 			  unsigned status_flags, char *result, unsigned maxlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	unsigned sz = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	struct flakey_c *fc = ti->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	unsigned drop_writes, error_writes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	case STATUSTYPE_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		result[0] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	case STATUSTYPE_TABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		DMEMIT("%s %llu %u %u ", fc->dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		       (unsigned long long)fc->start, fc->up_interval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		       fc->down_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		drop_writes = test_bit(DROP_WRITES, &fc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		error_writes = test_bit(ERROR_WRITES, &fc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		DMEMIT("%u ", drop_writes + error_writes + (fc->corrupt_bio_byte > 0) * 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 		if (drop_writes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 			DMEMIT("drop_writes ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		else if (error_writes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 			DMEMIT("error_writes ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		if (fc->corrupt_bio_byte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 			DMEMIT("corrupt_bio_byte %u %c %u %u ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 			       fc->corrupt_bio_byte,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 			       (fc->corrupt_bio_rw == WRITE) ? 'w' : 'r',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 			       fc->corrupt_bio_value, fc->corrupt_bio_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) static int flakey_prepare_ioctl(struct dm_target *ti, struct block_device **bdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	struct flakey_c *fc = ti->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	*bdev = fc->dev->bdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	 * Only pass ioctls through if the device sizes match exactly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	if (fc->start ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	    ti->len != i_size_read((*bdev)->bd_inode) >> SECTOR_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) #ifdef CONFIG_BLK_DEV_ZONED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static int flakey_report_zones(struct dm_target *ti,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		struct dm_report_zones_args *args, unsigned int nr_zones)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	struct flakey_c *fc = ti->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	sector_t sector = flakey_map_sector(ti, args->next_sector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	args->start = fc->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	return blkdev_report_zones(fc->dev->bdev, sector, nr_zones,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 				   dm_report_zones_cb, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) static int flakey_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	struct flakey_c *fc = ti->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	return fn(ti, fc->dev, fc->start, ti->len, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) static struct target_type flakey_target = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	.name   = "flakey",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	.version = {1, 5, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) #ifdef CONFIG_BLK_DEV_ZONED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	.features = DM_TARGET_ZONED_HM | DM_TARGET_PASSES_CRYPTO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	.report_zones = flakey_report_zones,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	.features = DM_TARGET_PASSES_CRYPTO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	.module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	.ctr    = flakey_ctr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	.dtr    = flakey_dtr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	.map    = flakey_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	.end_io = flakey_end_io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	.status = flakey_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	.prepare_ioctl = flakey_prepare_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	.iterate_devices = flakey_iterate_devices,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) static int __init dm_flakey_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	int r = dm_register_target(&flakey_target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	if (r < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 		DMERR("register failed %d", r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) static void __exit dm_flakey_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	dm_unregister_target(&flakey_target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) /* Module hooks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) module_init(dm_flakey_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) module_exit(dm_flakey_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) MODULE_DESCRIPTION(DM_NAME " flakey target");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) MODULE_LICENSE("GPL");