Commit 4d11eff6 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://neil.brown.name/md

* 'for-linus' of git://neil.brown.name/md:
  md/raid5: fix bug in reshape code when chunk_size decreases.
  md/raid5 - avoid deadlocks in get_active_stripe during reshape
  md/raid5: use conf->raid_disks in preference to mddev->raid_disk
parents 3af968e0 0e6e0271
...@@ -362,7 +362,7 @@ static void raid5_unplug_device(struct request_queue *q); ...@@ -362,7 +362,7 @@ static void raid5_unplug_device(struct request_queue *q);
static struct stripe_head * static struct stripe_head *
get_active_stripe(raid5_conf_t *conf, sector_t sector, get_active_stripe(raid5_conf_t *conf, sector_t sector,
int previous, int noblock) int previous, int noblock, int noquiesce)
{ {
struct stripe_head *sh; struct stripe_head *sh;
...@@ -372,7 +372,7 @@ get_active_stripe(raid5_conf_t *conf, sector_t sector, ...@@ -372,7 +372,7 @@ get_active_stripe(raid5_conf_t *conf, sector_t sector,
do { do {
wait_event_lock_irq(conf->wait_for_stripe, wait_event_lock_irq(conf->wait_for_stripe,
conf->quiesce == 0, conf->quiesce == 0 || noquiesce,
conf->device_lock, /* nothing */); conf->device_lock, /* nothing */);
sh = __find_stripe(conf, sector, conf->generation - previous); sh = __find_stripe(conf, sector, conf->generation - previous);
if (!sh) { if (!sh) {
...@@ -2671,7 +2671,7 @@ static void handle_stripe_expansion(raid5_conf_t *conf, struct stripe_head *sh, ...@@ -2671,7 +2671,7 @@ static void handle_stripe_expansion(raid5_conf_t *conf, struct stripe_head *sh,
sector_t bn = compute_blocknr(sh, i, 1); sector_t bn = compute_blocknr(sh, i, 1);
sector_t s = raid5_compute_sector(conf, bn, 0, sector_t s = raid5_compute_sector(conf, bn, 0,
&dd_idx, NULL); &dd_idx, NULL);
sh2 = get_active_stripe(conf, s, 0, 1); sh2 = get_active_stripe(conf, s, 0, 1, 1);
if (sh2 == NULL) if (sh2 == NULL)
/* so far only the early blocks of this stripe /* so far only the early blocks of this stripe
* have been requested. When later blocks * have been requested. When later blocks
...@@ -2944,7 +2944,7 @@ static bool handle_stripe5(struct stripe_head *sh) ...@@ -2944,7 +2944,7 @@ static bool handle_stripe5(struct stripe_head *sh)
/* Finish reconstruct operations initiated by the expansion process */ /* Finish reconstruct operations initiated by the expansion process */
if (sh->reconstruct_state == reconstruct_state_result) { if (sh->reconstruct_state == reconstruct_state_result) {
struct stripe_head *sh2 struct stripe_head *sh2
= get_active_stripe(conf, sh->sector, 1, 1); = get_active_stripe(conf, sh->sector, 1, 1, 1);
if (sh2 && test_bit(STRIPE_EXPAND_SOURCE, &sh2->state)) { if (sh2 && test_bit(STRIPE_EXPAND_SOURCE, &sh2->state)) {
/* sh cannot be written until sh2 has been read. /* sh cannot be written until sh2 has been read.
* so arrange for sh to be delayed a little * so arrange for sh to be delayed a little
...@@ -3189,7 +3189,7 @@ static bool handle_stripe6(struct stripe_head *sh, struct page *tmp_page) ...@@ -3189,7 +3189,7 @@ static bool handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
if (s.expanded && test_bit(STRIPE_EXPANDING, &sh->state)) { if (s.expanded && test_bit(STRIPE_EXPANDING, &sh->state)) {
struct stripe_head *sh2 struct stripe_head *sh2
= get_active_stripe(conf, sh->sector, 1, 1); = get_active_stripe(conf, sh->sector, 1, 1, 1);
if (sh2 && test_bit(STRIPE_EXPAND_SOURCE, &sh2->state)) { if (sh2 && test_bit(STRIPE_EXPAND_SOURCE, &sh2->state)) {
/* sh cannot be written until sh2 has been read. /* sh cannot be written until sh2 has been read.
* so arrange for sh to be delayed a little * so arrange for sh to be delayed a little
...@@ -3288,7 +3288,7 @@ static void unplug_slaves(mddev_t *mddev) ...@@ -3288,7 +3288,7 @@ static void unplug_slaves(mddev_t *mddev)
int i; int i;
rcu_read_lock(); rcu_read_lock();
for (i=0; i<mddev->raid_disks; i++) { for (i = 0; i < conf->raid_disks; i++) {
mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev); mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) { if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
struct request_queue *r_queue = bdev_get_queue(rdev->bdev); struct request_queue *r_queue = bdev_get_queue(rdev->bdev);
...@@ -3675,7 +3675,7 @@ static int make_request(struct request_queue *q, struct bio * bi) ...@@ -3675,7 +3675,7 @@ static int make_request(struct request_queue *q, struct bio * bi)
(unsigned long long)logical_sector); (unsigned long long)logical_sector);
sh = get_active_stripe(conf, new_sector, previous, sh = get_active_stripe(conf, new_sector, previous,
(bi->bi_rw&RWA_MASK)); (bi->bi_rw&RWA_MASK), 0);
if (sh) { if (sh) {
if (unlikely(previous)) { if (unlikely(previous)) {
/* expansion might have moved on while waiting for a /* expansion might have moved on while waiting for a
...@@ -3873,7 +3873,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped ...@@ -3873,7 +3873,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
for (i = 0; i < reshape_sectors; i += STRIPE_SECTORS) { for (i = 0; i < reshape_sectors; i += STRIPE_SECTORS) {
int j; int j;
int skipped = 0; int skipped = 0;
sh = get_active_stripe(conf, stripe_addr+i, 0, 0); sh = get_active_stripe(conf, stripe_addr+i, 0, 0, 1);
set_bit(STRIPE_EXPANDING, &sh->state); set_bit(STRIPE_EXPANDING, &sh->state);
atomic_inc(&conf->reshape_stripes); atomic_inc(&conf->reshape_stripes);
/* If any of this stripe is beyond the end of the old /* If any of this stripe is beyond the end of the old
...@@ -3916,13 +3916,13 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped ...@@ -3916,13 +3916,13 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
raid5_compute_sector(conf, stripe_addr*(new_data_disks), raid5_compute_sector(conf, stripe_addr*(new_data_disks),
1, &dd_idx, NULL); 1, &dd_idx, NULL);
last_sector = last_sector =
raid5_compute_sector(conf, ((stripe_addr+conf->chunk_size/512) raid5_compute_sector(conf, ((stripe_addr+reshape_sectors)
*(new_data_disks) - 1), *(new_data_disks) - 1),
1, &dd_idx, NULL); 1, &dd_idx, NULL);
if (last_sector >= mddev->dev_sectors) if (last_sector >= mddev->dev_sectors)
last_sector = mddev->dev_sectors - 1; last_sector = mddev->dev_sectors - 1;
while (first_sector <= last_sector) { while (first_sector <= last_sector) {
sh = get_active_stripe(conf, first_sector, 1, 0); sh = get_active_stripe(conf, first_sector, 1, 0, 1);
set_bit(STRIPE_EXPAND_SOURCE, &sh->state); set_bit(STRIPE_EXPAND_SOURCE, &sh->state);
set_bit(STRIPE_HANDLE, &sh->state); set_bit(STRIPE_HANDLE, &sh->state);
release_stripe(sh); release_stripe(sh);
...@@ -4022,9 +4022,9 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski ...@@ -4022,9 +4022,9 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
bitmap_cond_end_sync(mddev->bitmap, sector_nr); bitmap_cond_end_sync(mddev->bitmap, sector_nr);
sh = get_active_stripe(conf, sector_nr, 0, 1); sh = get_active_stripe(conf, sector_nr, 0, 1, 0);
if (sh == NULL) { if (sh == NULL) {
sh = get_active_stripe(conf, sector_nr, 0, 0); sh = get_active_stripe(conf, sector_nr, 0, 0, 0);
/* make sure we don't swamp the stripe cache if someone else /* make sure we don't swamp the stripe cache if someone else
* is trying to get access * is trying to get access
*/ */
...@@ -4034,7 +4034,7 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski ...@@ -4034,7 +4034,7 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
* We don't need to check the 'failed' flag as when that gets set, * We don't need to check the 'failed' flag as when that gets set,
* recovery aborts. * recovery aborts.
*/ */
for (i=0; i<mddev->raid_disks; i++) for (i = 0; i < conf->raid_disks; i++)
if (conf->disks[i].rdev == NULL) if (conf->disks[i].rdev == NULL)
still_degraded = 1; still_degraded = 1;
...@@ -4086,7 +4086,7 @@ static int retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio) ...@@ -4086,7 +4086,7 @@ static int retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio)
/* already done this stripe */ /* already done this stripe */
continue; continue;
sh = get_active_stripe(conf, sector, 0, 1); sh = get_active_stripe(conf, sector, 0, 1, 0);
if (!sh) { if (!sh) {
/* failed to get a stripe - must wait */ /* failed to get a stripe - must wait */
......
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