aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2010-06-17 03:25:21 -0400
committerNeilBrown <neilb@suse.de>2010-06-23 23:35:39 -0400
commit415e72d034c50520ddb7ff79e7d1792c1306f0c9 (patch)
tree4558df940a15693e477af206b54423d98d9a04b1
parent674806d62fb02a22eea948c9f1b5e58e0947b728 (diff)
md/raid5: Allow recovered part of partially recovered devices to be in-sync
During a recovery of reshape the early part of some devices might be in-sync while the later parts are not. We we know we are looking at an early part it is good to treat that part as in-sync for stripe calculations. This is particularly important for a reshape which suffers device failure. Treating the data as in-sync can mean the difference between data-safety and data-loss. Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r--drivers/md/raid5.c42
1 files changed, 30 insertions, 12 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index d4b233c25f2e..09f07dadf404 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3031,7 +3031,6 @@ static void handle_stripe5(struct stripe_head *sh)
3031 mdk_rdev_t *rdev; 3031 mdk_rdev_t *rdev;
3032 3032
3033 dev = &sh->dev[i]; 3033 dev = &sh->dev[i];
3034 clear_bit(R5_Insync, &dev->flags);
3035 3034
3036 pr_debug("check %d: state 0x%lx toread %p read %p write %p " 3035 pr_debug("check %d: state 0x%lx toread %p read %p write %p "
3037 "written %p\n", i, dev->flags, dev->toread, dev->read, 3036 "written %p\n", i, dev->flags, dev->toread, dev->read,
@@ -3068,17 +3067,27 @@ static void handle_stripe5(struct stripe_head *sh)
3068 blocked_rdev = rdev; 3067 blocked_rdev = rdev;
3069 atomic_inc(&rdev->nr_pending); 3068 atomic_inc(&rdev->nr_pending);
3070 } 3069 }
3071 if (!rdev || !test_bit(In_sync, &rdev->flags)) { 3070 clear_bit(R5_Insync, &dev->flags);
3071 if (!rdev)
3072 /* Not in-sync */;
3073 else if (test_bit(In_sync, &rdev->flags))
3074 set_bit(R5_Insync, &dev->flags);
3075 else {
3076 /* could be in-sync depending on recovery/reshape status */
3077 if (sh->sector + STRIPE_SECTORS <= rdev->recovery_offset)
3078 set_bit(R5_Insync, &dev->flags);
3079 }
3080 if (!test_bit(R5_Insync, &dev->flags)) {
3072 /* The ReadError flag will just be confusing now */ 3081 /* The ReadError flag will just be confusing now */
3073 clear_bit(R5_ReadError, &dev->flags); 3082 clear_bit(R5_ReadError, &dev->flags);
3074 clear_bit(R5_ReWrite, &dev->flags); 3083 clear_bit(R5_ReWrite, &dev->flags);
3075 } 3084 }
3076 if (!rdev || !test_bit(In_sync, &rdev->flags) 3085 if (test_bit(R5_ReadError, &dev->flags))
3077 || test_bit(R5_ReadError, &dev->flags)) { 3086 clear_bit(R5_Insync, &dev->flags);
3087 if (!test_bit(R5_Insync, &dev->flags)) {
3078 s.failed++; 3088 s.failed++;
3079 s.failed_num = i; 3089 s.failed_num = i;
3080 } else 3090 }
3081 set_bit(R5_Insync, &dev->flags);
3082 } 3091 }
3083 rcu_read_unlock(); 3092 rcu_read_unlock();
3084 3093
@@ -3312,7 +3321,6 @@ static void handle_stripe6(struct stripe_head *sh)
3312 for (i=disks; i--; ) { 3321 for (i=disks; i--; ) {
3313 mdk_rdev_t *rdev; 3322 mdk_rdev_t *rdev;
3314 dev = &sh->dev[i]; 3323 dev = &sh->dev[i];
3315 clear_bit(R5_Insync, &dev->flags);
3316 3324
3317 pr_debug("check %d: state 0x%lx read %p write %p written %p\n", 3325 pr_debug("check %d: state 0x%lx read %p write %p written %p\n",
3318 i, dev->flags, dev->toread, dev->towrite, dev->written); 3326 i, dev->flags, dev->toread, dev->towrite, dev->written);
@@ -3350,18 +3358,28 @@ static void handle_stripe6(struct stripe_head *sh)
3350 blocked_rdev = rdev; 3358 blocked_rdev = rdev;
3351 atomic_inc(&rdev->nr_pending); 3359 atomic_inc(&rdev->nr_pending);
3352 } 3360 }
3353 if (!rdev || !test_bit(In_sync, &rdev->flags)) { 3361 clear_bit(R5_Insync, &dev->flags);
3362 if (!rdev)
3363 /* Not in-sync */;
3364 else if (test_bit(In_sync, &rdev->flags))
3365 set_bit(R5_Insync, &dev->flags);
3366 else {
3367 /* in sync if before recovery_offset */
3368 if (sh->sector + STRIPE_SECTORS <= rdev->recovery_offset)
3369 set_bit(R5_Insync, &dev->flags);
3370 }
3371 if (!test_bit(R5_Insync, &dev->flags)) {
3354 /* The ReadError flag will just be confusing now */ 3372 /* The ReadError flag will just be confusing now */
3355 clear_bit(R5_ReadError, &dev->flags); 3373 clear_bit(R5_ReadError, &dev->flags);
3356 clear_bit(R5_ReWrite, &dev->flags); 3374 clear_bit(R5_ReWrite, &dev->flags);
3357 } 3375 }
3358 if (!rdev || !test_bit(In_sync, &rdev->flags) 3376 if (test_bit(R5_ReadError, &dev->flags))
3359 || test_bit(R5_ReadError, &dev->flags)) { 3377 clear_bit(R5_Insync, &dev->flags);
3378 if (!test_bit(R5_Insync, &dev->flags)) {
3360 if (s.failed < 2) 3379 if (s.failed < 2)
3361 r6s.failed_num[s.failed] = i; 3380 r6s.failed_num[s.failed] = i;
3362 s.failed++; 3381 s.failed++;
3363 } else 3382 }
3364 set_bit(R5_Insync, &dev->flags);
3365 } 3383 }
3366 rcu_read_unlock(); 3384 rcu_read_unlock();
3367 3385