aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-07-26 21:00:36 -0400
committerNeilBrown <neilb@suse.de>2011-07-26 21:00:36 -0400
commit474af965fe0005b334cabdb2904a7d712c21489b (patch)
tree1d63b4bbe47e2976dd10e7fa4674299b58efc45a /drivers
parent84789554e96c0263ad8aa9be91397ece1f88c768 (diff)
md/raid5: move some more common code into handle_stripe
The RAID6 version of this code is usable for RAID5 providing: - we test "conf->max_degraded" rather than "2" as appropriate - we make sure s->failed_num[1] is meaningful (and not '-1') when s->failed > 1 The 'return 1' must become 'goto finish' in the new location. Signed-off-by: NeilBrown <neilb@suse.de> Reviewed-by: Namhyung Kim <namhyung@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/md/raid5.c180
1 files changed, 67 insertions, 113 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index cf60b15b4e3a..63acc51e8406 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -2968,63 +2968,14 @@ static int handle_stripe5(struct stripe_head *sh, struct stripe_head_state *s)
2968 if (test_bit(R5_ReadError, &dev->flags)) 2968 if (test_bit(R5_ReadError, &dev->flags))
2969 clear_bit(R5_Insync, &dev->flags); 2969 clear_bit(R5_Insync, &dev->flags);
2970 if (!test_bit(R5_Insync, &dev->flags)) { 2970 if (!test_bit(R5_Insync, &dev->flags)) {
2971 if (s->failed < 2)
2972 s->failed_num[s->failed] = i;
2971 s->failed++; 2973 s->failed++;
2972 s->failed_num[0] = i;
2973 } 2974 }
2974 } 2975 }
2975 spin_unlock_irq(&conf->device_lock); 2976 spin_unlock_irq(&conf->device_lock);
2976 rcu_read_unlock(); 2977 rcu_read_unlock();
2977 2978
2978 if (unlikely(s->blocked_rdev)) {
2979 if (s->syncing || s->expanding || s->expanded ||
2980 s->to_write || s->written) {
2981 set_bit(STRIPE_HANDLE, &sh->state);
2982 return 1;
2983 }
2984 /* There is nothing for the blocked_rdev to block */
2985 rdev_dec_pending(s->blocked_rdev, conf->mddev);
2986 s->blocked_rdev = NULL;
2987 }
2988
2989 if (s->to_fill && !test_bit(STRIPE_BIOFILL_RUN, &sh->state)) {
2990 set_bit(STRIPE_OP_BIOFILL, &s->ops_request);
2991 set_bit(STRIPE_BIOFILL_RUN, &sh->state);
2992 }
2993
2994 pr_debug("locked=%d uptodate=%d to_read=%d"
2995 " to_write=%d failed=%d failed_num=%d\n",
2996 s->locked, s->uptodate, s->to_read, s->to_write,
2997 s->failed, s->failed_num[0]);
2998 /* check if the array has lost two devices and, if so, some requests might
2999 * need to be failed
3000 */
3001 if (s->failed > 1 && s->to_read+s->to_write+s->written)
3002 handle_failed_stripe(conf, sh, s, disks, &s->return_bi);
3003 if (s->failed > 1 && s->syncing) {
3004 md_done_sync(conf->mddev, STRIPE_SECTORS,0);
3005 clear_bit(STRIPE_SYNCING, &sh->state);
3006 s->syncing = 0;
3007 }
3008
3009 /* might be able to return some write requests if the parity block
3010 * is safe, or on a failed drive
3011 */
3012 dev = &sh->dev[sh->pd_idx];
3013 if (s->written &&
3014 ((test_bit(R5_Insync, &dev->flags) &&
3015 !test_bit(R5_LOCKED, &dev->flags) &&
3016 test_bit(R5_UPTODATE, &dev->flags)) ||
3017 (s->failed == 1 && s->failed_num[0] == sh->pd_idx)))
3018 handle_stripe_clean_event(conf, sh, disks, &s->return_bi);
3019
3020 /* Now we might consider reading some blocks, either to check/generate
3021 * parity, or to satisfy requests
3022 * or to load a block that is being partially written.
3023 */
3024 if (s->to_read || s->non_overwrite ||
3025 (s->syncing && (s->uptodate + s->compute < disks)) || s->expanding)
3026 handle_stripe_fill(sh, s, disks);
3027
3028 return 0; 2979 return 0;
3029} 2980}
3030 2981
@@ -3032,8 +2983,8 @@ static int handle_stripe6(struct stripe_head *sh, struct stripe_head_state *s)
3032{ 2983{
3033 raid5_conf_t *conf = sh->raid_conf; 2984 raid5_conf_t *conf = sh->raid_conf;
3034 int disks = sh->disks; 2985 int disks = sh->disks;
3035 int i, pd_idx = sh->pd_idx, qd_idx = sh->qd_idx; 2986 struct r5dev *dev;
3036 struct r5dev *dev, *pdev, *qdev; 2987 int i;
3037 2988
3038 /* Now to look around and see what can be done */ 2989 /* Now to look around and see what can be done */
3039 2990
@@ -3107,65 +3058,6 @@ static int handle_stripe6(struct stripe_head *sh, struct stripe_head_state *s)
3107 spin_unlock_irq(&conf->device_lock); 3058 spin_unlock_irq(&conf->device_lock);
3108 rcu_read_unlock(); 3059 rcu_read_unlock();
3109 3060
3110 if (unlikely(s->blocked_rdev)) {
3111 if (s->syncing || s->expanding || s->expanded ||
3112 s->to_write || s->written) {
3113 set_bit(STRIPE_HANDLE, &sh->state);
3114 return 1;
3115 }
3116 /* There is nothing for the blocked_rdev to block */
3117 rdev_dec_pending(s->blocked_rdev, conf->mddev);
3118 s->blocked_rdev = NULL;
3119 }
3120
3121 if (s->to_fill && !test_bit(STRIPE_BIOFILL_RUN, &sh->state)) {
3122 set_bit(STRIPE_OP_BIOFILL, &s->ops_request);
3123 set_bit(STRIPE_BIOFILL_RUN, &sh->state);
3124 }
3125
3126 pr_debug("locked=%d uptodate=%d to_read=%d"
3127 " to_write=%d failed=%d failed_num=%d,%d\n",
3128 s->locked, s->uptodate, s->to_read, s->to_write, s->failed,
3129 s->failed_num[0], s->failed_num[1]);
3130 /* check if the array has lost >2 devices and, if so, some requests
3131 * might need to be failed
3132 */
3133 if (s->failed > 2 && s->to_read+s->to_write+s->written)
3134 handle_failed_stripe(conf, sh, s, disks, &s->return_bi);
3135 if (s->failed > 2 && s->syncing) {
3136 md_done_sync(conf->mddev, STRIPE_SECTORS,0);
3137 clear_bit(STRIPE_SYNCING, &sh->state);
3138 s->syncing = 0;
3139 }
3140
3141 /*
3142 * might be able to return some write requests if the parity blocks
3143 * are safe, or on a failed drive
3144 */
3145 pdev = &sh->dev[pd_idx];
3146 s->p_failed = (s->failed >= 1 && s->failed_num[0] == pd_idx)
3147 || (s->failed >= 2 && s->failed_num[1] == pd_idx);
3148 qdev = &sh->dev[qd_idx];
3149 s->q_failed = (s->failed >= 1 && s->failed_num[0] == qd_idx)
3150 || (s->failed >= 2 && s->failed_num[1] == qd_idx);
3151
3152 if (s->written &&
3153 (s->p_failed || ((test_bit(R5_Insync, &pdev->flags)
3154 && !test_bit(R5_LOCKED, &pdev->flags)
3155 && test_bit(R5_UPTODATE, &pdev->flags)))) &&
3156 (s->q_failed || ((test_bit(R5_Insync, &qdev->flags)
3157 && !test_bit(R5_LOCKED, &qdev->flags)
3158 && test_bit(R5_UPTODATE, &qdev->flags)))))
3159 handle_stripe_clean_event(conf, sh, disks, &s->return_bi);
3160
3161 /* Now we might consider reading some blocks, either to check/generate
3162 * parity, or to satisfy requests
3163 * or to load a block that is being partially written.
3164 */
3165 if (s->to_read || s->non_overwrite || (s->to_write && s->failed) ||
3166 (s->syncing && (s->uptodate + s->compute < disks)) || s->expanding)
3167 handle_stripe_fill(sh, s, disks);
3168
3169 return 0; 3061 return 0;
3170} 3062}
3171 3063
@@ -3173,10 +3065,11 @@ static void handle_stripe(struct stripe_head *sh)
3173{ 3065{
3174 struct stripe_head_state s; 3066 struct stripe_head_state s;
3175 int done; 3067 int done;
3068 raid5_conf_t *conf = sh->raid_conf;
3176 int i; 3069 int i;
3177 int prexor; 3070 int prexor;
3178 int disks = sh->disks; 3071 int disks = sh->disks;
3179 raid5_conf_t *conf = sh->raid_conf; 3072 struct r5dev *pdev, *qdev;
3180 3073
3181 clear_bit(STRIPE_HANDLE, &sh->state); 3074 clear_bit(STRIPE_HANDLE, &sh->state);
3182 if (test_and_set_bit(STRIPE_ACTIVE, &sh->state)) { 3075 if (test_and_set_bit(STRIPE_ACTIVE, &sh->state)) {
@@ -3213,6 +3106,67 @@ static void handle_stripe(struct stripe_head *sh)
3213 if (done) 3106 if (done)
3214 goto finish; 3107 goto finish;
3215 3108
3109 if (unlikely(s.blocked_rdev)) {
3110 if (s.syncing || s.expanding || s.expanded ||
3111 s.to_write || s.written) {
3112 set_bit(STRIPE_HANDLE, &sh->state);
3113 goto finish;
3114 }
3115 /* There is nothing for the blocked_rdev to block */
3116 rdev_dec_pending(s.blocked_rdev, conf->mddev);
3117 s.blocked_rdev = NULL;
3118 }
3119
3120 if (s.to_fill && !test_bit(STRIPE_BIOFILL_RUN, &sh->state)) {
3121 set_bit(STRIPE_OP_BIOFILL, &s.ops_request);
3122 set_bit(STRIPE_BIOFILL_RUN, &sh->state);
3123 }
3124
3125 pr_debug("locked=%d uptodate=%d to_read=%d"
3126 " to_write=%d failed=%d failed_num=%d,%d\n",
3127 s.locked, s.uptodate, s.to_read, s.to_write, s.failed,
3128 s.failed_num[0], s.failed_num[1]);
3129 /* check if the array has lost more than max_degraded devices and,
3130 * if so, some requests might need to be failed.
3131 */
3132 if (s.failed > conf->max_degraded && s.to_read+s.to_write+s.written)
3133 handle_failed_stripe(conf, sh, &s, disks, &s.return_bi);
3134 if (s.failed > conf->max_degraded && s.syncing) {
3135 md_done_sync(conf->mddev, STRIPE_SECTORS, 0);
3136 clear_bit(STRIPE_SYNCING, &sh->state);
3137 s.syncing = 0;
3138 }
3139
3140 /*
3141 * might be able to return some write requests if the parity blocks
3142 * are safe, or on a failed drive
3143 */
3144 pdev = &sh->dev[sh->pd_idx];
3145 s.p_failed = (s.failed >= 1 && s.failed_num[0] == sh->pd_idx)
3146 || (s.failed >= 2 && s.failed_num[1] == sh->pd_idx);
3147 qdev = &sh->dev[sh->qd_idx];
3148 s.q_failed = (s.failed >= 1 && s.failed_num[0] == sh->qd_idx)
3149 || (s.failed >= 2 && s.failed_num[1] == sh->qd_idx)
3150 || conf->level < 6;
3151
3152 if (s.written &&
3153 (s.p_failed || ((test_bit(R5_Insync, &pdev->flags)
3154 && !test_bit(R5_LOCKED, &pdev->flags)
3155 && test_bit(R5_UPTODATE, &pdev->flags)))) &&
3156 (s.q_failed || ((test_bit(R5_Insync, &qdev->flags)
3157 && !test_bit(R5_LOCKED, &qdev->flags)
3158 && test_bit(R5_UPTODATE, &qdev->flags)))))
3159 handle_stripe_clean_event(conf, sh, disks, &s.return_bi);
3160
3161 /* Now we might consider reading some blocks, either to check/generate
3162 * parity, or to satisfy requests
3163 * or to load a block that is being partially written.
3164 */
3165 if (s.to_read || s.non_overwrite
3166 || (conf->level == 6 && s.to_write && s.failed)
3167 || (s.syncing && (s.uptodate + s.compute < disks)) || s.expanding)
3168 handle_stripe_fill(sh, &s, disks);
3169
3216 /* Now we check to see if any write operations have recently 3170 /* Now we check to see if any write operations have recently
3217 * completed 3171 * completed
3218 */ 3172 */