aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-07-27 21:39:23 -0400
committerNeilBrown <neilb@suse.de>2011-07-27 21:39:23 -0400
commit560f8e5532d63a314271bfb99d3d1d53c938ed14 (patch)
treec47cbeb54b1e98f626a3e4af1bf0a184a831d3b9
parent1294b9c973251a5e68b62c9b40dd914517bda675 (diff)
md/raid10: Split handle_read_error out from raid10d.
raid10d() is too big and is about to get bigger, so split handle_read_error() out as a separate function. Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r--drivers/md/raid10.c123
1 files changed, 66 insertions, 57 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index c489b5c6ed6d..f1b749c21717 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1618,21 +1618,81 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio)
1618 } 1618 }
1619} 1619}
1620 1620
1621static void handle_read_error(mddev_t *mddev, r10bio_t *r10_bio)
1622{
1623 int slot = r10_bio->read_slot;
1624 int mirror = r10_bio->devs[slot].devnum;
1625 struct bio *bio;
1626 conf_t *conf = mddev->private;
1627 mdk_rdev_t *rdev;
1628 char b[BDEVNAME_SIZE];
1629 unsigned long do_sync;
1630
1631 /* we got a read error. Maybe the drive is bad. Maybe just
1632 * the block and we can fix it.
1633 * We freeze all other IO, and try reading the block from
1634 * other devices. When we find one, we re-write
1635 * and check it that fixes the read error.
1636 * This is all done synchronously while the array is
1637 * frozen.
1638 */
1639 if (mddev->ro == 0) {
1640 freeze_array(conf);
1641 fix_read_error(conf, mddev, r10_bio);
1642 unfreeze_array(conf);
1643 }
1644 rdev_dec_pending(conf->mirrors[mirror].rdev, mddev);
1645
1646 bio = r10_bio->devs[slot].bio;
1647 r10_bio->devs[slot].bio =
1648 mddev->ro ? IO_BLOCKED : NULL;
1649 mirror = read_balance(conf, r10_bio);
1650 if (mirror == -1) {
1651 printk(KERN_ALERT "md/raid10:%s: %s: unrecoverable I/O"
1652 " read error for block %llu\n",
1653 mdname(mddev),
1654 bdevname(bio->bi_bdev, b),
1655 (unsigned long long)r10_bio->sector);
1656 raid_end_bio_io(r10_bio);
1657 bio_put(bio);
1658 return;
1659 }
1660
1661 do_sync = (r10_bio->master_bio->bi_rw & REQ_SYNC);
1662 bio_put(bio);
1663 slot = r10_bio->read_slot;
1664 rdev = conf->mirrors[mirror].rdev;
1665 printk_ratelimited(
1666 KERN_ERR
1667 "md/raid10:%s: %s: redirecting"
1668 "sector %llu to another mirror\n",
1669 mdname(mddev),
1670 bdevname(rdev->bdev, b),
1671 (unsigned long long)r10_bio->sector);
1672 bio = bio_clone_mddev(r10_bio->master_bio,
1673 GFP_NOIO, mddev);
1674 r10_bio->devs[slot].bio = bio;
1675 bio->bi_sector = r10_bio->devs[slot].addr
1676 + rdev->data_offset;
1677 bio->bi_bdev = rdev->bdev;
1678 bio->bi_rw = READ | do_sync;
1679 bio->bi_private = r10_bio;
1680 bio->bi_end_io = raid10_end_read_request;
1681 generic_make_request(bio);
1682}
1683
1621static void raid10d(mddev_t *mddev) 1684static void raid10d(mddev_t *mddev)
1622{ 1685{
1623 r10bio_t *r10_bio; 1686 r10bio_t *r10_bio;
1624 struct bio *bio;
1625 unsigned long flags; 1687 unsigned long flags;
1626 conf_t *conf = mddev->private; 1688 conf_t *conf = mddev->private;
1627 struct list_head *head = &conf->retry_list; 1689 struct list_head *head = &conf->retry_list;
1628 mdk_rdev_t *rdev;
1629 struct blk_plug plug; 1690 struct blk_plug plug;
1630 1691
1631 md_check_recovery(mddev); 1692 md_check_recovery(mddev);
1632 1693
1633 blk_start_plug(&plug); 1694 blk_start_plug(&plug);
1634 for (;;) { 1695 for (;;) {
1635 char b[BDEVNAME_SIZE];
1636 1696
1637 flush_pending_writes(conf); 1697 flush_pending_writes(conf);
1638 1698
@@ -1652,60 +1712,9 @@ static void raid10d(mddev_t *mddev)
1652 sync_request_write(mddev, r10_bio); 1712 sync_request_write(mddev, r10_bio);
1653 else if (test_bit(R10BIO_IsRecover, &r10_bio->state)) 1713 else if (test_bit(R10BIO_IsRecover, &r10_bio->state))
1654 recovery_request_write(mddev, r10_bio); 1714 recovery_request_write(mddev, r10_bio);
1655 else { 1715 else
1656 int slot = r10_bio->read_slot; 1716 handle_read_error(mddev, r10_bio);
1657 int mirror = r10_bio->devs[slot].devnum; 1717
1658 /* we got a read error. Maybe the drive is bad. Maybe just
1659 * the block and we can fix it.
1660 * We freeze all other IO, and try reading the block from
1661 * other devices. When we find one, we re-write
1662 * and check it that fixes the read error.
1663 * This is all done synchronously while the array is
1664 * frozen.
1665 */
1666 if (mddev->ro == 0) {
1667 freeze_array(conf);
1668 fix_read_error(conf, mddev, r10_bio);
1669 unfreeze_array(conf);
1670 }
1671 rdev_dec_pending(conf->mirrors[mirror].rdev, mddev);
1672
1673 bio = r10_bio->devs[slot].bio;
1674 r10_bio->devs[slot].bio =
1675 mddev->ro ? IO_BLOCKED : NULL;
1676 mirror = read_balance(conf, r10_bio);
1677 if (mirror == -1) {
1678 printk(KERN_ALERT "md/raid10:%s: %s: unrecoverable I/O"
1679 " read error for block %llu\n",
1680 mdname(mddev),
1681 bdevname(bio->bi_bdev,b),
1682 (unsigned long long)r10_bio->sector);
1683 raid_end_bio_io(r10_bio);
1684 bio_put(bio);
1685 } else {
1686 const unsigned long do_sync = (r10_bio->master_bio->bi_rw & REQ_SYNC);
1687 bio_put(bio);
1688 slot = r10_bio->read_slot;
1689 rdev = conf->mirrors[mirror].rdev;
1690 printk_ratelimited(
1691 KERN_ERR
1692 "md/raid10:%s: %s: redirecting"
1693 "sector %llu to another mirror\n",
1694 mdname(mddev),
1695 bdevname(rdev->bdev, b),
1696 (unsigned long long)r10_bio->sector);
1697 bio = bio_clone_mddev(r10_bio->master_bio,
1698 GFP_NOIO, mddev);
1699 r10_bio->devs[slot].bio = bio;
1700 bio->bi_sector = r10_bio->devs[slot].addr
1701 + rdev->data_offset;
1702 bio->bi_bdev = rdev->bdev;
1703 bio->bi_rw = READ | do_sync;
1704 bio->bi_private = r10_bio;
1705 bio->bi_end_io = raid10_end_read_request;
1706 generic_make_request(bio);
1707 }
1708 }
1709 cond_resched(); 1718 cond_resched();
1710 if (mddev->flags & ~(1<<MD_CHANGE_PENDING)) 1719 if (mddev->flags & ~(1<<MD_CHANGE_PENDING))
1711 md_check_recovery(mddev); 1720 md_check_recovery(mddev);