aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2009-03-31 00:19:03 -0400
committerNeilBrown <neilb@suse.de>2009-03-31 00:19:03 -0400
commit86b42c713be3e5f6807aa14b4cbdb005d35c64d5 (patch)
treed6c70a966a6bda99e6cd4ce055efa84ab0ded701 /drivers/md
parent11373542344bdc35be1e6e68b0baadd1b6f7acbb (diff)
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>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/raid5.c12
-rw-r--r--drivers/md/raid5.h3
2 files changed, 10 insertions, 5 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 76eed592371e..73cdf43a6479 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -318,6 +318,7 @@ static void init_stripe(struct stripe_head *sh, sector_t sector, int previous)
318 318
319 remove_hash(sh); 319 remove_hash(sh);
320 320
321 sh->generation = conf->generation - previous;
321 sh->disks = previous ? conf->previous_raid_disks : conf->raid_disks; 322 sh->disks = previous ? conf->previous_raid_disks : conf->raid_disks;
322 sh->sector = sector; 323 sh->sector = sector;
323 stripe_set_idx(sector, conf, previous, sh); 324 stripe_set_idx(sector, conf, previous, sh);
@@ -341,7 +342,8 @@ static void init_stripe(struct stripe_head *sh, sector_t sector, int previous)
341 insert_hash(conf, sh); 342 insert_hash(conf, sh);
342} 343}
343 344
344static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector, int disks) 345static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector,
346 short generation)
345{ 347{
346 struct stripe_head *sh; 348 struct stripe_head *sh;
347 struct hlist_node *hn; 349 struct hlist_node *hn;
@@ -349,7 +351,7 @@ static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector, in
349 CHECK_DEVLOCK(); 351 CHECK_DEVLOCK();
350 pr_debug("__find_stripe, sector %llu\n", (unsigned long long)sector); 352 pr_debug("__find_stripe, sector %llu\n", (unsigned long long)sector);
351 hlist_for_each_entry(sh, hn, stripe_hash(conf, sector), hash) 353 hlist_for_each_entry(sh, hn, stripe_hash(conf, sector), hash)
352 if (sh->sector == sector && sh->disks == disks) 354 if (sh->sector == sector && sh->generation == generation)
353 return sh; 355 return sh;
354 pr_debug("__stripe %llu not in cache\n", (unsigned long long)sector); 356 pr_debug("__stripe %llu not in cache\n", (unsigned long long)sector);
355 return NULL; 357 return NULL;
@@ -363,7 +365,6 @@ get_active_stripe(raid5_conf_t *conf, sector_t sector,
363 int previous, int noblock) 365 int previous, int noblock)
364{ 366{
365 struct stripe_head *sh; 367 struct stripe_head *sh;
366 int disks = previous ? conf->previous_raid_disks : conf->raid_disks;
367 368
368 pr_debug("get_stripe, sector %llu\n", (unsigned long long)sector); 369 pr_debug("get_stripe, sector %llu\n", (unsigned long long)sector);
369 370
@@ -373,7 +374,7 @@ get_active_stripe(raid5_conf_t *conf, sector_t sector,
373 wait_event_lock_irq(conf->wait_for_stripe, 374 wait_event_lock_irq(conf->wait_for_stripe,
374 conf->quiesce == 0, 375 conf->quiesce == 0,
375 conf->device_lock, /* nothing */); 376 conf->device_lock, /* nothing */);
376 sh = __find_stripe(conf, sector, disks); 377 sh = __find_stripe(conf, sector, conf->generation - previous);
377 if (!sh) { 378 if (!sh) {
378 if (!conf->inactive_blocked) 379 if (!conf->inactive_blocked)
379 sh = get_free_stripe(conf); 380 sh = get_free_stripe(conf);
@@ -3648,7 +3649,7 @@ static int make_request(struct request_queue *q, struct bio * bi)
3648 if ((mddev->delta_disks < 0 3649 if ((mddev->delta_disks < 0
3649 ? logical_sector >= conf->reshape_progress 3650 ? logical_sector >= conf->reshape_progress
3650 : logical_sector < conf->reshape_progress) 3651 : logical_sector < conf->reshape_progress)
3651 && disks == conf->previous_raid_disks) 3652 && previous)
3652 /* mismatch, need to try again */ 3653 /* mismatch, need to try again */
3653 must_retry = 1; 3654 must_retry = 1;
3654 spin_unlock_irq(&conf->device_lock); 3655 spin_unlock_irq(&conf->device_lock);
@@ -4837,6 +4838,7 @@ static int raid5_start_reshape(mddev_t *mddev)
4837 else 4838 else
4838 conf->reshape_progress = 0; 4839 conf->reshape_progress = 0;
4839 conf->reshape_safe = conf->reshape_progress; 4840 conf->reshape_safe = conf->reshape_progress;
4841 conf->generation++;
4840 spin_unlock_irq(&conf->device_lock); 4842 spin_unlock_irq(&conf->device_lock);
4841 4843
4842 /* Add some new drives, as many as will fit. 4844 /* Add some new drives, as many as will fit.
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h
index b2edcc434e41..a081fb40a5a2 100644
--- a/drivers/md/raid5.h
+++ b/drivers/md/raid5.h
@@ -198,6 +198,8 @@ struct stripe_head {
198 struct hlist_node hash; 198 struct hlist_node hash;
199 struct list_head lru; /* inactive_list or handle_list */ 199 struct list_head lru; /* inactive_list or handle_list */
200 struct raid5_private_data *raid_conf; 200 struct raid5_private_data *raid_conf;
201 short generation; /* increments with every
202 * reshape */
201 sector_t sector; /* sector of this row */ 203 sector_t sector; /* sector of this row */
202 short pd_idx; /* parity disk index */ 204 short pd_idx; /* parity disk index */
203 short qd_idx; /* 'Q' disk index for raid6 */ 205 short qd_idx; /* 'Q' disk index for raid6 */
@@ -348,6 +350,7 @@ struct raid5_private_data {
348 */ 350 */
349 sector_t reshape_safe; 351 sector_t reshape_safe;
350 int previous_raid_disks; 352 int previous_raid_disks;
353 short generation; /* increments with every reshape */
351 354
352 struct list_head handle_list; /* stripes needing handling */ 355 struct list_head handle_list; /* stripes needing handling */
353 struct list_head hold_list; /* preread ready stripes */ 356 struct list_head hold_list; /* preread ready stripes */