aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid5.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r--drivers/md/raid5.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 472aedfb07cf..31670f8d6b65 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3036,6 +3036,8 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s)
3036 if (dev->written) 3036 if (dev->written)
3037 s->written++; 3037 s->written++;
3038 rdev = rcu_dereference(conf->disks[i].rdev); 3038 rdev = rcu_dereference(conf->disks[i].rdev);
3039 if (rdev && test_bit(Faulty, &rdev->flags))
3040 rdev = NULL;
3039 if (rdev) { 3041 if (rdev) {
3040 is_bad = is_badblock(rdev, sh->sector, STRIPE_SECTORS, 3042 is_bad = is_badblock(rdev, sh->sector, STRIPE_SECTORS,
3041 &first_bad, &bad_sectors); 3043 &first_bad, &bad_sectors);
@@ -3063,12 +3065,12 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s)
3063 } 3065 }
3064 } else if (test_bit(In_sync, &rdev->flags)) 3066 } else if (test_bit(In_sync, &rdev->flags))
3065 set_bit(R5_Insync, &dev->flags); 3067 set_bit(R5_Insync, &dev->flags);
3066 else if (!test_bit(Faulty, &rdev->flags)) { 3068 else {
3067 /* in sync if before recovery_offset */ 3069 /* in sync if before recovery_offset */
3068 if (sh->sector + STRIPE_SECTORS <= rdev->recovery_offset) 3070 if (sh->sector + STRIPE_SECTORS <= rdev->recovery_offset)
3069 set_bit(R5_Insync, &dev->flags); 3071 set_bit(R5_Insync, &dev->flags);
3070 } 3072 }
3071 if (test_bit(R5_WriteError, &dev->flags)) { 3073 if (rdev && test_bit(R5_WriteError, &dev->flags)) {
3072 clear_bit(R5_Insync, &dev->flags); 3074 clear_bit(R5_Insync, &dev->flags);
3073 if (!test_bit(Faulty, &rdev->flags)) { 3075 if (!test_bit(Faulty, &rdev->flags)) {
3074 s->handle_bad_blocks = 1; 3076 s->handle_bad_blocks = 1;
@@ -3076,7 +3078,7 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s)
3076 } else 3078 } else
3077 clear_bit(R5_WriteError, &dev->flags); 3079 clear_bit(R5_WriteError, &dev->flags);
3078 } 3080 }
3079 if (test_bit(R5_MadeGood, &dev->flags)) { 3081 if (rdev && test_bit(R5_MadeGood, &dev->flags)) {
3080 if (!test_bit(Faulty, &rdev->flags)) { 3082 if (!test_bit(Faulty, &rdev->flags)) {
3081 s->handle_bad_blocks = 1; 3083 s->handle_bad_blocks = 1;
3082 atomic_inc(&rdev->nr_pending); 3084 atomic_inc(&rdev->nr_pending);
@@ -3110,7 +3112,7 @@ static void handle_stripe(struct stripe_head *sh)
3110 struct r5dev *pdev, *qdev; 3112 struct r5dev *pdev, *qdev;
3111 3113
3112 clear_bit(STRIPE_HANDLE, &sh->state); 3114 clear_bit(STRIPE_HANDLE, &sh->state);
3113 if (test_and_set_bit(STRIPE_ACTIVE, &sh->state)) { 3115 if (test_and_set_bit_lock(STRIPE_ACTIVE, &sh->state)) {
3114 /* already being handled, ensure it gets handled 3116 /* already being handled, ensure it gets handled
3115 * again when current action finishes */ 3117 * again when current action finishes */
3116 set_bit(STRIPE_HANDLE, &sh->state); 3118 set_bit(STRIPE_HANDLE, &sh->state);
@@ -3159,10 +3161,14 @@ static void handle_stripe(struct stripe_head *sh)
3159 /* check if the array has lost more than max_degraded devices and, 3161 /* check if the array has lost more than max_degraded devices and,
3160 * if so, some requests might need to be failed. 3162 * if so, some requests might need to be failed.
3161 */ 3163 */
3162 if (s.failed > conf->max_degraded && s.to_read+s.to_write+s.written) 3164 if (s.failed > conf->max_degraded) {
3163 handle_failed_stripe(conf, sh, &s, disks, &s.return_bi); 3165 sh->check_state = 0;
3164 if (s.failed > conf->max_degraded && s.syncing) 3166 sh->reconstruct_state = 0;
3165 handle_failed_sync(conf, sh, &s); 3167 if (s.to_read+s.to_write+s.written)
3168 handle_failed_stripe(conf, sh, &s, disks, &s.return_bi);
3169 if (s.syncing)
3170 handle_failed_sync(conf, sh, &s);
3171 }
3166 3172
3167 /* 3173 /*
3168 * might be able to return some write requests if the parity blocks 3174 * might be able to return some write requests if the parity blocks
@@ -3371,7 +3377,7 @@ finish:
3371 3377
3372 return_io(s.return_bi); 3378 return_io(s.return_bi);
3373 3379
3374 clear_bit(STRIPE_ACTIVE, &sh->state); 3380 clear_bit_unlock(STRIPE_ACTIVE, &sh->state);
3375} 3381}
3376 3382
3377static void raid5_activate_delayed(struct r5conf *conf) 3383static void raid5_activate_delayed(struct r5conf *conf)