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 /drivers/md | |
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>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/md.c | 41 |
1 files changed, 40 insertions, 1 deletions
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; |