mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-24 20:54:10 +08:00
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>
This commit is contained in:
parent
e99dda8fc4
commit
ef548c551e
@ -36,7 +36,8 @@ struct flakey_c {
|
||||
};
|
||||
|
||||
enum feature_flag_bits {
|
||||
DROP_WRITES
|
||||
DROP_WRITES,
|
||||
ERROR_WRITES
|
||||
};
|
||||
|
||||
struct per_bio_data {
|
||||
@ -76,6 +77,25 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
|
||||
if (test_and_set_bit(DROP_WRITES, &fc->flags)) {
|
||||
ti->error = "Feature drop_writes duplicated";
|
||||
return -EINVAL;
|
||||
} else if (test_bit(ERROR_WRITES, &fc->flags)) {
|
||||
ti->error = "Feature drop_writes conflicts with feature error_writes";
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* error_writes
|
||||
*/
|
||||
if (!strcasecmp(arg_name, "error_writes")) {
|
||||
if (test_and_set_bit(ERROR_WRITES, &fc->flags)) {
|
||||
ti->error = "Feature error_writes duplicated";
|
||||
return -EINVAL;
|
||||
|
||||
} else if (test_bit(DROP_WRITES, &fc->flags)) {
|
||||
ti->error = "Feature error_writes conflicts with feature drop_writes";
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
continue;
|
||||
@ -135,6 +155,10 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
|
||||
if (test_bit(DROP_WRITES, &fc->flags) && (fc->corrupt_bio_rw == WRITE)) {
|
||||
ti->error = "drop_writes is incompatible with corrupt_bio_byte with the WRITE flag set";
|
||||
return -EINVAL;
|
||||
|
||||
} else if (test_bit(ERROR_WRITES, &fc->flags) && (fc->corrupt_bio_rw == WRITE)) {
|
||||
ti->error = "error_writes is incompatible with corrupt_bio_byte with the WRITE flag set";
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -291,22 +315,27 @@ static int flakey_map(struct dm_target *ti, struct bio *bio)
|
||||
pb->bio_submitted = true;
|
||||
|
||||
/*
|
||||
* Error reads if neither corrupt_bio_byte or drop_writes are set.
|
||||
* Error reads if neither corrupt_bio_byte or drop_writes or error_writes are set.
|
||||
* 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))
|
||||
if (!fc->corrupt_bio_byte && !test_bit(DROP_WRITES, &fc->flags) &&
|
||||
!test_bit(ERROR_WRITES, &fc->flags))
|
||||
return -EIO;
|
||||
goto map_bio;
|
||||
}
|
||||
|
||||
/*
|
||||
* Drop writes?
|
||||
* Drop or error writes?
|
||||
*/
|
||||
if (test_bit(DROP_WRITES, &fc->flags)) {
|
||||
bio_endio(bio);
|
||||
return DM_MAPIO_SUBMITTED;
|
||||
}
|
||||
else if (test_bit(ERROR_WRITES, &fc->flags)) {
|
||||
bio_io_error(bio);
|
||||
return DM_MAPIO_SUBMITTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Corrupt matching writes.
|
||||
@ -342,10 +371,11 @@ static int flakey_end_io(struct dm_target *ti, struct bio *bio, int error)
|
||||
*/
|
||||
corrupt_bio_data(bio, fc);
|
||||
|
||||
} else if (!test_bit(DROP_WRITES, &fc->flags)) {
|
||||
} else if (!test_bit(DROP_WRITES, &fc->flags) &&
|
||||
!test_bit(ERROR_WRITES, &fc->flags)) {
|
||||
/*
|
||||
* Error read during the down_interval if drop_writes
|
||||
* wasn't configured.
|
||||
* and error_writes were not configured.
|
||||
*/
|
||||
return -EIO;
|
||||
}
|
||||
@ -359,7 +389,7 @@ static void flakey_status(struct dm_target *ti, status_type_t type,
|
||||
{
|
||||
unsigned sz = 0;
|
||||
struct flakey_c *fc = ti->private;
|
||||
unsigned drop_writes;
|
||||
unsigned drop_writes, error_writes;
|
||||
|
||||
switch (type) {
|
||||
case STATUSTYPE_INFO:
|
||||
@ -372,10 +402,13 @@ static void flakey_status(struct dm_target *ti, status_type_t type,
|
||||
fc->down_interval);
|
||||
|
||||
drop_writes = test_bit(DROP_WRITES, &fc->flags);
|
||||
DMEMIT("%u ", drop_writes + (fc->corrupt_bio_byte > 0) * 5);
|
||||
error_writes = test_bit(ERROR_WRITES, &fc->flags);
|
||||
DMEMIT("%u ", drop_writes + error_writes + (fc->corrupt_bio_byte > 0) * 5);
|
||||
|
||||
if (drop_writes)
|
||||
DMEMIT("drop_writes ");
|
||||
else if (error_writes)
|
||||
DMEMIT("error_writes ");
|
||||
|
||||
if (fc->corrupt_bio_byte)
|
||||
DMEMIT("corrupt_bio_byte %u %c %u %u ",
|
||||
@ -412,7 +445,7 @@ static int flakey_iterate_devices(struct dm_target *ti, iterate_devices_callout_
|
||||
|
||||
static struct target_type flakey_target = {
|
||||
.name = "flakey",
|
||||
.version = {1, 3, 1},
|
||||
.version = {1, 4, 0},
|
||||
.module = THIS_MODULE,
|
||||
.ctr = flakey_ctr,
|
||||
.dtr = flakey_dtr,
|
||||
|
Loading…
Reference in New Issue
Block a user