mirror of
https://github.com/adulau/aha.git
synced 2024-12-27 03:06:10 +00:00
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:
parent
4e59ca7da0
commit
06e3c817b7
2 changed files with 63 additions and 5 deletions
|
@ -233,9 +233,9 @@ All md devices contain:
|
||||||
|
|
||||||
resync_start
|
resync_start
|
||||||
The point at which resync should start. If no resync is needed,
|
The point at which resync should start. If no resync is needed,
|
||||||
this will be a very large number. At array creation it will
|
this will be a very large number (or 'none' since 2.6.30-rc1). At
|
||||||
default to 0, though starting the array as 'clean' will
|
array creation it will default to 0, though starting the array as
|
||||||
set it much larger.
|
'clean' will set it much larger.
|
||||||
|
|
||||||
new_dev
|
new_dev
|
||||||
This file can be written but not read. The value written should
|
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" sets the writemostly flag.
|
||||||
Writing "-writemostly" clears the writemostly flag.
|
Writing "-writemostly" clears the writemostly flag.
|
||||||
Writing "blocked" sets the "blocked" 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.
|
to complete.
|
||||||
|
Writing "in_sync" sets the in_sync flag.
|
||||||
|
|
||||||
This file responds to select/poll. Any change to 'faulty'
|
This file responds to select/poll. Any change to 'faulty'
|
||||||
or 'blocked' causes an event.
|
or 'blocked' causes an event.
|
||||||
|
@ -417,6 +418,24 @@ Each directory contains:
|
||||||
array. If a value less than the current component_size is
|
array. If a value less than the current component_size is
|
||||||
written, it will be rejected.
|
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
|
An active md device will also contain and entry for each active device
|
||||||
in the array. These are named
|
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 =
|
static struct rdev_sysfs_entry rdev_size =
|
||||||
__ATTR(size, S_IRUGO|S_IWUSR, rdev_size_show, rdev_size_store);
|
__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[] = {
|
static struct attribute *rdev_default_attrs[] = {
|
||||||
&rdev_state.attr,
|
&rdev_state.attr,
|
||||||
&rdev_errors.attr,
|
&rdev_errors.attr,
|
||||||
&rdev_slot.attr,
|
&rdev_slot.attr,
|
||||||
&rdev_offset.attr,
|
&rdev_offset.attr,
|
||||||
&rdev_size.attr,
|
&rdev_size.attr,
|
||||||
|
&rdev_recovery_start.attr,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
static ssize_t
|
static ssize_t
|
||||||
|
@ -3101,7 +3138,9 @@ resync_start_store(mddev_t *mddev, const char *buf, size_t len)
|
||||||
|
|
||||||
if (mddev->pers)
|
if (mddev->pers)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
if (!*buf || (*e && *e != '\n'))
|
if (cmd_match(buf, "none"))
|
||||||
|
n = MaxSector;
|
||||||
|
else if (!*buf || (*e && *e != '\n'))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
mddev->recovery_cp = n;
|
mddev->recovery_cp = n;
|
||||||
|
|
Loading…
Reference in a new issue