dm-flakey.c (e3675dc1e7ea2e4e5a6527fa7068e9fcbc2475cc) | dm-flakey.c (aa7d7bc99fed71664e9a241b32294ee15a88d938) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2003 Sistina Software (UK) Limited. 4 * Copyright (C) 2004, 2010-2011 Red Hat, Inc. All rights reserved. 5 * 6 * This file is released under the GPL. 7 */ 8 --- 23 unchanged lines hidden (view full) --- 32 unsigned long flags; 33 unsigned int corrupt_bio_byte; 34 unsigned int corrupt_bio_rw; 35 unsigned int corrupt_bio_value; 36 blk_opf_t corrupt_bio_flags; 37}; 38 39enum feature_flag_bits { | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2003 Sistina Software (UK) Limited. 4 * Copyright (C) 2004, 2010-2011 Red Hat, Inc. All rights reserved. 5 * 6 * This file is released under the GPL. 7 */ 8 --- 23 unchanged lines hidden (view full) --- 32 unsigned long flags; 33 unsigned int corrupt_bio_byte; 34 unsigned int corrupt_bio_rw; 35 unsigned int corrupt_bio_value; 36 blk_opf_t corrupt_bio_flags; 37}; 38 39enum feature_flag_bits { |
40 ERROR_READS, |
|
40 DROP_WRITES, 41 ERROR_WRITES 42}; 43 44struct per_bio_data { 45 bool bio_submitted; 46}; 47 48static int parse_features(struct dm_arg_set *as, struct flakey_c *fc, 49 struct dm_target *ti) 50{ 51 int r; 52 unsigned int argc; 53 const char *arg_name; 54 55 static const struct dm_arg _args[] = { | 41 DROP_WRITES, 42 ERROR_WRITES 43}; 44 45struct per_bio_data { 46 bool bio_submitted; 47}; 48 49static int parse_features(struct dm_arg_set *as, struct flakey_c *fc, 50 struct dm_target *ti) 51{ 52 int r; 53 unsigned int argc; 54 const char *arg_name; 55 56 static const struct dm_arg _args[] = { |
56 {0, 6, "Invalid number of feature args"}, | 57 {0, 7, "Invalid number of feature args"}, |
57 {1, UINT_MAX, "Invalid corrupt bio byte"}, 58 {0, 255, "Invalid corrupt value to write into bio byte (0-255)"}, 59 {0, UINT_MAX, "Invalid corrupt bio flags mask"}, 60 }; 61 62 /* No feature arguments supplied. */ 63 if (!as->argc) 64 return 0; --- 7 unchanged lines hidden (view full) --- 72 argc--; 73 74 if (!arg_name) { 75 ti->error = "Insufficient feature arguments"; 76 return -EINVAL; 77 } 78 79 /* | 58 {1, UINT_MAX, "Invalid corrupt bio byte"}, 59 {0, 255, "Invalid corrupt value to write into bio byte (0-255)"}, 60 {0, UINT_MAX, "Invalid corrupt bio flags mask"}, 61 }; 62 63 /* No feature arguments supplied. */ 64 if (!as->argc) 65 return 0; --- 7 unchanged lines hidden (view full) --- 73 argc--; 74 75 if (!arg_name) { 76 ti->error = "Insufficient feature arguments"; 77 return -EINVAL; 78 } 79 80 /* |
81 * error_reads 82 */ 83 if (!strcasecmp(arg_name, "error_reads")) { 84 if (test_and_set_bit(ERROR_READS, &fc->flags)) { 85 ti->error = "Feature error_reads duplicated"; 86 return -EINVAL; 87 } 88 continue; 89 } 90 91 /* |
|
80 * drop_writes 81 */ 82 if (!strcasecmp(arg_name, "drop_writes")) { 83 if (test_and_set_bit(DROP_WRITES, &fc->flags)) { 84 ti->error = "Feature drop_writes duplicated"; 85 return -EINVAL; 86 } else if (test_bit(ERROR_WRITES, &fc->flags)) { 87 ti->error = "Feature drop_writes conflicts with feature error_writes"; --- 78 unchanged lines hidden (view full) --- 166 ti->error = "drop_writes is incompatible with corrupt_bio_byte with the WRITE flag set"; 167 return -EINVAL; 168 169 } else if (test_bit(ERROR_WRITES, &fc->flags) && (fc->corrupt_bio_rw == WRITE)) { 170 ti->error = "error_writes is incompatible with corrupt_bio_byte with the WRITE flag set"; 171 return -EINVAL; 172 } 173 | 92 * drop_writes 93 */ 94 if (!strcasecmp(arg_name, "drop_writes")) { 95 if (test_and_set_bit(DROP_WRITES, &fc->flags)) { 96 ti->error = "Feature drop_writes duplicated"; 97 return -EINVAL; 98 } else if (test_bit(ERROR_WRITES, &fc->flags)) { 99 ti->error = "Feature drop_writes conflicts with feature error_writes"; --- 78 unchanged lines hidden (view full) --- 178 ti->error = "drop_writes is incompatible with corrupt_bio_byte with the WRITE flag set"; 179 return -EINVAL; 180 181 } else if (test_bit(ERROR_WRITES, &fc->flags) && (fc->corrupt_bio_rw == WRITE)) { 182 ti->error = "error_writes is incompatible with corrupt_bio_byte with the WRITE flag set"; 183 return -EINVAL; 184 } 185 |
186 if (!fc->corrupt_bio_byte && !test_bit(ERROR_READS, &fc->flags) && 187 !test_bit(DROP_WRITES, &fc->flags) && !test_bit(ERROR_WRITES, &fc->flags)) { 188 set_bit(ERROR_WRITES, &fc->flags); 189 set_bit(ERROR_READS, &fc->flags); 190 } 191 |
|
174 return 0; 175} 176 177/* 178 * Construct a flakey mapping: 179 * <dev_path> <offset> <up interval> <down interval> [<#feature args> [<arg>]*] 180 * 181 * Feature args: --- 159 unchanged lines hidden (view full) --- 341 */ 342 pb->bio_submitted = true; 343 344 /* 345 * Error reads if neither corrupt_bio_byte or drop_writes or error_writes are set. 346 * Otherwise, flakey_end_io() will decide if the reads should be modified. 347 */ 348 if (bio_data_dir(bio) == READ) { | 192 return 0; 193} 194 195/* 196 * Construct a flakey mapping: 197 * <dev_path> <offset> <up interval> <down interval> [<#feature args> [<arg>]*] 198 * 199 * Feature args: --- 159 unchanged lines hidden (view full) --- 359 */ 360 pb->bio_submitted = true; 361 362 /* 363 * Error reads if neither corrupt_bio_byte or drop_writes or error_writes are set. 364 * Otherwise, flakey_end_io() will decide if the reads should be modified. 365 */ 366 if (bio_data_dir(bio) == READ) { |
349 if (!fc->corrupt_bio_byte && !test_bit(DROP_WRITES, &fc->flags) && 350 !test_bit(ERROR_WRITES, &fc->flags)) | 367 if (test_bit(ERROR_READS, &fc->flags)) |
351 return DM_MAPIO_KILL; 352 goto map_bio; 353 } 354 355 /* 356 * Drop or error writes? 357 */ 358 if (test_bit(DROP_WRITES, &fc->flags)) { --- 9 unchanged lines hidden (view full) --- 368 */ 369 if (fc->corrupt_bio_byte) { 370 if (fc->corrupt_bio_rw == WRITE) { 371 if (all_corrupt_bio_flags_match(bio, fc)) 372 corrupt_bio_data(bio, fc); 373 } 374 goto map_bio; 375 } | 368 return DM_MAPIO_KILL; 369 goto map_bio; 370 } 371 372 /* 373 * Drop or error writes? 374 */ 375 if (test_bit(DROP_WRITES, &fc->flags)) { --- 9 unchanged lines hidden (view full) --- 385 */ 386 if (fc->corrupt_bio_byte) { 387 if (fc->corrupt_bio_rw == WRITE) { 388 if (all_corrupt_bio_flags_match(bio, fc)) 389 corrupt_bio_data(bio, fc); 390 } 391 goto map_bio; 392 } |
376 377 /* 378 * By default, error all I/O. 379 */ 380 return DM_MAPIO_KILL; | |
381 } 382 383map_bio: 384 flakey_map_bio(ti, bio); 385 386 return DM_MAPIO_REMAPPED; 387} 388 --- 10 unchanged lines hidden (view full) --- 399 if (fc->corrupt_bio_byte) { 400 if ((fc->corrupt_bio_rw == READ) && 401 all_corrupt_bio_flags_match(bio, fc)) { 402 /* 403 * Corrupt successful matching READs while in down state. 404 */ 405 corrupt_bio_data(bio, fc); 406 } | 393 } 394 395map_bio: 396 flakey_map_bio(ti, bio); 397 398 return DM_MAPIO_REMAPPED; 399} 400 --- 10 unchanged lines hidden (view full) --- 411 if (fc->corrupt_bio_byte) { 412 if ((fc->corrupt_bio_rw == READ) && 413 all_corrupt_bio_flags_match(bio, fc)) { 414 /* 415 * Corrupt successful matching READs while in down state. 416 */ 417 corrupt_bio_data(bio, fc); 418 } |
407 } else if (!test_bit(DROP_WRITES, &fc->flags) && 408 !test_bit(ERROR_WRITES, &fc->flags)) { | 419 } 420 if (test_bit(ERROR_READS, &fc->flags)) { |
409 /* 410 * Error read during the down_interval if drop_writes 411 * and error_writes were not configured. 412 */ 413 *error = BLK_STS_IOERR; 414 } 415 } 416 417 return DM_ENDIO_DONE; 418} 419 420static void flakey_status(struct dm_target *ti, status_type_t type, 421 unsigned int status_flags, char *result, unsigned int maxlen) 422{ 423 unsigned int sz = 0; 424 struct flakey_c *fc = ti->private; | 421 /* 422 * Error read during the down_interval if drop_writes 423 * and error_writes were not configured. 424 */ 425 *error = BLK_STS_IOERR; 426 } 427 } 428 429 return DM_ENDIO_DONE; 430} 431 432static void flakey_status(struct dm_target *ti, status_type_t type, 433 unsigned int status_flags, char *result, unsigned int maxlen) 434{ 435 unsigned int sz = 0; 436 struct flakey_c *fc = ti->private; |
425 unsigned int drop_writes, error_writes; | 437 unsigned int error_reads, drop_writes, error_writes; |
426 427 switch (type) { 428 case STATUSTYPE_INFO: 429 result[0] = '\0'; 430 break; 431 432 case STATUSTYPE_TABLE: 433 DMEMIT("%s %llu %u %u", fc->dev->name, 434 (unsigned long long)fc->start, fc->up_interval, 435 fc->down_interval); 436 | 438 439 switch (type) { 440 case STATUSTYPE_INFO: 441 result[0] = '\0'; 442 break; 443 444 case STATUSTYPE_TABLE: 445 DMEMIT("%s %llu %u %u", fc->dev->name, 446 (unsigned long long)fc->start, fc->up_interval, 447 fc->down_interval); 448 |
449 error_reads = test_bit(ERROR_READS, &fc->flags); |
|
437 drop_writes = test_bit(DROP_WRITES, &fc->flags); 438 error_writes = test_bit(ERROR_WRITES, &fc->flags); | 450 drop_writes = test_bit(DROP_WRITES, &fc->flags); 451 error_writes = test_bit(ERROR_WRITES, &fc->flags); |
439 DMEMIT(" %u", drop_writes + error_writes + (fc->corrupt_bio_byte > 0) * 5); | 452 DMEMIT(" %u", error_reads + drop_writes + error_writes + (fc->corrupt_bio_byte > 0) * 5); |
440 | 453 |
454 if (error_reads) 455 DMEMIT(" error_reads"); |
|
441 if (drop_writes) 442 DMEMIT(" drop_writes"); 443 else if (error_writes) 444 DMEMIT(" error_writes"); 445 446 if (fc->corrupt_bio_byte) 447 DMEMIT(" corrupt_bio_byte %u %c %u %u", 448 fc->corrupt_bio_byte, --- 65 unchanged lines hidden --- | 456 if (drop_writes) 457 DMEMIT(" drop_writes"); 458 else if (error_writes) 459 DMEMIT(" error_writes"); 460 461 if (fc->corrupt_bio_byte) 462 DMEMIT(" corrupt_bio_byte %u %c %u %u", 463 fc->corrupt_bio_byte, --- 65 unchanged lines hidden --- |