Skip to content

Commit ef548c5

Browse files
committed
dm flakey: introduce "error_writes" feature
Recent dm-flakey fixes, to have reads error out during the "down" interval, made it so that the previous read behaviour is no longer available. It is useful to have reads complete like normal but have writes error out, so make it possible again with a new "error_writes" feature. Signed-off-by: Mike Snitzer <snitzer@redhat.com>
1 parent e99dda8 commit ef548c5

File tree

1 file changed

+42
-9
lines changed

1 file changed

+42
-9
lines changed

drivers/md/dm-flakey.c

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ struct flakey_c {
3636
};
3737

3838
enum feature_flag_bits {
39-
DROP_WRITES
39+
DROP_WRITES,
40+
ERROR_WRITES
4041
};
4142

4243
struct per_bio_data {
@@ -76,6 +77,25 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
7677
if (test_and_set_bit(DROP_WRITES, &fc->flags)) {
7778
ti->error = "Feature drop_writes duplicated";
7879
return -EINVAL;
80+
} else if (test_bit(ERROR_WRITES, &fc->flags)) {
81+
ti->error = "Feature drop_writes conflicts with feature error_writes";
82+
return -EINVAL;
83+
}
84+
85+
continue;
86+
}
87+
88+
/*
89+
* error_writes
90+
*/
91+
if (!strcasecmp(arg_name, "error_writes")) {
92+
if (test_and_set_bit(ERROR_WRITES, &fc->flags)) {
93+
ti->error = "Feature error_writes duplicated";
94+
return -EINVAL;
95+
96+
} else if (test_bit(DROP_WRITES, &fc->flags)) {
97+
ti->error = "Feature error_writes conflicts with feature drop_writes";
98+
return -EINVAL;
7999
}
80100

81101
continue;
@@ -135,6 +155,10 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
135155
if (test_bit(DROP_WRITES, &fc->flags) && (fc->corrupt_bio_rw == WRITE)) {
136156
ti->error = "drop_writes is incompatible with corrupt_bio_byte with the WRITE flag set";
137157
return -EINVAL;
158+
159+
} else if (test_bit(ERROR_WRITES, &fc->flags) && (fc->corrupt_bio_rw == WRITE)) {
160+
ti->error = "error_writes is incompatible with corrupt_bio_byte with the WRITE flag set";
161+
return -EINVAL;
138162
}
139163

140164
return 0;
@@ -291,22 +315,27 @@ static int flakey_map(struct dm_target *ti, struct bio *bio)
291315
pb->bio_submitted = true;
292316

293317
/*
294-
* Error reads if neither corrupt_bio_byte or drop_writes are set.
318+
* Error reads if neither corrupt_bio_byte or drop_writes or error_writes are set.
295319
* Otherwise, flakey_end_io() will decide if the reads should be modified.
296320
*/
297321
if (bio_data_dir(bio) == READ) {
298-
if (!fc->corrupt_bio_byte && !test_bit(DROP_WRITES, &fc->flags))
322+
if (!fc->corrupt_bio_byte && !test_bit(DROP_WRITES, &fc->flags) &&
323+
!test_bit(ERROR_WRITES, &fc->flags))
299324
return -EIO;
300325
goto map_bio;
301326
}
302327

303328
/*
304-
* Drop writes?
329+
* Drop or error writes?
305330
*/
306331
if (test_bit(DROP_WRITES, &fc->flags)) {
307332
bio_endio(bio);
308333
return DM_MAPIO_SUBMITTED;
309334
}
335+
else if (test_bit(ERROR_WRITES, &fc->flags)) {
336+
bio_io_error(bio);
337+
return DM_MAPIO_SUBMITTED;
338+
}
310339

311340
/*
312341
* Corrupt matching writes.
@@ -342,10 +371,11 @@ static int flakey_end_io(struct dm_target *ti, struct bio *bio, int error)
342371
*/
343372
corrupt_bio_data(bio, fc);
344373

345-
} else if (!test_bit(DROP_WRITES, &fc->flags)) {
374+
} else if (!test_bit(DROP_WRITES, &fc->flags) &&
375+
!test_bit(ERROR_WRITES, &fc->flags)) {
346376
/*
347377
* Error read during the down_interval if drop_writes
348-
* wasn't configured.
378+
* and error_writes were not configured.
349379
*/
350380
return -EIO;
351381
}
@@ -359,7 +389,7 @@ static void flakey_status(struct dm_target *ti, status_type_t type,
359389
{
360390
unsigned sz = 0;
361391
struct flakey_c *fc = ti->private;
362-
unsigned drop_writes;
392+
unsigned drop_writes, error_writes;
363393

364394
switch (type) {
365395
case STATUSTYPE_INFO:
@@ -372,10 +402,13 @@ static void flakey_status(struct dm_target *ti, status_type_t type,
372402
fc->down_interval);
373403

374404
drop_writes = test_bit(DROP_WRITES, &fc->flags);
375-
DMEMIT("%u ", drop_writes + (fc->corrupt_bio_byte > 0) * 5);
405+
error_writes = test_bit(ERROR_WRITES, &fc->flags);
406+
DMEMIT("%u ", drop_writes + error_writes + (fc->corrupt_bio_byte > 0) * 5);
376407

377408
if (drop_writes)
378409
DMEMIT("drop_writes ");
410+
else if (error_writes)
411+
DMEMIT("error_writes ");
379412

380413
if (fc->corrupt_bio_byte)
381414
DMEMIT("corrupt_bio_byte %u %c %u %u ",
@@ -412,7 +445,7 @@ static int flakey_iterate_devices(struct dm_target *ti, iterate_devices_callout_
412445

413446
static struct target_type flakey_target = {
414447
.name = "flakey",
415-
.version = {1, 3, 1},
448+
.version = {1, 4, 0},
416449
.module = THIS_MODULE,
417450
.ctr = flakey_ctr,
418451
.dtr = flakey_dtr,

0 commit comments

Comments
 (0)