aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2005-11-09 00:39:26 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-09 10:56:37 -0500
commit24dd469d728dae07f40c5d79ea6dedd38cdf1a30 (patch)
tree3975aaeaa6c1cd77a2d4b06184ad3bd0175a44a5
parent3f294f4fb6f2ba887b717674da26c21f3d57f3fc (diff)
[PATCH] md: allow a manual resync with md
You can trigger a 'check' with echo check > /sys/block/mdX/md/scan_mode or a check-and-repair errors with echo repair > /sys/block/mdX/md/scan_mode and read the current state from the same file. Note: personalities need to know the different between 'check' and 'repair', but don't yet. Until they do, 'check' will be the same as 'repair' and will just do a normal resync pass. 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>
-rw-r--r--drivers/md/md.c77
-rw-r--r--include/linux/raid/md_k.h4
2 files changed, 72 insertions, 9 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 74520b50c307..37400873b879 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1714,9 +1714,60 @@ static struct md_sysfs_entry md_raid_disks = {
1714 .show = md_show_rdisks, 1714 .show = md_show_rdisks,
1715}; 1715};
1716 1716
1717static ssize_t
1718md_show_scan(mddev_t *mddev, char *page)
1719{
1720 char *type = "none";
1721 if (mddev->recovery &
1722 ((1<<MD_RECOVERY_RUNNING) || (1<<MD_RECOVERY_NEEDED))) {
1723 if (mddev->recovery & (1<<MD_RECOVERY_SYNC)) {
1724 if (!test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
1725 type = "resync";
1726 else if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery))
1727 type = "check";
1728 else
1729 type = "repair";
1730 } else
1731 type = "recover";
1732 }
1733 return sprintf(page, "%s\n", type);
1734}
1735
1736static ssize_t
1737md_store_scan(mddev_t *mddev, const char *page, size_t len)
1738{
1739 int canscan=0;
1740 if (mddev->recovery &
1741 ((1<<MD_RECOVERY_RUNNING) || (1<<MD_RECOVERY_NEEDED)))
1742 return -EBUSY;
1743 down(&mddev->reconfig_sem);
1744 if (mddev->pers && mddev->pers->sync_request)
1745 canscan=1;
1746 up(&mddev->reconfig_sem);
1747 if (!canscan)
1748 return -EINVAL;
1749
1750 if (strcmp(page, "check")==0 || strcmp(page, "check\n")==0)
1751 set_bit(MD_RECOVERY_CHECK, &mddev->recovery);
1752 else if (strcmp(page, "repair")!=0 && strcmp(page, "repair\n")!=0)
1753 return -EINVAL;
1754 set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
1755 set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
1756 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
1757 md_wakeup_thread(mddev->thread);
1758 return len;
1759}
1760
1761static struct md_sysfs_entry md_scan_mode = {
1762 .attr = {.name = "scan_mode", .mode = S_IRUGO|S_IWUSR },
1763 .show = md_show_scan,
1764 .store = md_store_scan,
1765};
1766
1717static struct attribute *md_default_attrs[] = { 1767static struct attribute *md_default_attrs[] = {
1718 &md_level.attr, 1768 &md_level.attr,
1719 &md_raid_disks.attr, 1769 &md_raid_disks.attr,
1770 &md_scan_mode.attr,
1720 NULL, 1771 NULL,
1721}; 1772};
1722 1773
@@ -3855,7 +3906,8 @@ static void md_do_sync(mddev_t *mddev)
3855 3906
3856 is_mddev_idle(mddev); /* this also initializes IO event counters */ 3907 is_mddev_idle(mddev); /* this also initializes IO event counters */
3857 /* we don't use the checkpoint if there's a bitmap */ 3908 /* we don't use the checkpoint if there's a bitmap */
3858 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) && !mddev->bitmap) 3909 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) && !mddev->bitmap
3910 && ! test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
3859 j = mddev->recovery_cp; 3911 j = mddev->recovery_cp;
3860 else 3912 else
3861 j = 0; 3913 j = 0;
@@ -4093,9 +4145,13 @@ void md_check_recovery(mddev_t *mddev)
4093 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 4145 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
4094 goto unlock; 4146 goto unlock;
4095 } 4147 }
4096 if (mddev->recovery) 4148 /* Clear some bits that don't mean anything, but
4097 /* probably just the RECOVERY_NEEDED flag */ 4149 * might be left set
4098 mddev->recovery = 0; 4150 */
4151 clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
4152 clear_bit(MD_RECOVERY_ERR, &mddev->recovery);
4153 clear_bit(MD_RECOVERY_INTR, &mddev->recovery);
4154 clear_bit(MD_RECOVERY_DONE, &mddev->recovery);
4099 4155
4100 /* no recovery is running. 4156 /* no recovery is running.
4101 * remove any failed drives, then 4157 * remove any failed drives, then
@@ -4129,14 +4185,17 @@ void md_check_recovery(mddev_t *mddev)
4129 } 4185 }
4130 } 4186 }
4131 4187
4132 if (!spares && (mddev->recovery_cp == MaxSector )) { 4188 if (spares) {
4133 /* nothing we can do ... */ 4189 clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
4190 clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
4191 } else if (mddev->recovery_cp < MaxSector) {
4192 set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
4193 } else if (!test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
4194 /* nothing to be done ... */
4134 goto unlock; 4195 goto unlock;
4135 } 4196
4136 if (mddev->pers->sync_request) { 4197 if (mddev->pers->sync_request) {
4137 set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); 4198 set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
4138 if (!spares)
4139 set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
4140 if (spares && mddev->bitmap && ! mddev->bitmap->file) { 4199 if (spares && mddev->bitmap && ! mddev->bitmap->file) {
4141 /* We are adding a device or devices to an array 4200 /* We are adding a device or devices to an array
4142 * which has the bitmap stored on all devices. 4201 * which has the bitmap stored on all devices.
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h
index d1dad32ebe07..efd04dca0abd 100644
--- a/include/linux/raid/md_k.h
+++ b/include/linux/raid/md_k.h
@@ -182,6 +182,8 @@ struct mddev_s
182 * ERR: and IO error was detected - abort the resync/recovery 182 * ERR: and IO error was detected - abort the resync/recovery
183 * INTR: someone requested a (clean) early abort. 183 * INTR: someone requested a (clean) early abort.
184 * DONE: thread is done and is waiting to be reaped 184 * DONE: thread is done and is waiting to be reaped
185 * REQUEST: user-space has requested a sync (used with SYNC)
186 * CHECK: user-space request for for check-only, no repair
185 */ 187 */
186#define MD_RECOVERY_RUNNING 0 188#define MD_RECOVERY_RUNNING 0
187#define MD_RECOVERY_SYNC 1 189#define MD_RECOVERY_SYNC 1
@@ -189,6 +191,8 @@ struct mddev_s
189#define MD_RECOVERY_INTR 3 191#define MD_RECOVERY_INTR 3
190#define MD_RECOVERY_DONE 4 192#define MD_RECOVERY_DONE 4
191#define MD_RECOVERY_NEEDED 5 193#define MD_RECOVERY_NEEDED 5
194#define MD_RECOVERY_REQUESTED 6
195#define MD_RECOVERY_CHECK 7
192 unsigned long recovery; 196 unsigned long recovery;
193 197
194 int in_sync; /* know to not need resync */ 198 int in_sync; /* know to not need resync */