[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>
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 3740087..e58d61d 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1758,16 +1758,29 @@
 	return len;
 }
 
+static ssize_t
+md_show_mismatch(mddev_t *mddev, char *page)
+{
+	return sprintf(page, "%llu\n",
+		       (unsigned long long) mddev->resync_mismatches);
+}
+
 static struct md_sysfs_entry md_scan_mode = {
 	.attr = {.name = "scan_mode", .mode = S_IRUGO|S_IWUSR },
 	.show = md_show_scan,
 	.store = md_store_scan,
 };
 
+static struct md_sysfs_entry md_mismatches = {
+	.attr = {.name = "mismatch_cnt", .mode = S_IRUGO },
+	.show = md_show_mismatch,
+};
+
 static struct attribute *md_default_attrs[] = {
 	&md_level.attr,
 	&md_raid_disks.attr,
 	&md_scan_mode.attr,
+	&md_mismatches.attr,
 	NULL,
 };
 
@@ -3888,12 +3901,13 @@
 		}
 	} while (mddev->curr_resync < 2);
 
-	if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
+	if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
 		/* resync follows the size requested by the personality,
 		 * which defaults to physical size, but can be virtual size
 		 */
 		max_sectors = mddev->resync_max_sectors;
-	else
+		mddev->resync_mismatches = 0;
+	} else
 		/* recovery follows the physical size of devices */
 		max_sectors = mddev->size << 1;