mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
Allow setting start point for requested check/repair
This makes it possible to just resync a small part of an array. e.g. if a drive reports that it has questionable sectors, a 'repair' of just the region covering those sectors will cause them to be read and, if there is an error, re-written with correct data. Signed-off-by: Neil Brown <neilb@suse.de>
This commit is contained in:
parent
a0da84f35b
commit
5e96ee65c8
2 changed files with 44 additions and 5 deletions
|
@ -278,6 +278,7 @@ static mddev_t * mddev_find(dev_t unit)
|
||||||
init_waitqueue_head(&new->sb_wait);
|
init_waitqueue_head(&new->sb_wait);
|
||||||
init_waitqueue_head(&new->recovery_wait);
|
init_waitqueue_head(&new->recovery_wait);
|
||||||
new->reshape_position = MaxSector;
|
new->reshape_position = MaxSector;
|
||||||
|
new->resync_min = 0;
|
||||||
new->resync_max = MaxSector;
|
new->resync_max = MaxSector;
|
||||||
new->level = LEVEL_NONE;
|
new->level = LEVEL_NONE;
|
||||||
|
|
||||||
|
@ -3074,6 +3075,36 @@ sync_completed_show(mddev_t *mddev, char *page)
|
||||||
|
|
||||||
static struct md_sysfs_entry md_sync_completed = __ATTR_RO(sync_completed);
|
static struct md_sysfs_entry md_sync_completed = __ATTR_RO(sync_completed);
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
min_sync_show(mddev_t *mddev, char *page)
|
||||||
|
{
|
||||||
|
return sprintf(page, "%llu\n",
|
||||||
|
(unsigned long long)mddev->resync_min);
|
||||||
|
}
|
||||||
|
static ssize_t
|
||||||
|
min_sync_store(mddev_t *mddev, const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
unsigned long long min;
|
||||||
|
if (strict_strtoull(buf, 10, &min))
|
||||||
|
return -EINVAL;
|
||||||
|
if (min > mddev->resync_max)
|
||||||
|
return -EINVAL;
|
||||||
|
if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
|
/* Must be a multiple of chunk_size */
|
||||||
|
if (mddev->chunk_size) {
|
||||||
|
if (min & (sector_t)((mddev->chunk_size>>9)-1))
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
mddev->resync_min = min;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct md_sysfs_entry md_min_sync =
|
||||||
|
__ATTR(sync_min, S_IRUGO|S_IWUSR, min_sync_show, min_sync_store);
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
max_sync_show(mddev_t *mddev, char *page)
|
max_sync_show(mddev_t *mddev, char *page)
|
||||||
{
|
{
|
||||||
|
@ -3089,9 +3120,10 @@ max_sync_store(mddev_t *mddev, const char *buf, size_t len)
|
||||||
if (strncmp(buf, "max", 3) == 0)
|
if (strncmp(buf, "max", 3) == 0)
|
||||||
mddev->resync_max = MaxSector;
|
mddev->resync_max = MaxSector;
|
||||||
else {
|
else {
|
||||||
char *ep;
|
unsigned long long max;
|
||||||
unsigned long long max = simple_strtoull(buf, &ep, 10);
|
if (strict_strtoull(buf, 10, &max))
|
||||||
if (ep == buf || (*ep != 0 && *ep != '\n'))
|
return -EINVAL;
|
||||||
|
if (max < mddev->resync_min)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (max < mddev->resync_max &&
|
if (max < mddev->resync_max &&
|
||||||
test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
|
test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
|
||||||
|
@ -3222,6 +3254,7 @@ static struct attribute *md_redundancy_attrs[] = {
|
||||||
&md_sync_speed.attr,
|
&md_sync_speed.attr,
|
||||||
&md_sync_force_parallel.attr,
|
&md_sync_force_parallel.attr,
|
||||||
&md_sync_completed.attr,
|
&md_sync_completed.attr,
|
||||||
|
&md_min_sync.attr,
|
||||||
&md_max_sync.attr,
|
&md_max_sync.attr,
|
||||||
&md_suspend_lo.attr,
|
&md_suspend_lo.attr,
|
||||||
&md_suspend_hi.attr,
|
&md_suspend_hi.attr,
|
||||||
|
@ -3777,6 +3810,7 @@ static int do_md_stop(mddev_t * mddev, int mode)
|
||||||
mddev->size = 0;
|
mddev->size = 0;
|
||||||
mddev->raid_disks = 0;
|
mddev->raid_disks = 0;
|
||||||
mddev->recovery_cp = 0;
|
mddev->recovery_cp = 0;
|
||||||
|
mddev->resync_min = 0;
|
||||||
mddev->resync_max = MaxSector;
|
mddev->resync_max = MaxSector;
|
||||||
mddev->reshape_position = MaxSector;
|
mddev->reshape_position = MaxSector;
|
||||||
mddev->external = 0;
|
mddev->external = 0;
|
||||||
|
@ -5625,9 +5659,11 @@ void md_do_sync(mddev_t *mddev)
|
||||||
max_sectors = mddev->resync_max_sectors;
|
max_sectors = mddev->resync_max_sectors;
|
||||||
mddev->resync_mismatches = 0;
|
mddev->resync_mismatches = 0;
|
||||||
/* we don't use the checkpoint if there's a bitmap */
|
/* we don't use the checkpoint if there's a bitmap */
|
||||||
if (!mddev->bitmap &&
|
if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
|
||||||
!test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
|
j = mddev->resync_min;
|
||||||
|
else if (!mddev->bitmap)
|
||||||
j = mddev->recovery_cp;
|
j = mddev->recovery_cp;
|
||||||
|
|
||||||
} else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
|
} else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
|
||||||
max_sectors = mddev->size << 1;
|
max_sectors = mddev->size << 1;
|
||||||
else {
|
else {
|
||||||
|
@ -5796,6 +5832,7 @@ void md_do_sync(mddev_t *mddev)
|
||||||
|
|
||||||
skip:
|
skip:
|
||||||
mddev->curr_resync = 0;
|
mddev->curr_resync = 0;
|
||||||
|
mddev->resync_min = 0;
|
||||||
mddev->resync_max = MaxSector;
|
mddev->resync_max = MaxSector;
|
||||||
sysfs_notify(&mddev->kobj, NULL, "sync_completed");
|
sysfs_notify(&mddev->kobj, NULL, "sync_completed");
|
||||||
wake_up(&resync_wait);
|
wake_up(&resync_wait);
|
||||||
|
|
|
@ -227,6 +227,8 @@ struct mddev_s
|
||||||
atomic_t recovery_active; /* blocks scheduled, but not written */
|
atomic_t recovery_active; /* blocks scheduled, but not written */
|
||||||
wait_queue_head_t recovery_wait;
|
wait_queue_head_t recovery_wait;
|
||||||
sector_t recovery_cp;
|
sector_t recovery_cp;
|
||||||
|
sector_t resync_min; /* user requested sync
|
||||||
|
* starts here */
|
||||||
sector_t resync_max; /* resync should pause
|
sector_t resync_max; /* resync should pause
|
||||||
* when it gets here */
|
* when it gets here */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue