diff options
Diffstat (limited to 'drivers/md/dm-flakey.c')
-rw-r--r-- | drivers/md/dm-flakey.c | 71 |
1 files changed, 34 insertions, 37 deletions
diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c index 5b7556d2a9d9..bd80bcafbe50 100644 --- a/drivers/md/dm-flakey.c +++ b/drivers/md/dm-flakey.c @@ -37,6 +37,7 @@ struct flakey_c { }; enum feature_flag_bits { + ERROR_READS, DROP_WRITES, ERROR_WRITES }; @@ -53,7 +54,7 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc, const char *arg_name; static const struct dm_arg _args[] = { - {0, 6, "Invalid number of feature args"}, + {0, 7, "Invalid number of feature args"}, {1, UINT_MAX, "Invalid corrupt bio byte"}, {0, 255, "Invalid corrupt value to write into bio byte (0-255)"}, {0, UINT_MAX, "Invalid corrupt bio flags mask"}, @@ -77,6 +78,17 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc, } /* + * error_reads + */ + if (!strcasecmp(arg_name, "error_reads")) { + if (test_and_set_bit(ERROR_READS, &fc->flags)) { + ti->error = "Feature error_reads duplicated"; + return -EINVAL; + } + continue; + } + + /* * drop_writes */ if (!strcasecmp(arg_name, "drop_writes")) { @@ -125,9 +137,9 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc, * Direction r or w? */ arg_name = dm_shift_arg(as); - if (!strcasecmp(arg_name, "w")) + if (arg_name && !strcasecmp(arg_name, "w")) fc->corrupt_bio_rw = WRITE; - else if (!strcasecmp(arg_name, "r")) + else if (arg_name && !strcasecmp(arg_name, "r")) fc->corrupt_bio_rw = READ; else { ti->error = "Invalid corrupt bio direction (r or w)"; @@ -171,6 +183,12 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc, return -EINVAL; } + if (!fc->corrupt_bio_byte && !test_bit(ERROR_READS, &fc->flags) && + !test_bit(DROP_WRITES, &fc->flags) && !test_bit(ERROR_WRITES, &fc->flags)) { + set_bit(ERROR_WRITES, &fc->flags); + set_bit(ERROR_READS, &fc->flags); + } + return 0; } @@ -346,8 +364,7 @@ static int flakey_map(struct dm_target *ti, struct bio *bio) * Otherwise, flakey_end_io() will decide if the reads should be modified. */ if (bio_data_dir(bio) == READ) { - if (!fc->corrupt_bio_byte && !test_bit(DROP_WRITES, &fc->flags) && - !test_bit(ERROR_WRITES, &fc->flags)) + if (test_bit(ERROR_READS, &fc->flags)) return DM_MAPIO_KILL; goto map_bio; } @@ -373,11 +390,6 @@ static int flakey_map(struct dm_target *ti, struct bio *bio) } goto map_bio; } - - /* - * By default, error all I/O. - */ - return DM_MAPIO_KILL; } map_bio: @@ -404,8 +416,8 @@ static int flakey_end_io(struct dm_target *ti, struct bio *bio, */ corrupt_bio_data(bio, fc); } - } else if (!test_bit(DROP_WRITES, &fc->flags) && - !test_bit(ERROR_WRITES, &fc->flags)) { + } + if (test_bit(ERROR_READS, &fc->flags)) { /* * Error read during the down_interval if drop_writes * and error_writes were not configured. @@ -422,7 +434,7 @@ static void flakey_status(struct dm_target *ti, status_type_t type, { unsigned int sz = 0; struct flakey_c *fc = ti->private; - unsigned int drop_writes, error_writes; + unsigned int error_reads, drop_writes, error_writes; switch (type) { case STATUSTYPE_INFO: @@ -430,21 +442,24 @@ static void flakey_status(struct dm_target *ti, status_type_t type, break; case STATUSTYPE_TABLE: - DMEMIT("%s %llu %u %u ", fc->dev->name, + DMEMIT("%s %llu %u %u", fc->dev->name, (unsigned long long)fc->start, fc->up_interval, fc->down_interval); + error_reads = test_bit(ERROR_READS, &fc->flags); drop_writes = test_bit(DROP_WRITES, &fc->flags); error_writes = test_bit(ERROR_WRITES, &fc->flags); - DMEMIT("%u ", drop_writes + error_writes + (fc->corrupt_bio_byte > 0) * 5); + DMEMIT(" %u", error_reads + drop_writes + error_writes + (fc->corrupt_bio_byte > 0) * 5); + if (error_reads) + DMEMIT(" error_reads"); if (drop_writes) - DMEMIT("drop_writes "); + DMEMIT(" drop_writes"); else if (error_writes) - DMEMIT("error_writes "); + DMEMIT(" error_writes"); if (fc->corrupt_bio_byte) - DMEMIT("corrupt_bio_byte %u %c %u %u ", + DMEMIT(" corrupt_bio_byte %u %c %u %u", fc->corrupt_bio_byte, (fc->corrupt_bio_rw == WRITE) ? 'w' : 'r', fc->corrupt_bio_value, fc->corrupt_bio_flags); @@ -506,25 +521,7 @@ static struct target_type flakey_target = { .prepare_ioctl = flakey_prepare_ioctl, .iterate_devices = flakey_iterate_devices, }; - -static int __init dm_flakey_init(void) -{ - int r = dm_register_target(&flakey_target); - - if (r < 0) - DMERR("register failed %d", r); - - return r; -} - -static void __exit dm_flakey_exit(void) -{ - dm_unregister_target(&flakey_target); -} - -/* Module hooks */ -module_init(dm_flakey_init); -module_exit(dm_flakey_exit); +module_dm(flakey); MODULE_DESCRIPTION(DM_NAME " flakey target"); MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>"); |