@@ -36,7 +36,8 @@ struct flakey_c {
3636};
3737
3838enum feature_flag_bits {
39- DROP_WRITES
39+ DROP_WRITES ,
40+ ERROR_WRITES
4041};
4142
4243struct 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
413446static 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