md: add 'recovery_start' per-device sysfs attribute
Enable external metadata arrays to manage rebuild checkpointing via a md/dev-XXX/recovery_start attribute which reflects rdev->recovery_offset Also update resync_start_store to allow 'none' to be written, for consistency. Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
Родитель
4e59ca7da0
Коммит
06e3c817b7
|
@ -233,9 +233,9 @@ All md devices contain:
|
|||
|
||||
resync_start
|
||||
The point at which resync should start. If no resync is needed,
|
||||
this will be a very large number. At array creation it will
|
||||
default to 0, though starting the array as 'clean' will
|
||||
set it much larger.
|
||||
this will be a very large number (or 'none' since 2.6.30-rc1). At
|
||||
array creation it will default to 0, though starting the array as
|
||||
'clean' will set it much larger.
|
||||
|
||||
new_dev
|
||||
This file can be written but not read. The value written should
|
||||
|
@ -379,8 +379,9 @@ Each directory contains:
|
|||
Writing "writemostly" sets the writemostly flag.
|
||||
Writing "-writemostly" clears the writemostly flag.
|
||||
Writing "blocked" sets the "blocked" flag.
|
||||
Writing "-blocked" clear the "blocked" flag and allows writes
|
||||
Writing "-blocked" clears the "blocked" flag and allows writes
|
||||
to complete.
|
||||
Writing "in_sync" sets the in_sync flag.
|
||||
|
||||
This file responds to select/poll. Any change to 'faulty'
|
||||
or 'blocked' causes an event.
|
||||
|
@ -417,6 +418,24 @@ Each directory contains:
|
|||
array. If a value less than the current component_size is
|
||||
written, it will be rejected.
|
||||
|
||||
recovery_start
|
||||
|
||||
When the device is not 'in_sync', this records the number of
|
||||
sectors from the start of the device which are known to be
|
||||
correct. This is normally zero, but during a recovery
|
||||
operation is will steadily increase, and if the recovery is
|
||||
interrupted, restoring this value can cause recovery to
|
||||
avoid repeating the earlier blocks. With v1.x metadata, this
|
||||
value is saved and restored automatically.
|
||||
|
||||
This can be set whenever the device is not an active member of
|
||||
the array, either before the array is activated, or before
|
||||
the 'slot' is set.
|
||||
|
||||
Setting this to 'none' is equivalent to setting 'in_sync'.
|
||||
Setting to any other value also clears the 'in_sync' flag.
|
||||
|
||||
|
||||
|
||||
An active md device will also contain and entry for each active device
|
||||
in the array. These are named
|
||||
|
|
|
@ -2551,12 +2551,49 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
|
|||
static struct rdev_sysfs_entry rdev_size =
|
||||
__ATTR(size, S_IRUGO|S_IWUSR, rdev_size_show, rdev_size_store);
|
||||
|
||||
|
||||
static ssize_t recovery_start_show(mdk_rdev_t *rdev, char *page)
|
||||
{
|
||||
unsigned long long recovery_start = rdev->recovery_offset;
|
||||
|
||||
if (test_bit(In_sync, &rdev->flags) ||
|
||||
recovery_start == MaxSector)
|
||||
return sprintf(page, "none\n");
|
||||
|
||||
return sprintf(page, "%llu\n", recovery_start);
|
||||
}
|
||||
|
||||
static ssize_t recovery_start_store(mdk_rdev_t *rdev, const char *buf, size_t len)
|
||||
{
|
||||
unsigned long long recovery_start;
|
||||
|
||||
if (cmd_match(buf, "none"))
|
||||
recovery_start = MaxSector;
|
||||
else if (strict_strtoull(buf, 10, &recovery_start))
|
||||
return -EINVAL;
|
||||
|
||||
if (rdev->mddev->pers &&
|
||||
rdev->raid_disk >= 0)
|
||||
return -EBUSY;
|
||||
|
||||
rdev->recovery_offset = recovery_start;
|
||||
if (recovery_start == MaxSector)
|
||||
set_bit(In_sync, &rdev->flags);
|
||||
else
|
||||
clear_bit(In_sync, &rdev->flags);
|
||||
return len;
|
||||
}
|
||||
|
||||
static struct rdev_sysfs_entry rdev_recovery_start =
|
||||
__ATTR(recovery_start, S_IRUGO|S_IWUSR, recovery_start_show, recovery_start_store);
|
||||
|
||||
static struct attribute *rdev_default_attrs[] = {
|
||||
&rdev_state.attr,
|
||||
&rdev_errors.attr,
|
||||
&rdev_slot.attr,
|
||||
&rdev_offset.attr,
|
||||
&rdev_size.attr,
|
||||
&rdev_recovery_start.attr,
|
||||
NULL,
|
||||
};
|
||||
static ssize_t
|
||||
|
@ -3101,7 +3138,9 @@ resync_start_store(mddev_t *mddev, const char *buf, size_t len)
|
|||
|
||||
if (mddev->pers)
|
||||
return -EBUSY;
|
||||
if (!*buf || (*e && *e != '\n'))
|
||||
if (cmd_match(buf, "none"))
|
||||
n = MaxSector;
|
||||
else if (!*buf || (*e && *e != '\n'))
|
||||
return -EINVAL;
|
||||
|
||||
mddev->recovery_cp = n;
|
||||
|
|
Загрузка…
Ссылка в новой задаче