aboutsummaryrefslogtreecommitdiff
path: root/drivers/md/dm-flakey.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm-flakey.c')
-rw-r--r--drivers/md/dm-flakey.c71
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>");