/* write 0 to the specified Nth byte of the bio */
- if (data && bio_bytes >= fc->corrupt_bio_byte)
+ if (data && bio_bytes >= fc->corrupt_bio_byte) {
data[fc->corrupt_bio_byte-1] = 0;
+ printk("corrupting data rw=%lu
", bio_data_dir(bio));
+ }
}
static int flakey_map(struct dm_target *ti, struct bio *bio,
@@ -214,9 +220,11 @@ static int flakey_map(struct dm_target *ti, struct bio *bio,
if (elapsed % (fc->up_interval + fc->down_interval) >= fc->up_interval) {
unsigned rw = bio_data_dir(bio);
if (fc->corrupt_bio_byte) {
- /* only corrupt either reads or writes */
- if (rw == WRITE && rw == fc->corrupt_bio_data_dir)
+ /* corrupt matching writes, defer reads until end_io */
+ if (rw == WRITE && rw == corrupt_bio_data_dir(fc) &&
+ all_corrupt_bio_flags_match(fc, bio))
corrupt_bio_data(bio, fc);
+
/* flag this bio as submitted while down */
map_context->ll = 1;
goto map_bio;
@@ -247,7 +255,8 @@ static int flakey_end_io(struct dm_target *ti, struct bio *bio,
unsigned rw = bio_data_dir(bio);
if (!error && bio_submitted_while_down)
- if (rw == READ && rw == fc->corrupt_bio_data_dir)
+ if (rw == READ && rw == corrupt_bio_data_dir(fc) &&
+ all_corrupt_bio_flags_match(fc, bio))
corrupt_bio_data(bio, fc);