Skip to content

Commit 24dd469

Browse files
neilbrownLinus Torvalds
authored andcommitted
[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>
1 parent 3f294f4 commit 24dd469

File tree

2 files changed

+72
-9
lines changed

2 files changed

+72
-9
lines changed

drivers/md/md.c

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1714,9 +1714,60 @@ static struct md_sysfs_entry md_raid_disks = {
17141714
.show = md_show_rdisks,
17151715
};
17161716

1717+
static ssize_t
1718+
md_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+
1736+
static ssize_t
1737+
md_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+
1761+
static 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+
17171767
static struct attribute *md_default_attrs[] = {
17181768
&md_level.attr,
17191769
&md_raid_disks.attr,
1770+
&md_scan_mode.attr,
17201771
NULL,
17211772
};
17221773

@@ -3855,7 +3906,8 @@ static void md_do_sync(mddev_t *mddev)
38553906

38563907
is_mddev_idle(mddev); /* this also initializes IO event counters */
38573908
/* 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))
38593911
j = mddev->recovery_cp;
38603912
else
38613913
j = 0;
@@ -4093,9 +4145,13 @@ void md_check_recovery(mddev_t *mddev)
40934145
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
40944146
goto unlock;
40954147
}
4096-
if (mddev->recovery)
4097-
/* probably just the RECOVERY_NEEDED flag */
4098-
mddev->recovery = 0;
4148+
/* Clear some bits that don't mean anything, but
4149+
* might be left set
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);
40994155

41004156
/* no recovery is running.
41014157
* remove any failed drives, then
@@ -4129,14 +4185,17 @@ void md_check_recovery(mddev_t *mddev)
41294185
}
41304186
}
41314187

4132-
if (!spares && (mddev->recovery_cp == MaxSector )) {
4133-
/* nothing we can do ... */
4188+
if (spares) {
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 ... */
41344195
goto unlock;
4135-
}
4196+
41364197
if (mddev->pers->sync_request) {
41374198
set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
4138-
if (!spares)
4139-
set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
41404199
if (spares && mddev->bitmap && ! mddev->bitmap->file) {
41414200
/* We are adding a device or devices to an array
41424201
* which has the bitmap stored on all devices.

include/linux/raid/md_k.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,13 +182,17 @@ struct mddev_s
182182
* ERR: and IO error was detected - abort the resync/recovery
183183
* INTR: someone requested a (clean) early abort.
184184
* 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
185187
*/
186188
#define MD_RECOVERY_RUNNING 0
187189
#define MD_RECOVERY_SYNC 1
188190
#define MD_RECOVERY_ERR 2
189191
#define MD_RECOVERY_INTR 3
190192
#define MD_RECOVERY_DONE 4
191193
#define MD_RECOVERY_NEEDED 5
194+
#define MD_RECOVERY_REQUESTED 6
195+
#define MD_RECOVERY_CHECK 7
192196
unsigned long recovery;
193197

194198
int in_sync; /* know to not need resync */

0 commit comments

Comments
 (0)