aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid5.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-08-01 14:56:07 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-08-01 14:56:07 -0400
commit1e24b15b267293567a8d752721c7ae63f281325a (patch)
treeee63644d2dc59899e42ec0802c201140e3a92e5e /drivers/md/raid5.c
parent63a16f90167850010864a9e8ebb71d216983090f (diff)
parent388667bed591b2359713bb17d5de0cf56e961447 (diff)
Merge branch 'for-linus' of git://neil.brown.name/md
* 'for-linus' of git://neil.brown.name/md: md: raid10: wake up frozen array md: do not count blocked devices as spares md: do not progress the resync process if the stripe was blocked md: delay notification of 'active_idle' to the recovery thread md: fix merge error md: move async_tx_issue_pending_all outside spin_lock_irq
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r--drivers/md/raid5.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 55e7c56045a..40e93967565 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -2507,7 +2507,7 @@ static void handle_stripe_expansion(raid5_conf_t *conf, struct stripe_head *sh,
2507 * 2507 *
2508 */ 2508 */
2509 2509
2510static void handle_stripe5(struct stripe_head *sh) 2510static bool handle_stripe5(struct stripe_head *sh)
2511{ 2511{
2512 raid5_conf_t *conf = sh->raid_conf; 2512 raid5_conf_t *conf = sh->raid_conf;
2513 int disks = sh->disks, i; 2513 int disks = sh->disks, i;
@@ -2717,10 +2717,11 @@ static void handle_stripe5(struct stripe_head *sh)
2717 if (sh->reconstruct_state == reconstruct_state_result) { 2717 if (sh->reconstruct_state == reconstruct_state_result) {
2718 sh->reconstruct_state = reconstruct_state_idle; 2718 sh->reconstruct_state = reconstruct_state_idle;
2719 clear_bit(STRIPE_EXPANDING, &sh->state); 2719 clear_bit(STRIPE_EXPANDING, &sh->state);
2720 for (i = conf->raid_disks; i--; ) 2720 for (i = conf->raid_disks; i--; ) {
2721 set_bit(R5_Wantwrite, &sh->dev[i].flags); 2721 set_bit(R5_Wantwrite, &sh->dev[i].flags);
2722 set_bit(R5_LOCKED, &dev->flags); 2722 set_bit(R5_LOCKED, &sh->dev[i].flags);
2723 s.locked++; 2723 s.locked++;
2724 }
2724 } 2725 }
2725 2726
2726 if (s.expanded && test_bit(STRIPE_EXPANDING, &sh->state) && 2727 if (s.expanded && test_bit(STRIPE_EXPANDING, &sh->state) &&
@@ -2754,9 +2755,11 @@ static void handle_stripe5(struct stripe_head *sh)
2754 ops_run_io(sh, &s); 2755 ops_run_io(sh, &s);
2755 2756
2756 return_io(return_bi); 2757 return_io(return_bi);
2758
2759 return blocked_rdev == NULL;
2757} 2760}
2758 2761
2759static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page) 2762static bool handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
2760{ 2763{
2761 raid6_conf_t *conf = sh->raid_conf; 2764 raid6_conf_t *conf = sh->raid_conf;
2762 int disks = sh->disks; 2765 int disks = sh->disks;
@@ -2967,14 +2970,17 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
2967 ops_run_io(sh, &s); 2970 ops_run_io(sh, &s);
2968 2971
2969 return_io(return_bi); 2972 return_io(return_bi);
2973
2974 return blocked_rdev == NULL;
2970} 2975}
2971 2976
2972static void handle_stripe(struct stripe_head *sh, struct page *tmp_page) 2977/* returns true if the stripe was handled */
2978static bool handle_stripe(struct stripe_head *sh, struct page *tmp_page)
2973{ 2979{
2974 if (sh->raid_conf->level == 6) 2980 if (sh->raid_conf->level == 6)
2975 handle_stripe6(sh, tmp_page); 2981 return handle_stripe6(sh, tmp_page);
2976 else 2982 else
2977 handle_stripe5(sh); 2983 return handle_stripe5(sh);
2978} 2984}
2979 2985
2980 2986
@@ -3692,7 +3698,9 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
3692 clear_bit(STRIPE_INSYNC, &sh->state); 3698 clear_bit(STRIPE_INSYNC, &sh->state);
3693 spin_unlock(&sh->lock); 3699 spin_unlock(&sh->lock);
3694 3700
3695 handle_stripe(sh, NULL); 3701 /* wait for any blocked device to be handled */
3702 while(unlikely(!handle_stripe(sh, NULL)))
3703 ;
3696 release_stripe(sh); 3704 release_stripe(sh);
3697 3705
3698 return STRIPE_SECTORS; 3706 return STRIPE_SECTORS;
@@ -3811,10 +3819,8 @@ static void raid5d(mddev_t *mddev)
3811 3819
3812 sh = __get_priority_stripe(conf); 3820 sh = __get_priority_stripe(conf);
3813 3821
3814 if (!sh) { 3822 if (!sh)
3815 async_tx_issue_pending_all();
3816 break; 3823 break;
3817 }
3818 spin_unlock_irq(&conf->device_lock); 3824 spin_unlock_irq(&conf->device_lock);
3819 3825
3820 handled++; 3826 handled++;
@@ -3827,6 +3833,7 @@ static void raid5d(mddev_t *mddev)
3827 3833
3828 spin_unlock_irq(&conf->device_lock); 3834 spin_unlock_irq(&conf->device_lock);
3829 3835
3836 async_tx_issue_pending_all();
3830 unplug_slaves(mddev); 3837 unplug_slaves(mddev);
3831 3838
3832 pr_debug("--- raid5d inactive\n"); 3839 pr_debug("--- raid5d inactive\n");