md/raid5: clearly differentiate 'before' and 'after' stripes during reshape.
During a raid5 reshape, we have some stripes in the cache that are
'before' the reshape (and are still to be processed) and some that are
'after'. They are currently differentiated by having different
->disks values as the only reshape current supported involves changing
the number of disks.
However we will soon support reshapes that do not change the number
of disks (chunk parity or chunk size). So make the difference more
explicit with a 'generation' number.
Signed-off-by: NeilBrown <neilb@suse.de>
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 76eed59..73cdf43 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -318,6 +318,7 @@
remove_hash(sh);
+ sh->generation = conf->generation - previous;
sh->disks = previous ? conf->previous_raid_disks : conf->raid_disks;
sh->sector = sector;
stripe_set_idx(sector, conf, previous, sh);
@@ -341,7 +342,8 @@
insert_hash(conf, sh);
}
-static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector, int disks)
+static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector,
+ short generation)
{
struct stripe_head *sh;
struct hlist_node *hn;
@@ -349,7 +351,7 @@
CHECK_DEVLOCK();
pr_debug("__find_stripe, sector %llu\n", (unsigned long long)sector);
hlist_for_each_entry(sh, hn, stripe_hash(conf, sector), hash)
- if (sh->sector == sector && sh->disks == disks)
+ if (sh->sector == sector && sh->generation == generation)
return sh;
pr_debug("__stripe %llu not in cache\n", (unsigned long long)sector);
return NULL;
@@ -363,7 +365,6 @@
int previous, int noblock)
{
struct stripe_head *sh;
- int disks = previous ? conf->previous_raid_disks : conf->raid_disks;
pr_debug("get_stripe, sector %llu\n", (unsigned long long)sector);
@@ -373,7 +374,7 @@
wait_event_lock_irq(conf->wait_for_stripe,
conf->quiesce == 0,
conf->device_lock, /* nothing */);
- sh = __find_stripe(conf, sector, disks);
+ sh = __find_stripe(conf, sector, conf->generation - previous);
if (!sh) {
if (!conf->inactive_blocked)
sh = get_free_stripe(conf);
@@ -3648,7 +3649,7 @@
if ((mddev->delta_disks < 0
? logical_sector >= conf->reshape_progress
: logical_sector < conf->reshape_progress)
- && disks == conf->previous_raid_disks)
+ && previous)
/* mismatch, need to try again */
must_retry = 1;
spin_unlock_irq(&conf->device_lock);
@@ -4837,6 +4838,7 @@
else
conf->reshape_progress = 0;
conf->reshape_safe = conf->reshape_progress;
+ conf->generation++;
spin_unlock_irq(&conf->device_lock);
/* Add some new drives, as many as will fit.