@@ -47,7 +47,8 @@ enum feature_flag_bits {
4747};
4848
4949struct per_bio_data {
50- bool bio_submitted ;
50+ bool bio_can_corrupt ;
51+ struct bvec_iter saved_iter ;
5152};
5253
5354static int parse_features (struct dm_arg_set * as , struct flakey_c * fc ,
@@ -354,7 +355,8 @@ static void flakey_map_bio(struct dm_target *ti, struct bio *bio)
354355}
355356
356357static void corrupt_bio_common (struct bio * bio , unsigned int corrupt_bio_byte ,
357- unsigned char corrupt_bio_value )
358+ unsigned char corrupt_bio_value ,
359+ struct bvec_iter start )
358360{
359361 struct bvec_iter iter ;
360362 struct bio_vec bvec ;
@@ -363,7 +365,7 @@ static void corrupt_bio_common(struct bio *bio, unsigned int corrupt_bio_byte,
363365 * Overwrite the Nth byte of the bio's data, on whichever page
364366 * it falls.
365367 */
366- bio_for_each_segment (bvec , bio , iter ) {
368+ __bio_for_each_segment (bvec , bio , iter , start ) {
367369 if (bio_iter_len (bio , iter ) > corrupt_bio_byte ) {
368370 unsigned char * segment = bvec_kmap_local (& bvec );
369371 segment [corrupt_bio_byte ] = corrupt_bio_value ;
@@ -372,36 +374,31 @@ static void corrupt_bio_common(struct bio *bio, unsigned int corrupt_bio_byte,
372374 "(rw=%c bi_opf=%u bi_sector=%llu size=%u)\n" ,
373375 bio , corrupt_bio_value , corrupt_bio_byte ,
374376 (bio_data_dir (bio ) == WRITE ) ? 'w' : 'r' , bio -> bi_opf ,
375- (unsigned long long )bio -> bi_iter .bi_sector ,
376- bio -> bi_iter .bi_size );
377+ (unsigned long long )start .bi_sector ,
378+ start .bi_size );
377379 break ;
378380 }
379381 corrupt_bio_byte -= bio_iter_len (bio , iter );
380382 }
381383}
382384
383- static void corrupt_bio_data (struct bio * bio , struct flakey_c * fc )
385+ static void corrupt_bio_data (struct bio * bio , struct flakey_c * fc ,
386+ struct bvec_iter start )
384387{
385388 unsigned int corrupt_bio_byte = fc -> corrupt_bio_byte - 1 ;
386389
387- if (!bio_has_data (bio ))
388- return ;
389-
390- corrupt_bio_common (bio , corrupt_bio_byte , fc -> corrupt_bio_value );
390+ corrupt_bio_common (bio , corrupt_bio_byte , fc -> corrupt_bio_value , start );
391391}
392392
393- static void corrupt_bio_random (struct bio * bio )
393+ static void corrupt_bio_random (struct bio * bio , struct bvec_iter start )
394394{
395395 unsigned int corrupt_byte ;
396396 unsigned char corrupt_value ;
397397
398- if (!bio_has_data (bio ))
399- return ;
400-
401- corrupt_byte = get_random_u32 () % bio -> bi_iter .bi_size ;
398+ corrupt_byte = get_random_u32 () % start .bi_size ;
402399 corrupt_value = get_random_u8 ();
403400
404- corrupt_bio_common (bio , corrupt_byte , corrupt_value );
401+ corrupt_bio_common (bio , corrupt_byte , corrupt_value , start );
405402}
406403
407404static void clone_free (struct bio * clone )
@@ -496,7 +493,7 @@ static int flakey_map(struct dm_target *ti, struct bio *bio)
496493 unsigned int elapsed ;
497494 struct per_bio_data * pb = dm_per_bio_data (bio , sizeof (struct per_bio_data ));
498495
499- pb -> bio_submitted = false;
496+ pb -> bio_can_corrupt = false;
500497
501498 if (op_is_zone_mgmt (bio_op (bio )))
502499 goto map_bio ;
@@ -505,10 +502,11 @@ static int flakey_map(struct dm_target *ti, struct bio *bio)
505502 elapsed = (jiffies - fc -> start_time ) / HZ ;
506503 if (elapsed % (fc -> up_interval + fc -> down_interval ) >= fc -> up_interval ) {
507504 bool corrupt_fixed , corrupt_random ;
508- /*
509- * Flag this bio as submitted while down.
510- */
511- pb -> bio_submitted = true;
505+
506+ if (bio_has_data (bio )) {
507+ pb -> bio_can_corrupt = true;
508+ pb -> saved_iter = bio -> bi_iter ;
509+ }
512510
513511 /*
514512 * If ERROR_READS isn't set flakey_end_io() will decide if the
@@ -531,6 +529,8 @@ static int flakey_map(struct dm_target *ti, struct bio *bio)
531529 return DM_MAPIO_SUBMITTED ;
532530 }
533531
532+ if (!pb -> bio_can_corrupt )
533+ goto map_bio ;
534534 /*
535535 * Corrupt matching writes.
536536 */
@@ -550,9 +550,11 @@ static int flakey_map(struct dm_target *ti, struct bio *bio)
550550 struct bio * clone = clone_bio (ti , fc , bio );
551551 if (clone ) {
552552 if (corrupt_fixed )
553- corrupt_bio_data (clone , fc );
553+ corrupt_bio_data (clone , fc ,
554+ clone -> bi_iter );
554555 if (corrupt_random )
555- corrupt_bio_random (clone );
556+ corrupt_bio_random (clone ,
557+ clone -> bi_iter );
556558 submit_bio (clone );
557559 return DM_MAPIO_SUBMITTED ;
558560 }
@@ -574,21 +576,21 @@ static int flakey_end_io(struct dm_target *ti, struct bio *bio,
574576 if (op_is_zone_mgmt (bio_op (bio )))
575577 return DM_ENDIO_DONE ;
576578
577- if (!* error && pb -> bio_submitted && (bio_data_dir (bio ) == READ )) {
579+ if (!* error && pb -> bio_can_corrupt && (bio_data_dir (bio ) == READ )) {
578580 if (fc -> corrupt_bio_byte ) {
579581 if ((fc -> corrupt_bio_rw == READ ) &&
580582 all_corrupt_bio_flags_match (bio , fc )) {
581583 /*
582584 * Corrupt successful matching READs while in down state.
583585 */
584- corrupt_bio_data (bio , fc );
586+ corrupt_bio_data (bio , fc , pb -> saved_iter );
585587 }
586588 }
587589 if (fc -> random_read_corrupt ) {
588590 u64 rnd = get_random_u64 ();
589591 u32 rem = do_div (rnd , PROBABILITY_BASE );
590592 if (rem < fc -> random_read_corrupt )
591- corrupt_bio_random (bio );
593+ corrupt_bio_random (bio , pb -> saved_iter );
592594 }
593595 }
594596
0 commit comments