diff options
author | Dan Williams <dan.j.williams@intel.com> | 2009-12-12 23:17:12 -0500 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2009-12-13 20:58:57 -0500 |
commit | 06e3c817b750c131a20e82eed57a17841ea88ed2 (patch) | |
tree | 55da529f662c29da5b5fd202b5ece9fb907aa431 | |
parent | 4e59ca7da05f0d5d3ad40365c502c8b0fd24c7e3 (diff) |
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>
-rw-r--r-- | Documentation/md.txt | 27 | ||||
-rw-r--r-- | drivers/md/md.c | 41 |
2 files changed, 63 insertions, 5 deletions
diff --git a/Documentation/md.txt b/Documentation/md.txt index 21d26fb5d02b..188f4768f1d5 100644 --- a/Documentation/md.txt +++ b/Documentation/md.txt | |||
@@ -233,9 +233,9 @@ All md devices contain: | |||
233 | 233 | ||
234 | resync_start | 234 | resync_start |
235 | The point at which resync should start. If no resync is needed, | 235 | The point at which resync should start. If no resync is needed, |
236 | this will be a very large number. At array creation it will | 236 | this will be a very large number (or 'none' since 2.6.30-rc1). At |
237 | default to 0, though starting the array as 'clean' will | 237 | array creation it will default to 0, though starting the array as |
238 | set it much larger. | 238 | 'clean' will set it much larger. |
239 | 239 | ||
240 | new_dev | 240 | new_dev |
241 | This file can be written but not read. The value written should | 241 | This file can be written but not read. The value written should |
@@ -379,8 +379,9 @@ Each directory contains: | |||
379 | Writing "writemostly" sets the writemostly flag. | 379 | Writing "writemostly" sets the writemostly flag. |
380 | Writing "-writemostly" clears the writemostly flag. | 380 | Writing "-writemostly" clears the writemostly flag. |
381 | Writing "blocked" sets the "blocked" flag. | 381 | Writing "blocked" sets the "blocked" flag. |
382 | Writing "-blocked" clear the "blocked" flag and allows writes | 382 | Writing "-blocked" clears the "blocked" flag and allows writes |
383 | to complete. | 383 | to complete. |
384 | Writing "in_sync" sets the in_sync flag. | ||
384 | 385 | ||
385 | This file responds to select/poll. Any change to 'faulty' | 386 | This file responds to select/poll. Any change to 'faulty' |
386 | or 'blocked' causes an event. | 387 | or 'blocked' causes an event. |
@@ -417,6 +418,24 @@ Each directory contains: | |||
417 | array. If a value less than the current component_size is | 418 | array. If a value less than the current component_size is |
418 | written, it will be rejected. | 419 | written, it will be rejected. |
419 | 420 | ||
421 | recovery_start | ||
422 | |||
423 | When the device is not 'in_sync', this records the number of | ||
424 | sectors from the start of the device which are known to be | ||
425 | correct. This is normally zero, but during a recovery | ||
426 | operation is will steadily increase, and if the recovery is | ||
427 | interrupted, restoring this value can cause recovery to | ||
428 | avoid repeating the earlier blocks. With v1.x metadata, this | ||
429 | value is saved and restored automatically. | ||
430 | |||
431 | This can be set whenever the device is not an active member of | ||
432 | the array, either before the array is activated, or before | ||
433 | the 'slot' is set. | ||
434 | |||
435 | Setting this to 'none' is equivalent to setting 'in_sync'. | ||
436 | Setting to any other value also clears the 'in_sync' flag. | ||
437 | |||
438 | |||
420 | 439 | ||
421 | An active md device will also contain and entry for each active device | 440 | An active md device will also contain and entry for each active device |
422 | in the array. These are named | 441 | in the array. These are named |
diff --git a/drivers/md/md.c b/drivers/md/md.c index ea64a68e9c75..e1f3c1715cca 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -2551,12 +2551,49 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
2551 | static struct rdev_sysfs_entry rdev_size = | 2551 | static struct rdev_sysfs_entry rdev_size = |
2552 | __ATTR(size, S_IRUGO|S_IWUSR, rdev_size_show, rdev_size_store); | 2552 | __ATTR(size, S_IRUGO|S_IWUSR, rdev_size_show, rdev_size_store); |
2553 | 2553 | ||
2554 | |||
2555 | static ssize_t recovery_start_show(mdk_rdev_t *rdev, char *page) | ||
2556 | { | ||
2557 | unsigned long long recovery_start = rdev->recovery_offset; | ||
2558 | |||
2559 | if (test_bit(In_sync, &rdev->flags) || | ||
2560 | recovery_start == MaxSector) | ||
2561 | return sprintf(page, "none\n"); | ||
2562 | |||
2563 | return sprintf(page, "%llu\n", recovery_start); | ||
2564 | } | ||
2565 | |||
2566 | static ssize_t recovery_start_store(mdk_rdev_t *rdev, const char *buf, size_t len) | ||
2567 | { | ||
2568 | unsigned long long recovery_start; | ||
2569 | |||
2570 | if (cmd_match(buf, "none")) | ||
2571 | recovery_start = MaxSector; | ||
2572 | else if (strict_strtoull(buf, 10, &recovery_start)) | ||
2573 | return -EINVAL; | ||
2574 | |||
2575 | if (rdev->mddev->pers && | ||
2576 | rdev->raid_disk >= 0) | ||
2577 | return -EBUSY; | ||
2578 | |||
2579 | rdev->recovery_offset = recovery_start; | ||
2580 | if (recovery_start == MaxSector) | ||
2581 | set_bit(In_sync, &rdev->flags); | ||
2582 | else | ||
2583 | clear_bit(In_sync, &rdev->flags); | ||
2584 | return len; | ||
2585 | } | ||
2586 | |||
2587 | static struct rdev_sysfs_entry rdev_recovery_start = | ||
2588 | __ATTR(recovery_start, S_IRUGO|S_IWUSR, recovery_start_show, recovery_start_store); | ||
2589 | |||
2554 | static struct attribute *rdev_default_attrs[] = { | 2590 | static struct attribute *rdev_default_attrs[] = { |
2555 | &rdev_state.attr, | 2591 | &rdev_state.attr, |
2556 | &rdev_errors.attr, | 2592 | &rdev_errors.attr, |
2557 | &rdev_slot.attr, | 2593 | &rdev_slot.attr, |
2558 | &rdev_offset.attr, | 2594 | &rdev_offset.attr, |
2559 | &rdev_size.attr, | 2595 | &rdev_size.attr, |
2596 | &rdev_recovery_start.attr, | ||
2560 | NULL, | 2597 | NULL, |
2561 | }; | 2598 | }; |
2562 | static ssize_t | 2599 | static ssize_t |
@@ -3101,7 +3138,9 @@ resync_start_store(mddev_t *mddev, const char *buf, size_t len) | |||
3101 | 3138 | ||
3102 | if (mddev->pers) | 3139 | if (mddev->pers) |
3103 | return -EBUSY; | 3140 | return -EBUSY; |
3104 | if (!*buf || (*e && *e != '\n')) | 3141 | if (cmd_match(buf, "none")) |
3142 | n = MaxSector; | ||
3143 | else if (!*buf || (*e && *e != '\n')) | ||
3105 | return -EINVAL; | 3144 | return -EINVAL; |
3106 | 3145 | ||
3107 | mddev->recovery_cp = n; | 3146 | mddev->recovery_cp = n; |