diff options
Diffstat (limited to 'drivers/md/raid10.c')
-rw-r--r-- | drivers/md/raid10.c | 148 |
1 files changed, 77 insertions, 71 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index d1295aff4173..64d48249c03b 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -499,7 +499,7 @@ static void raid10_end_write_request(struct bio *bio, int error) | |||
499 | */ | 499 | */ |
500 | one_write_done(r10_bio); | 500 | one_write_done(r10_bio); |
501 | if (dec_rdev) | 501 | if (dec_rdev) |
502 | rdev_dec_pending(conf->mirrors[dev].rdev, conf->mddev); | 502 | rdev_dec_pending(rdev, conf->mddev); |
503 | } | 503 | } |
504 | 504 | ||
505 | /* | 505 | /* |
@@ -952,7 +952,7 @@ static void raise_barrier(struct r10conf *conf, int force) | |||
952 | 952 | ||
953 | /* Wait until no block IO is waiting (unless 'force') */ | 953 | /* Wait until no block IO is waiting (unless 'force') */ |
954 | wait_event_lock_irq(conf->wait_barrier, force || !conf->nr_waiting, | 954 | wait_event_lock_irq(conf->wait_barrier, force || !conf->nr_waiting, |
955 | conf->resync_lock, ); | 955 | conf->resync_lock); |
956 | 956 | ||
957 | /* block any new IO from starting */ | 957 | /* block any new IO from starting */ |
958 | conf->barrier++; | 958 | conf->barrier++; |
@@ -960,7 +960,7 @@ static void raise_barrier(struct r10conf *conf, int force) | |||
960 | /* Now wait for all pending IO to complete */ | 960 | /* Now wait for all pending IO to complete */ |
961 | wait_event_lock_irq(conf->wait_barrier, | 961 | wait_event_lock_irq(conf->wait_barrier, |
962 | !conf->nr_pending && conf->barrier < RESYNC_DEPTH, | 962 | !conf->nr_pending && conf->barrier < RESYNC_DEPTH, |
963 | conf->resync_lock, ); | 963 | conf->resync_lock); |
964 | 964 | ||
965 | spin_unlock_irq(&conf->resync_lock); | 965 | spin_unlock_irq(&conf->resync_lock); |
966 | } | 966 | } |
@@ -993,8 +993,7 @@ static void wait_barrier(struct r10conf *conf) | |||
993 | (conf->nr_pending && | 993 | (conf->nr_pending && |
994 | current->bio_list && | 994 | current->bio_list && |
995 | !bio_list_empty(current->bio_list)), | 995 | !bio_list_empty(current->bio_list)), |
996 | conf->resync_lock, | 996 | conf->resync_lock); |
997 | ); | ||
998 | conf->nr_waiting--; | 997 | conf->nr_waiting--; |
999 | } | 998 | } |
1000 | conf->nr_pending++; | 999 | conf->nr_pending++; |
@@ -1027,10 +1026,10 @@ static void freeze_array(struct r10conf *conf) | |||
1027 | spin_lock_irq(&conf->resync_lock); | 1026 | spin_lock_irq(&conf->resync_lock); |
1028 | conf->barrier++; | 1027 | conf->barrier++; |
1029 | conf->nr_waiting++; | 1028 | conf->nr_waiting++; |
1030 | wait_event_lock_irq(conf->wait_barrier, | 1029 | wait_event_lock_irq_cmd(conf->wait_barrier, |
1031 | conf->nr_pending == conf->nr_queued+1, | 1030 | conf->nr_pending == conf->nr_queued+1, |
1032 | conf->resync_lock, | 1031 | conf->resync_lock, |
1033 | flush_pending_writes(conf)); | 1032 | flush_pending_writes(conf)); |
1034 | 1033 | ||
1035 | spin_unlock_irq(&conf->resync_lock); | 1034 | spin_unlock_irq(&conf->resync_lock); |
1036 | } | 1035 | } |
@@ -1069,7 +1068,7 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule) | |||
1069 | struct r10conf *conf = mddev->private; | 1068 | struct r10conf *conf = mddev->private; |
1070 | struct bio *bio; | 1069 | struct bio *bio; |
1071 | 1070 | ||
1072 | if (from_schedule) { | 1071 | if (from_schedule || current->bio_list) { |
1073 | spin_lock_irq(&conf->device_lock); | 1072 | spin_lock_irq(&conf->device_lock); |
1074 | bio_list_merge(&conf->pending_bio_list, &plug->pending); | 1073 | bio_list_merge(&conf->pending_bio_list, &plug->pending); |
1075 | conf->pending_count += plug->pending_cnt; | 1074 | conf->pending_count += plug->pending_cnt; |
@@ -1334,18 +1333,21 @@ retry_write: | |||
1334 | blocked_rdev = rrdev; | 1333 | blocked_rdev = rrdev; |
1335 | break; | 1334 | break; |
1336 | } | 1335 | } |
1336 | if (rdev && (test_bit(Faulty, &rdev->flags) | ||
1337 | || test_bit(Unmerged, &rdev->flags))) | ||
1338 | rdev = NULL; | ||
1337 | if (rrdev && (test_bit(Faulty, &rrdev->flags) | 1339 | if (rrdev && (test_bit(Faulty, &rrdev->flags) |
1338 | || test_bit(Unmerged, &rrdev->flags))) | 1340 | || test_bit(Unmerged, &rrdev->flags))) |
1339 | rrdev = NULL; | 1341 | rrdev = NULL; |
1340 | 1342 | ||
1341 | r10_bio->devs[i].bio = NULL; | 1343 | r10_bio->devs[i].bio = NULL; |
1342 | r10_bio->devs[i].repl_bio = NULL; | 1344 | r10_bio->devs[i].repl_bio = NULL; |
1343 | if (!rdev || test_bit(Faulty, &rdev->flags) || | 1345 | |
1344 | test_bit(Unmerged, &rdev->flags)) { | 1346 | if (!rdev && !rrdev) { |
1345 | set_bit(R10BIO_Degraded, &r10_bio->state); | 1347 | set_bit(R10BIO_Degraded, &r10_bio->state); |
1346 | continue; | 1348 | continue; |
1347 | } | 1349 | } |
1348 | if (test_bit(WriteErrorSeen, &rdev->flags)) { | 1350 | if (rdev && test_bit(WriteErrorSeen, &rdev->flags)) { |
1349 | sector_t first_bad; | 1351 | sector_t first_bad; |
1350 | sector_t dev_sector = r10_bio->devs[i].addr; | 1352 | sector_t dev_sector = r10_bio->devs[i].addr; |
1351 | int bad_sectors; | 1353 | int bad_sectors; |
@@ -1387,8 +1389,10 @@ retry_write: | |||
1387 | max_sectors = good_sectors; | 1389 | max_sectors = good_sectors; |
1388 | } | 1390 | } |
1389 | } | 1391 | } |
1390 | r10_bio->devs[i].bio = bio; | 1392 | if (rdev) { |
1391 | atomic_inc(&rdev->nr_pending); | 1393 | r10_bio->devs[i].bio = bio; |
1394 | atomic_inc(&rdev->nr_pending); | ||
1395 | } | ||
1392 | if (rrdev) { | 1396 | if (rrdev) { |
1393 | r10_bio->devs[i].repl_bio = bio; | 1397 | r10_bio->devs[i].repl_bio = bio; |
1394 | atomic_inc(&rrdev->nr_pending); | 1398 | atomic_inc(&rrdev->nr_pending); |
@@ -1444,69 +1448,71 @@ retry_write: | |||
1444 | for (i = 0; i < conf->copies; i++) { | 1448 | for (i = 0; i < conf->copies; i++) { |
1445 | struct bio *mbio; | 1449 | struct bio *mbio; |
1446 | int d = r10_bio->devs[i].devnum; | 1450 | int d = r10_bio->devs[i].devnum; |
1447 | if (!r10_bio->devs[i].bio) | 1451 | if (r10_bio->devs[i].bio) { |
1448 | continue; | 1452 | struct md_rdev *rdev = conf->mirrors[d].rdev; |
1453 | mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); | ||
1454 | md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, | ||
1455 | max_sectors); | ||
1456 | r10_bio->devs[i].bio = mbio; | ||
1457 | |||
1458 | mbio->bi_sector = (r10_bio->devs[i].addr+ | ||
1459 | choose_data_offset(r10_bio, | ||
1460 | rdev)); | ||
1461 | mbio->bi_bdev = rdev->bdev; | ||
1462 | mbio->bi_end_io = raid10_end_write_request; | ||
1463 | mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; | ||
1464 | mbio->bi_private = r10_bio; | ||
1449 | 1465 | ||
1450 | mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); | 1466 | atomic_inc(&r10_bio->remaining); |
1451 | md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, | ||
1452 | max_sectors); | ||
1453 | r10_bio->devs[i].bio = mbio; | ||
1454 | 1467 | ||
1455 | mbio->bi_sector = (r10_bio->devs[i].addr+ | 1468 | cb = blk_check_plugged(raid10_unplug, mddev, |
1456 | choose_data_offset(r10_bio, | 1469 | sizeof(*plug)); |
1457 | conf->mirrors[d].rdev)); | 1470 | if (cb) |
1458 | mbio->bi_bdev = conf->mirrors[d].rdev->bdev; | 1471 | plug = container_of(cb, struct raid10_plug_cb, |
1459 | mbio->bi_end_io = raid10_end_write_request; | 1472 | cb); |
1460 | mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; | 1473 | else |
1461 | mbio->bi_private = r10_bio; | 1474 | plug = NULL; |
1475 | spin_lock_irqsave(&conf->device_lock, flags); | ||
1476 | if (plug) { | ||
1477 | bio_list_add(&plug->pending, mbio); | ||
1478 | plug->pending_cnt++; | ||
1479 | } else { | ||
1480 | bio_list_add(&conf->pending_bio_list, mbio); | ||
1481 | conf->pending_count++; | ||
1482 | } | ||
1483 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
1484 | if (!plug) | ||
1485 | md_wakeup_thread(mddev->thread); | ||
1486 | } | ||
1462 | 1487 | ||
1463 | atomic_inc(&r10_bio->remaining); | 1488 | if (r10_bio->devs[i].repl_bio) { |
1489 | struct md_rdev *rdev = conf->mirrors[d].replacement; | ||
1490 | if (rdev == NULL) { | ||
1491 | /* Replacement just got moved to main 'rdev' */ | ||
1492 | smp_mb(); | ||
1493 | rdev = conf->mirrors[d].rdev; | ||
1494 | } | ||
1495 | mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); | ||
1496 | md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, | ||
1497 | max_sectors); | ||
1498 | r10_bio->devs[i].repl_bio = mbio; | ||
1499 | |||
1500 | mbio->bi_sector = (r10_bio->devs[i].addr + | ||
1501 | choose_data_offset( | ||
1502 | r10_bio, rdev)); | ||
1503 | mbio->bi_bdev = rdev->bdev; | ||
1504 | mbio->bi_end_io = raid10_end_write_request; | ||
1505 | mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; | ||
1506 | mbio->bi_private = r10_bio; | ||
1464 | 1507 | ||
1465 | cb = blk_check_plugged(raid10_unplug, mddev, sizeof(*plug)); | 1508 | atomic_inc(&r10_bio->remaining); |
1466 | if (cb) | 1509 | spin_lock_irqsave(&conf->device_lock, flags); |
1467 | plug = container_of(cb, struct raid10_plug_cb, cb); | ||
1468 | else | ||
1469 | plug = NULL; | ||
1470 | spin_lock_irqsave(&conf->device_lock, flags); | ||
1471 | if (plug) { | ||
1472 | bio_list_add(&plug->pending, mbio); | ||
1473 | plug->pending_cnt++; | ||
1474 | } else { | ||
1475 | bio_list_add(&conf->pending_bio_list, mbio); | 1510 | bio_list_add(&conf->pending_bio_list, mbio); |
1476 | conf->pending_count++; | 1511 | conf->pending_count++; |
1512 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
1513 | if (!mddev_check_plugged(mddev)) | ||
1514 | md_wakeup_thread(mddev->thread); | ||
1477 | } | 1515 | } |
1478 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
1479 | if (!plug) | ||
1480 | md_wakeup_thread(mddev->thread); | ||
1481 | |||
1482 | if (!r10_bio->devs[i].repl_bio) | ||
1483 | continue; | ||
1484 | |||
1485 | mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); | ||
1486 | md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, | ||
1487 | max_sectors); | ||
1488 | r10_bio->devs[i].repl_bio = mbio; | ||
1489 | |||
1490 | /* We are actively writing to the original device | ||
1491 | * so it cannot disappear, so the replacement cannot | ||
1492 | * become NULL here | ||
1493 | */ | ||
1494 | mbio->bi_sector = (r10_bio->devs[i].addr + | ||
1495 | choose_data_offset( | ||
1496 | r10_bio, | ||
1497 | conf->mirrors[d].replacement)); | ||
1498 | mbio->bi_bdev = conf->mirrors[d].replacement->bdev; | ||
1499 | mbio->bi_end_io = raid10_end_write_request; | ||
1500 | mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; | ||
1501 | mbio->bi_private = r10_bio; | ||
1502 | |||
1503 | atomic_inc(&r10_bio->remaining); | ||
1504 | spin_lock_irqsave(&conf->device_lock, flags); | ||
1505 | bio_list_add(&conf->pending_bio_list, mbio); | ||
1506 | conf->pending_count++; | ||
1507 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
1508 | if (!mddev_check_plugged(mddev)) | ||
1509 | md_wakeup_thread(mddev->thread); | ||
1510 | } | 1516 | } |
1511 | 1517 | ||
1512 | /* Don't remove the bias on 'remaining' (one_write_done) until | 1518 | /* Don't remove the bias on 'remaining' (one_write_done) until |