diff options
author | NeilBrown <neilb@suse.de> | 2005-11-09 00:39:26 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-09 10:56:37 -0500 |
commit | 9d88883e68f404d5581bd391713ceef470ea53a9 (patch) | |
tree | 09217a737ca91fb1d105df601741a61e141d4946 /drivers/md | |
parent | 24dd469d728dae07f40c5d79ea6dedd38cdf1a30 (diff) |
[PATCH] md: teach raid5 the difference between 'check' and 'repair'.
With this, raid5 can be asked to check parity without repairing it. It also
keeps a count of the number of incorrect parity blocks found (mismatches) and
reports them through sysfs.
Signed-off-by: Neil Brown <neilb@suse.de>
Cc: Greg KH <greg@kroah.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/md.c | 18 | ||||
-rw-r--r-- | drivers/md/raid5.c | 5 |
2 files changed, 21 insertions, 2 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 37400873b879..e58d61d9f31b 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -1758,16 +1758,29 @@ md_store_scan(mddev_t *mddev, const char *page, size_t len) | |||
1758 | return len; | 1758 | return len; |
1759 | } | 1759 | } |
1760 | 1760 | ||
1761 | static ssize_t | ||
1762 | md_show_mismatch(mddev_t *mddev, char *page) | ||
1763 | { | ||
1764 | return sprintf(page, "%llu\n", | ||
1765 | (unsigned long long) mddev->resync_mismatches); | ||
1766 | } | ||
1767 | |||
1761 | static struct md_sysfs_entry md_scan_mode = { | 1768 | static struct md_sysfs_entry md_scan_mode = { |
1762 | .attr = {.name = "scan_mode", .mode = S_IRUGO|S_IWUSR }, | 1769 | .attr = {.name = "scan_mode", .mode = S_IRUGO|S_IWUSR }, |
1763 | .show = md_show_scan, | 1770 | .show = md_show_scan, |
1764 | .store = md_store_scan, | 1771 | .store = md_store_scan, |
1765 | }; | 1772 | }; |
1766 | 1773 | ||
1774 | static struct md_sysfs_entry md_mismatches = { | ||
1775 | .attr = {.name = "mismatch_cnt", .mode = S_IRUGO }, | ||
1776 | .show = md_show_mismatch, | ||
1777 | }; | ||
1778 | |||
1767 | static struct attribute *md_default_attrs[] = { | 1779 | static struct attribute *md_default_attrs[] = { |
1768 | &md_level.attr, | 1780 | &md_level.attr, |
1769 | &md_raid_disks.attr, | 1781 | &md_raid_disks.attr, |
1770 | &md_scan_mode.attr, | 1782 | &md_scan_mode.attr, |
1783 | &md_mismatches.attr, | ||
1771 | NULL, | 1784 | NULL, |
1772 | }; | 1785 | }; |
1773 | 1786 | ||
@@ -3888,12 +3901,13 @@ static void md_do_sync(mddev_t *mddev) | |||
3888 | } | 3901 | } |
3889 | } while (mddev->curr_resync < 2); | 3902 | } while (mddev->curr_resync < 2); |
3890 | 3903 | ||
3891 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) | 3904 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { |
3892 | /* resync follows the size requested by the personality, | 3905 | /* resync follows the size requested by the personality, |
3893 | * which defaults to physical size, but can be virtual size | 3906 | * which defaults to physical size, but can be virtual size |
3894 | */ | 3907 | */ |
3895 | max_sectors = mddev->resync_max_sectors; | 3908 | max_sectors = mddev->resync_max_sectors; |
3896 | else | 3909 | mddev->resync_mismatches = 0; |
3910 | } else | ||
3897 | /* recovery follows the physical size of devices */ | 3911 | /* recovery follows the physical size of devices */ |
3898 | max_sectors = mddev->size << 1; | 3912 | max_sectors = mddev->size << 1; |
3899 | 3913 | ||
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 121fbaa9ed59..ce154553aca5 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -1292,6 +1292,11 @@ static void handle_stripe(struct stripe_head *sh) | |||
1292 | !memcmp(pagea, pagea+4, STRIPE_SIZE-4)) { | 1292 | !memcmp(pagea, pagea+4, STRIPE_SIZE-4)) { |
1293 | /* parity is correct (on disc, not in buffer any more) */ | 1293 | /* parity is correct (on disc, not in buffer any more) */ |
1294 | set_bit(STRIPE_INSYNC, &sh->state); | 1294 | set_bit(STRIPE_INSYNC, &sh->state); |
1295 | } else { | ||
1296 | conf->mddev->resync_mismatches += STRIPE_SECTORS; | ||
1297 | if (test_bit(MD_RECOVERY_CHECK, &conf->mddev->recovery)) | ||
1298 | /* don't try to repair!! */ | ||
1299 | set_bit(STRIPE_INSYNC, &sh->state); | ||
1295 | } | 1300 | } |
1296 | } | 1301 | } |
1297 | if (!test_bit(STRIPE_INSYNC, &sh->state)) { | 1302 | if (!test_bit(STRIPE_INSYNC, &sh->state)) { |