10 #include <linux/module.h>
14 #include <linux/slab.h>
16 #define DM_MSG_PREFIX "flakey"
18 #define all_corrupt_bio_flags_match(bio, fc) \
19 (((bio)->bi_rw & (fc)->corrupt_bio_flags) == (fc)->corrupt_bio_flags)
49 static struct dm_arg _args[] = {
50 {0, 6,
"Invalid number of feature args"},
51 {1,
UINT_MAX,
"Invalid corrupt bio byte"},
52 {0, 255,
"Invalid corrupt value to write into bio byte (0-255)"},
53 {0,
UINT_MAX,
"Invalid corrupt bio flags mask"},
73 ti->
error =
"Feature drop_writes duplicated";
83 if (!
strcasecmp(arg_name,
"corrupt_bio_byte")) {
85 ti->
error =
"Feature corrupt_bio_byte requires parameters";
103 ti->
error =
"Invalid corrupt bio direction (r or w)";
127 ti->
error =
"Unrecognised flakey feature requested";
132 ti->
error =
"drop_writes is incompatible with corrupt_bio_byte with the WRITE flag set";
151 static int flakey_ctr(
struct dm_target *ti,
unsigned int argc,
char **argv)
153 static struct dm_arg _args[] = {
154 {0,
UINT_MAX,
"Invalid up interval"},
155 {0,
UINT_MAX,
"Invalid down interval"},
160 unsigned long long tmpll;
169 ti->
error =
"Invalid argument count";
175 ti->
error =
"Cannot allocate linear context";
183 ti->
error =
"Invalid device sector";
197 ti->
error =
"Total (up + down) interval is zero";
202 ti->
error =
"Interval overflow";
206 r = parse_features(&as, fc, ti);
211 ti->
error =
"Device lookup failed";
225 static void flakey_dtr(
struct dm_target *ti)
240 static void flakey_map_bio(
struct dm_target *ti,
struct bio *bio)
244 bio->bi_bdev = fc->
dev->bdev;
245 if (bio_sectors(bio))
246 bio->bi_sector = flakey_map_sector(ti, bio->bi_sector);
249 static void corrupt_bio_data(
struct bio *bio,
struct flakey_c *fc)
251 unsigned bio_bytes = bio_cur_bytes(bio);
252 char *
data = bio_data(bio);
260 DMDEBUG(
"Corrupting data bio=%p by writing %u to byte %u "
261 "(rw=%c bi_rw=%lu bi_sector=%llu cur_bytes=%u)\n",
263 (bio_data_dir(bio) ==
WRITE) ?
'w' :
'r',
264 bio->bi_rw, (
unsigned long long)bio->bi_sector, bio_bytes);
268 static int flakey_map(
struct dm_target *ti,
struct bio *bio,
285 if (bio_data_dir(bio) ==
READ)
301 corrupt_bio_data(bio, fc);
312 flakey_map_bio(ti, bio);
317 static int flakey_end_io(
struct dm_target *ti,
struct bio *bio,
321 unsigned bio_submitted_while_down = map_context->
ll;
330 corrupt_bio_data(bio, fc);
336 unsigned status_flags,
char *
result,
unsigned maxlen)
340 unsigned drop_writes;
359 DMEMIT(
"corrupt_bio_byte %u %c %u %u ",
369 static int flakey_ioctl(
struct dm_target *ti,
unsigned int cmd,
unsigned long arg)
385 static int flakey_merge(
struct dm_target *ti,
struct bvec_merge_data *bvm,
386 struct bio_vec *biovec,
int max_size)
391 if (!q->merge_bvec_fn)
394 bvm->bi_bdev = fc->
dev->bdev;
395 bvm->bi_sector = flakey_map_sector(ti, bvm->bi_sector);
397 return min(max_size, q->merge_bvec_fn(q, bvm, biovec));
409 .version = {1, 2, 0},
414 .end_io = flakey_end_io,
415 .status = flakey_status,
416 .ioctl = flakey_ioctl,
417 .merge = flakey_merge,
418 .iterate_devices = flakey_iterate_devices,
421 static int __init dm_flakey_init(
void)
426 DMERR(
"register failed %d", r);
431 static void __exit dm_flakey_exit(
void)