aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid5.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r--drivers/md/raid5.c107
1 files changed, 23 insertions, 84 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index a3d7cd96cfb7..a63a679105ca 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -2308,91 +2308,20 @@ handle_failed_stripe(raid5_conf_t *conf, struct stripe_head *sh,
2308 md_wakeup_thread(conf->mddev->thread); 2308 md_wakeup_thread(conf->mddev->thread);
2309} 2309}
2310 2310
2311/* fetch_block5 - checks the given member device to see if its data needs 2311/* fetch_block - checks the given member device to see if its data needs
2312 * to be read or computed to satisfy a request. 2312 * to be read or computed to satisfy a request.
2313 * 2313 *
2314 * Returns 1 when no more member devices need to be checked, otherwise returns 2314 * Returns 1 when no more member devices need to be checked, otherwise returns
2315 * 0 to tell the loop in handle_stripe_fill5 to continue 2315 * 0 to tell the loop in handle_stripe_fill to continue
2316 */ 2316 */
2317static int fetch_block5(struct stripe_head *sh, struct stripe_head_state *s, 2317static int fetch_block(struct stripe_head *sh, struct stripe_head_state *s,
2318 int disk_idx, int disks) 2318 int disk_idx, int disks)
2319{
2320 struct r5dev *dev = &sh->dev[disk_idx];
2321 struct r5dev *failed_dev = &sh->dev[s->failed_num[0]];
2322
2323 /* is the data in this block needed, and can we get it? */
2324 if (!test_bit(R5_LOCKED, &dev->flags) &&
2325 !test_bit(R5_UPTODATE, &dev->flags) &&
2326 (dev->toread ||
2327 (dev->towrite && !test_bit(R5_OVERWRITE, &dev->flags)) ||
2328 s->syncing || s->expanding ||
2329 (s->failed && failed_dev->toread) ||
2330 (s->failed && failed_dev->towrite &&
2331 !test_bit(R5_OVERWRITE, &failed_dev->flags)))))) {
2332 /* We would like to get this block, possibly by computing it,
2333 * otherwise read it if the backing disk is insync
2334 */
2335 if ((s->uptodate == disks - 1) &&
2336 (s->failed && disk_idx == s->failed_num[0])) {
2337 set_bit(STRIPE_COMPUTE_RUN, &sh->state);
2338 set_bit(STRIPE_OP_COMPUTE_BLK, &s->ops_request);
2339 set_bit(R5_Wantcompute, &dev->flags);
2340 sh->ops.target = disk_idx;
2341 sh->ops.target2 = -1;
2342 s->req_compute = 1;
2343 /* Careful: from this point on 'uptodate' is in the eye
2344 * of raid_run_ops which services 'compute' operations
2345 * before writes. R5_Wantcompute flags a block that will
2346 * be R5_UPTODATE by the time it is needed for a
2347 * subsequent operation.
2348 */
2349 s->uptodate++;
2350 return 1; /* uptodate + compute == disks */
2351 } else if (test_bit(R5_Insync, &dev->flags)) {
2352 set_bit(R5_LOCKED, &dev->flags);
2353 set_bit(R5_Wantread, &dev->flags);
2354 s->locked++;
2355 pr_debug("Reading block %d (sync=%d)\n", disk_idx,
2356 s->syncing);
2357 }
2358 }
2359
2360 return 0;
2361}
2362
2363/**
2364 * handle_stripe_fill5 - read or compute data to satisfy pending requests.
2365 */
2366static void handle_stripe_fill5(struct stripe_head *sh,
2367 struct stripe_head_state *s, int disks)
2368{
2369 int i;
2370
2371 /* look for blocks to read/compute, skip this if a compute
2372 * is already in flight, or if the stripe contents are in the
2373 * midst of changing due to a write
2374 */
2375 if (!test_bit(STRIPE_COMPUTE_RUN, &sh->state) && !sh->check_state &&
2376 !sh->reconstruct_state)
2377 for (i = disks; i--; )
2378 if (fetch_block5(sh, s, i, disks))
2379 break;
2380 set_bit(STRIPE_HANDLE, &sh->state);
2381}
2382
2383/* fetch_block6 - checks the given member device to see if its data needs
2384 * to be read or computed to satisfy a request.
2385 *
2386 * Returns 1 when no more member devices need to be checked, otherwise returns
2387 * 0 to tell the loop in handle_stripe_fill6 to continue
2388 */
2389static int fetch_block6(struct stripe_head *sh, struct stripe_head_state *s,
2390 int disk_idx, int disks)
2391{ 2319{
2392 struct r5dev *dev = &sh->dev[disk_idx]; 2320 struct r5dev *dev = &sh->dev[disk_idx];
2393 struct r5dev *fdev[2] = { &sh->dev[s->failed_num[0]], 2321 struct r5dev *fdev[2] = { &sh->dev[s->failed_num[0]],
2394 &sh->dev[s->failed_num[1]] }; 2322 &sh->dev[s->failed_num[1]] };
2395 2323
2324 /* is the data in this block needed, and can we get it? */
2396 if (!test_bit(R5_LOCKED, &dev->flags) && 2325 if (!test_bit(R5_LOCKED, &dev->flags) &&
2397 !test_bit(R5_UPTODATE, &dev->flags) && 2326 !test_bit(R5_UPTODATE, &dev->flags) &&
2398 (dev->toread || 2327 (dev->toread ||
@@ -2400,7 +2329,9 @@ static int fetch_block6(struct stripe_head *sh, struct stripe_head_state *s,
2400 s->syncing || s->expanding || 2329 s->syncing || s->expanding ||
2401 (s->failed >= 1 && fdev[0]->toread) || 2330 (s->failed >= 1 && fdev[0]->toread) ||
2402 (s->failed >= 2 && fdev[1]->toread) || 2331 (s->failed >= 2 && fdev[1]->toread) ||
2403 (s->failed && s->to_write)) { 2332 (sh->raid_conf->level <= 5 && s->failed && fdev[0]->towrite &&
2333 !test_bit(R5_OVERWRITE, &fdev[0]->flags)) ||
2334 (sh->raid_conf->level == 6 && s->failed && s->to_write))) {
2404 /* we would like to get this block, possibly by computing it, 2335 /* we would like to get this block, possibly by computing it,
2405 * otherwise read it if the backing disk is insync 2336 * otherwise read it if the backing disk is insync
2406 */ 2337 */
@@ -2420,6 +2351,12 @@ static int fetch_block6(struct stripe_head *sh, struct stripe_head_state *s,
2420 sh->ops.target = disk_idx; 2351 sh->ops.target = disk_idx;
2421 sh->ops.target2 = -1; /* no 2nd target */ 2352 sh->ops.target2 = -1; /* no 2nd target */
2422 s->req_compute = 1; 2353 s->req_compute = 1;
2354 /* Careful: from this point on 'uptodate' is in the eye
2355 * of raid_run_ops which services 'compute' operations
2356 * before writes. R5_Wantcompute flags a block that will
2357 * be R5_UPTODATE by the time it is needed for a
2358 * subsequent operation.
2359 */
2423 s->uptodate++; 2360 s->uptodate++;
2424 return 1; 2361 return 1;
2425 } else if (s->uptodate == disks-2 && s->failed >= 2) { 2362 } else if (s->uptodate == disks-2 && s->failed >= 2) {
@@ -2460,11 +2397,11 @@ static int fetch_block6(struct stripe_head *sh, struct stripe_head_state *s,
2460} 2397}
2461 2398
2462/** 2399/**
2463 * handle_stripe_fill6 - read or compute data to satisfy pending requests. 2400 * handle_stripe_fill - read or compute data to satisfy pending requests.
2464 */ 2401 */
2465static void handle_stripe_fill6(struct stripe_head *sh, 2402static void handle_stripe_fill(struct stripe_head *sh,
2466 struct stripe_head_state *s, 2403 struct stripe_head_state *s,
2467 int disks) 2404 int disks)
2468{ 2405{
2469 int i; 2406 int i;
2470 2407
@@ -2475,7 +2412,7 @@ static void handle_stripe_fill6(struct stripe_head *sh,
2475 if (!test_bit(STRIPE_COMPUTE_RUN, &sh->state) && !sh->check_state && 2412 if (!test_bit(STRIPE_COMPUTE_RUN, &sh->state) && !sh->check_state &&
2476 !sh->reconstruct_state) 2413 !sh->reconstruct_state)
2477 for (i = disks; i--; ) 2414 for (i = disks; i--; )
2478 if (fetch_block6(sh, s, i, disks)) 2415 if (fetch_block(sh, s, i, disks))
2479 break; 2416 break;
2480 set_bit(STRIPE_HANDLE, &sh->state); 2417 set_bit(STRIPE_HANDLE, &sh->state);
2481} 2418}
@@ -3122,7 +3059,7 @@ static int handle_stripe5(struct stripe_head *sh, struct stripe_head_state *s)
3122 */ 3059 */
3123 if (s->to_read || s->non_overwrite || 3060 if (s->to_read || s->non_overwrite ||
3124 (s->syncing && (s->uptodate + s->compute < disks)) || s->expanding) 3061 (s->syncing && (s->uptodate + s->compute < disks)) || s->expanding)
3125 handle_stripe_fill5(sh, s, disks); 3062 handle_stripe_fill(sh, s, disks);
3126 3063
3127 /* Now we check to see if any write operations have recently 3064 /* Now we check to see if any write operations have recently
3128 * completed 3065 * completed
@@ -3313,7 +3250,7 @@ static int handle_stripe6(struct stripe_head *sh, struct stripe_head_state *s)
3313 */ 3250 */
3314 if (s->to_read || s->non_overwrite || (s->to_write && s->failed) || 3251 if (s->to_read || s->non_overwrite || (s->to_write && s->failed) ||
3315 (s->syncing && (s->uptodate + s->compute < disks)) || s->expanding) 3252 (s->syncing && (s->uptodate + s->compute < disks)) || s->expanding)
3316 handle_stripe_fill6(sh, s, disks); 3253 handle_stripe_fill(sh, s, disks);
3317 3254
3318 /* Now we check to see if any write operations have recently 3255 /* Now we check to see if any write operations have recently
3319 * completed 3256 * completed
@@ -3397,6 +3334,8 @@ static void handle_stripe(struct stripe_head *sh)
3397 s.syncing = test_bit(STRIPE_SYNCING, &sh->state); 3334 s.syncing = test_bit(STRIPE_SYNCING, &sh->state);
3398 s.expanding = test_bit(STRIPE_EXPAND_SOURCE, &sh->state); 3335 s.expanding = test_bit(STRIPE_EXPAND_SOURCE, &sh->state);
3399 s.expanded = test_bit(STRIPE_EXPAND_READY, &sh->state); 3336 s.expanded = test_bit(STRIPE_EXPAND_READY, &sh->state);
3337 s.failed_num[0] = -1;
3338 s.failed_num[1] = -1;
3400 3339
3401 if (conf->level == 6) 3340 if (conf->level == 6)
3402 done = handle_stripe6(sh, &s); 3341 done = handle_stripe6(sh, &s);