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 ---