^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");