Commit 415e72d0 authored by NeilBrown's avatar NeilBrown

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: default avatarNeilBrown <neilb@suse.de>
parent 674806d6
...@@ -3031,7 +3031,6 @@ static void handle_stripe5(struct stripe_head *sh) ...@@ -3031,7 +3031,6 @@ static void handle_stripe5(struct stripe_head *sh)
mdk_rdev_t *rdev; mdk_rdev_t *rdev;
dev = &sh->dev[i]; dev = &sh->dev[i];
clear_bit(R5_Insync, &dev->flags);
pr_debug("check %d: state 0x%lx toread %p read %p write %p " pr_debug("check %d: state 0x%lx toread %p read %p write %p "
"written %p\n", i, dev->flags, dev->toread, dev->read, "written %p\n", i, dev->flags, dev->toread, dev->read,
...@@ -3068,17 +3067,27 @@ static void handle_stripe5(struct stripe_head *sh) ...@@ -3068,17 +3067,27 @@ static void handle_stripe5(struct stripe_head *sh)
blocked_rdev = rdev; blocked_rdev = rdev;
atomic_inc(&rdev->nr_pending); atomic_inc(&rdev->nr_pending);
} }
if (!rdev || !test_bit(In_sync, &rdev->flags)) { clear_bit(R5_Insync, &dev->flags);
if (!rdev)
/* Not in-sync */;
else if (test_bit(In_sync, &rdev->flags))
set_bit(R5_Insync, &dev->flags);
else {
/* could be in-sync depending on recovery/reshape status */
if (sh->sector + STRIPE_SECTORS <= rdev->recovery_offset)
set_bit(R5_Insync, &dev->flags);
}
if (!test_bit(R5_Insync, &dev->flags)) {
/* The ReadError flag will just be confusing now */ /* The ReadError flag will just be confusing now */
clear_bit(R5_ReadError, &dev->flags); clear_bit(R5_ReadError, &dev->flags);
clear_bit(R5_ReWrite, &dev->flags); clear_bit(R5_ReWrite, &dev->flags);
} }
if (!rdev || !test_bit(In_sync, &rdev->flags) if (test_bit(R5_ReadError, &dev->flags))
|| test_bit(R5_ReadError, &dev->flags)) { clear_bit(R5_Insync, &dev->flags);
if (!test_bit(R5_Insync, &dev->flags)) {
s.failed++; s.failed++;
s.failed_num = i; s.failed_num = i;
} else }
set_bit(R5_Insync, &dev->flags);
} }
rcu_read_unlock(); rcu_read_unlock();
...@@ -3312,7 +3321,6 @@ static void handle_stripe6(struct stripe_head *sh) ...@@ -3312,7 +3321,6 @@ static void handle_stripe6(struct stripe_head *sh)
for (i=disks; i--; ) { for (i=disks; i--; ) {
mdk_rdev_t *rdev; mdk_rdev_t *rdev;
dev = &sh->dev[i]; dev = &sh->dev[i];
clear_bit(R5_Insync, &dev->flags);
pr_debug("check %d: state 0x%lx read %p write %p written %p\n", pr_debug("check %d: state 0x%lx read %p write %p written %p\n",
i, dev->flags, dev->toread, dev->towrite, dev->written); i, dev->flags, dev->toread, dev->towrite, dev->written);
...@@ -3350,18 +3358,28 @@ static void handle_stripe6(struct stripe_head *sh) ...@@ -3350,18 +3358,28 @@ static void handle_stripe6(struct stripe_head *sh)
blocked_rdev = rdev; blocked_rdev = rdev;
atomic_inc(&rdev->nr_pending); atomic_inc(&rdev->nr_pending);
} }
if (!rdev || !test_bit(In_sync, &rdev->flags)) { clear_bit(R5_Insync, &dev->flags);
if (!rdev)
/* Not in-sync */;
else if (test_bit(In_sync, &rdev->flags))
set_bit(R5_Insync, &dev->flags);
else {
/* in sync if before recovery_offset */
if (sh->sector + STRIPE_SECTORS <= rdev->recovery_offset)
set_bit(R5_Insync, &dev->flags);
}
if (!test_bit(R5_Insync, &dev->flags)) {
/* The ReadError flag will just be confusing now */ /* The ReadError flag will just be confusing now */
clear_bit(R5_ReadError, &dev->flags); clear_bit(R5_ReadError, &dev->flags);
clear_bit(R5_ReWrite, &dev->flags); clear_bit(R5_ReWrite, &dev->flags);
} }
if (!rdev || !test_bit(In_sync, &rdev->flags) if (test_bit(R5_ReadError, &dev->flags))
|| test_bit(R5_ReadError, &dev->flags)) { clear_bit(R5_Insync, &dev->flags);
if (!test_bit(R5_Insync, &dev->flags)) {
if (s.failed < 2) if (s.failed < 2)
r6s.failed_num[s.failed] = i; r6s.failed_num[s.failed] = i;
s.failed++; s.failed++;
} else }
set_bit(R5_Insync, &dev->flags);
} }
rcu_read_unlock(); rcu_read_unlock();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment