diff options
Diffstat (limited to 'drivers/md/raid5.c')
| -rw-r--r-- | drivers/md/raid5.c | 16 | 
1 files changed, 10 insertions, 6 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 472aedfb07c..297e2609217 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3110,7 +3110,7 @@ static void handle_stripe(struct stripe_head *sh)  	struct r5dev *pdev, *qdev;  	clear_bit(STRIPE_HANDLE, &sh->state); -	if (test_and_set_bit(STRIPE_ACTIVE, &sh->state)) { +	if (test_and_set_bit_lock(STRIPE_ACTIVE, &sh->state)) {  		/* already being handled, ensure it gets handled  		 * again when current action finishes */  		set_bit(STRIPE_HANDLE, &sh->state); @@ -3159,10 +3159,14 @@ static void handle_stripe(struct stripe_head *sh)  	/* check if the array has lost more than max_degraded devices and,  	 * if so, some requests might need to be failed.  	 */ -	if (s.failed > conf->max_degraded && s.to_read+s.to_write+s.written) -		handle_failed_stripe(conf, sh, &s, disks, &s.return_bi); -	if (s.failed > conf->max_degraded && s.syncing) -		handle_failed_sync(conf, sh, &s); +	if (s.failed > conf->max_degraded) { +		sh->check_state = 0; +		sh->reconstruct_state = 0; +		if (s.to_read+s.to_write+s.written) +			handle_failed_stripe(conf, sh, &s, disks, &s.return_bi); +		if (s.syncing) +			handle_failed_sync(conf, sh, &s); +	}  	/*  	 * might be able to return some write requests if the parity blocks @@ -3371,7 +3375,7 @@ finish:  	return_io(s.return_bi); -	clear_bit(STRIPE_ACTIVE, &sh->state); +	clear_bit_unlock(STRIPE_ACTIVE, &sh->state);  }  static void raid5_activate_delayed(struct r5conf *conf)  |