diff options
Diffstat (limited to 'drivers/md/raid1.c')
| -rw-r--r-- | drivers/md/raid1.c | 26 | 
1 files changed, 15 insertions, 11 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 1961d827dbd1..29e2df5cd77b 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -403,11 +403,14 @@ static void raid1_end_write_request(struct bio *bio)  	struct bio *to_put = NULL;  	int mirror = find_bio_disk(r1_bio, bio);  	struct md_rdev *rdev = conf->mirrors[mirror].rdev; +	bool discard_error; + +	discard_error = bio->bi_error && bio_op(bio) == REQ_OP_DISCARD;  	/*  	 * 'one mirror IO has finished' event handler:  	 */ -	if (bio->bi_error) { +	if (bio->bi_error && !discard_error) {  		set_bit(WriteErrorSeen,	&rdev->flags);  		if (!test_and_set_bit(WantReplacement, &rdev->flags))  			set_bit(MD_RECOVERY_NEEDED, & @@ -444,7 +447,7 @@ static void raid1_end_write_request(struct bio *bio)  		/* Maybe we can clear some bad blocks. */  		if (is_badblock(rdev, r1_bio->sector, r1_bio->sectors, -				&first_bad, &bad_sectors)) { +				&first_bad, &bad_sectors) && !discard_error) {  			r1_bio->bios[mirror] = IO_MADE_GOOD;  			set_bit(R1BIO_MadeGood, &r1_bio->state);  		} @@ -2294,17 +2297,23 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio)  	 * This is all done synchronously while the array is  	 * frozen  	 */ + +	bio = r1_bio->bios[r1_bio->read_disk]; +	bdevname(bio->bi_bdev, b); +	bio_put(bio); +	r1_bio->bios[r1_bio->read_disk] = NULL; +  	if (mddev->ro == 0) {  		freeze_array(conf, 1);  		fix_read_error(conf, r1_bio->read_disk,  			       r1_bio->sector, r1_bio->sectors);  		unfreeze_array(conf); -	} else -		md_error(mddev, conf->mirrors[r1_bio->read_disk].rdev); +	} else { +		r1_bio->bios[r1_bio->read_disk] = IO_BLOCKED; +	} +  	rdev_dec_pending(conf->mirrors[r1_bio->read_disk].rdev, conf->mddev); -	bio = r1_bio->bios[r1_bio->read_disk]; -	bdevname(bio->bi_bdev, b);  read_more:  	disk = read_balance(conf, r1_bio, &max_sectors);  	if (disk == -1) { @@ -2315,11 +2324,6 @@ read_more:  	} else {  		const unsigned long do_sync  			= r1_bio->master_bio->bi_opf & REQ_SYNC; -		if (bio) { -			r1_bio->bios[r1_bio->read_disk] = -				mddev->ro ? IO_BLOCKED : NULL; -			bio_put(bio); -		}  		r1_bio->read_disk = disk;  		bio = bio_clone_mddev(r1_bio->master_bio, GFP_NOIO, mddev);  		bio_trim(bio, r1_bio->sector - bio->bi_iter.bi_sector,  | 
