diff options
author | Dan Williams <dan.j.williams@intel.com> | 2008-07-29 02:10:39 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2008-07-28 20:52:37 -0400 |
commit | df10cfbc4d7ab93260d997df754219d390d62a9d (patch) | |
tree | 23908d827de85f16f9404875859e51babb966856 /drivers | |
parent | d8e64406a037a64444175730294e449c9e21f5ec (diff) |
md: do not progress the resync process if the stripe was blocked
handle_stripe will take no action on a stripe when waiting for userspace
to unblock the array, so do not report completed sectors.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/md/raid5.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 46132fca3469..b428e15d59af 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 | ||
2510 | static void handle_stripe5(struct stripe_head *sh) | 2510 | static 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; |
@@ -2755,9 +2755,11 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2755 | ops_run_io(sh, &s); | 2755 | ops_run_io(sh, &s); |
2756 | 2756 | ||
2757 | return_io(return_bi); | 2757 | return_io(return_bi); |
2758 | |||
2759 | return blocked_rdev == NULL; | ||
2758 | } | 2760 | } |
2759 | 2761 | ||
2760 | static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page) | 2762 | static bool handle_stripe6(struct stripe_head *sh, struct page *tmp_page) |
2761 | { | 2763 | { |
2762 | raid6_conf_t *conf = sh->raid_conf; | 2764 | raid6_conf_t *conf = sh->raid_conf; |
2763 | int disks = sh->disks; | 2765 | int disks = sh->disks; |
@@ -2968,14 +2970,17 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page) | |||
2968 | ops_run_io(sh, &s); | 2970 | ops_run_io(sh, &s); |
2969 | 2971 | ||
2970 | return_io(return_bi); | 2972 | return_io(return_bi); |
2973 | |||
2974 | return blocked_rdev == NULL; | ||
2971 | } | 2975 | } |
2972 | 2976 | ||
2973 | static void handle_stripe(struct stripe_head *sh, struct page *tmp_page) | 2977 | /* returns true if the stripe was handled */ |
2978 | static bool handle_stripe(struct stripe_head *sh, struct page *tmp_page) | ||
2974 | { | 2979 | { |
2975 | if (sh->raid_conf->level == 6) | 2980 | if (sh->raid_conf->level == 6) |
2976 | handle_stripe6(sh, tmp_page); | 2981 | return handle_stripe6(sh, tmp_page); |
2977 | else | 2982 | else |
2978 | handle_stripe5(sh); | 2983 | return handle_stripe5(sh); |
2979 | } | 2984 | } |
2980 | 2985 | ||
2981 | 2986 | ||
@@ -3691,7 +3696,9 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski | |||
3691 | clear_bit(STRIPE_INSYNC, &sh->state); | 3696 | clear_bit(STRIPE_INSYNC, &sh->state); |
3692 | spin_unlock(&sh->lock); | 3697 | spin_unlock(&sh->lock); |
3693 | 3698 | ||
3694 | handle_stripe(sh, NULL); | 3699 | /* wait for any blocked device to be handled */ |
3700 | while(unlikely(!handle_stripe(sh, NULL))) | ||
3701 | ; | ||
3695 | release_stripe(sh); | 3702 | release_stripe(sh); |
3696 | 3703 | ||
3697 | return STRIPE_SECTORS; | 3704 | return STRIPE_SECTORS; |