From aa7d7bc99fed71664e9a241b32294ee15a88d938 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Tue, 18 Apr 2023 15:56:41 -0400 Subject: [PATCH] dm flakey: add an "error_reads" option dm-flakey returns error on reads if no other argument is specified. This commit simplifies associated logic while formalizing an "error_reads" argument and an ERROR_READS flag. If no argument is specified, set ERROR_READS flag so that it behaves just like before this commit. Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer --- .../admin-guide/device-mapper/dm-flakey.rst | 4 +++ drivers/md/dm-flakey.c | 39 +++++++++++++++------- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/Documentation/admin-guide/device-mapper/dm-flakey.rst b/Documentation/admin-guide/device-mapper/dm-flakey.rst index 8613873..f7104c0 100644 --- a/Documentation/admin-guide/device-mapper/dm-flakey.rst +++ b/Documentation/admin-guide/device-mapper/dm-flakey.rst @@ -39,6 +39,10 @@ Optional feature parameters: If no feature parameters are present, during the periods of unreliability, all I/O returns errors. + error_reads: + All read I/O is failed with an error signalled. + Write I/O is handled correctly. + drop_writes: All write I/O is silently ignored. Read I/O is handled correctly. diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c index 948b6b5..bd80bca 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")) { @@ -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: @@ -434,10 +446,13 @@ static void flakey_status(struct dm_target *ti, status_type_t type, (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"); else if (error_writes) -- 2.7.4