提交 06e3c817 编写于 作者: D Dan Williams 提交者: NeilBrown

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: NDan Williams <dan.j.williams@intel.com>
Signed-off-by: NNeilBrown <neilb@suse.de>
上级 4e59ca7d
...@@ -233,9 +233,9 @@ All md devices contain: ...@@ -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: ...@@ -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: ...@@ -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) ...@@ -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) ...@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册