diff options
Diffstat (limited to 'drivers/md/raid5.c')
| -rw-r--r-- | drivers/md/raid5.c | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 40e939675657..224de022e7c5 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
| @@ -2568,10 +2568,10 @@ static bool handle_stripe5(struct stripe_head *sh) | |||
| 2568 | if (dev->written) | 2568 | if (dev->written) |
| 2569 | s.written++; | 2569 | s.written++; |
| 2570 | rdev = rcu_dereference(conf->disks[i].rdev); | 2570 | rdev = rcu_dereference(conf->disks[i].rdev); |
| 2571 | if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) { | 2571 | if (blocked_rdev == NULL && |
| 2572 | rdev && unlikely(test_bit(Blocked, &rdev->flags))) { | ||
| 2572 | blocked_rdev = rdev; | 2573 | blocked_rdev = rdev; |
| 2573 | atomic_inc(&rdev->nr_pending); | 2574 | atomic_inc(&rdev->nr_pending); |
| 2574 | break; | ||
| 2575 | } | 2575 | } |
| 2576 | if (!rdev || !test_bit(In_sync, &rdev->flags)) { | 2576 | if (!rdev || !test_bit(In_sync, &rdev->flags)) { |
| 2577 | /* The ReadError flag will just be confusing now */ | 2577 | /* The ReadError flag will just be confusing now */ |
| @@ -2588,8 +2588,14 @@ static bool handle_stripe5(struct stripe_head *sh) | |||
| 2588 | rcu_read_unlock(); | 2588 | rcu_read_unlock(); |
| 2589 | 2589 | ||
| 2590 | if (unlikely(blocked_rdev)) { | 2590 | if (unlikely(blocked_rdev)) { |
| 2591 | set_bit(STRIPE_HANDLE, &sh->state); | 2591 | if (s.syncing || s.expanding || s.expanded || |
| 2592 | goto unlock; | 2592 | s.to_write || s.written) { |
| 2593 | set_bit(STRIPE_HANDLE, &sh->state); | ||
| 2594 | goto unlock; | ||
| 2595 | } | ||
| 2596 | /* There is nothing for the blocked_rdev to block */ | ||
| 2597 | rdev_dec_pending(blocked_rdev, conf->mddev); | ||
| 2598 | blocked_rdev = NULL; | ||
| 2593 | } | 2599 | } |
| 2594 | 2600 | ||
| 2595 | if (s.to_fill && !test_bit(STRIPE_BIOFILL_RUN, &sh->state)) { | 2601 | if (s.to_fill && !test_bit(STRIPE_BIOFILL_RUN, &sh->state)) { |
| @@ -2832,10 +2838,10 @@ static bool handle_stripe6(struct stripe_head *sh, struct page *tmp_page) | |||
| 2832 | if (dev->written) | 2838 | if (dev->written) |
| 2833 | s.written++; | 2839 | s.written++; |
| 2834 | rdev = rcu_dereference(conf->disks[i].rdev); | 2840 | rdev = rcu_dereference(conf->disks[i].rdev); |
| 2835 | if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) { | 2841 | if (blocked_rdev == NULL && |
| 2842 | rdev && unlikely(test_bit(Blocked, &rdev->flags))) { | ||
| 2836 | blocked_rdev = rdev; | 2843 | blocked_rdev = rdev; |
| 2837 | atomic_inc(&rdev->nr_pending); | 2844 | atomic_inc(&rdev->nr_pending); |
| 2838 | break; | ||
| 2839 | } | 2845 | } |
| 2840 | if (!rdev || !test_bit(In_sync, &rdev->flags)) { | 2846 | if (!rdev || !test_bit(In_sync, &rdev->flags)) { |
| 2841 | /* The ReadError flag will just be confusing now */ | 2847 | /* The ReadError flag will just be confusing now */ |
| @@ -2853,9 +2859,16 @@ static bool handle_stripe6(struct stripe_head *sh, struct page *tmp_page) | |||
| 2853 | rcu_read_unlock(); | 2859 | rcu_read_unlock(); |
| 2854 | 2860 | ||
| 2855 | if (unlikely(blocked_rdev)) { | 2861 | if (unlikely(blocked_rdev)) { |
| 2856 | set_bit(STRIPE_HANDLE, &sh->state); | 2862 | if (s.syncing || s.expanding || s.expanded || |
| 2857 | goto unlock; | 2863 | s.to_write || s.written) { |
| 2864 | set_bit(STRIPE_HANDLE, &sh->state); | ||
| 2865 | goto unlock; | ||
| 2866 | } | ||
| 2867 | /* There is nothing for the blocked_rdev to block */ | ||
| 2868 | rdev_dec_pending(blocked_rdev, conf->mddev); | ||
| 2869 | blocked_rdev = NULL; | ||
| 2858 | } | 2870 | } |
| 2871 | |||
| 2859 | pr_debug("locked=%d uptodate=%d to_read=%d" | 2872 | pr_debug("locked=%d uptodate=%d to_read=%d" |
| 2860 | " to_write=%d failed=%d failed_num=%d,%d\n", | 2873 | " to_write=%d failed=%d failed_num=%d,%d\n", |
| 2861 | s.locked, s.uptodate, s.to_read, s.to_write, s.failed, | 2874 | s.locked, s.uptodate, s.to_read, s.to_write, s.failed, |
| @@ -4446,6 +4459,9 @@ static int raid5_check_reshape(mddev_t *mddev) | |||
| 4446 | return -EINVAL; /* Cannot shrink array or change level yet */ | 4459 | return -EINVAL; /* Cannot shrink array or change level yet */ |
| 4447 | if (mddev->delta_disks == 0) | 4460 | if (mddev->delta_disks == 0) |
| 4448 | return 0; /* nothing to do */ | 4461 | return 0; /* nothing to do */ |
| 4462 | if (mddev->bitmap) | ||
| 4463 | /* Cannot grow a bitmap yet */ | ||
| 4464 | return -EBUSY; | ||
| 4449 | 4465 | ||
| 4450 | /* Can only proceed if there are plenty of stripe_heads. | 4466 | /* Can only proceed if there are plenty of stripe_heads. |
| 4451 | * We need a minimum of one full stripe,, and for sensible progress | 4467 | * We need a minimum of one full stripe,, and for sensible progress |
