diff options
author | NeilBrown <neilb@suse.de> | 2011-07-27 21:39:23 -0400 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2011-07-27 21:39:23 -0400 |
commit | 560f8e5532d63a314271bfb99d3d1d53c938ed14 (patch) | |
tree | c47cbeb54b1e98f626a3e4af1bf0a184a831d3b9 | |
parent | 1294b9c973251a5e68b62c9b40dd914517bda675 (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.c | 123 |
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 | ||
1621 | static 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 | |||
1621 | static void raid10d(mddev_t *mddev) | 1684 | static 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); |