aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/md.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2009-12-12 23:17:12 -0500
committerNeilBrown <neilb@suse.de>2009-12-13 20:58:57 -0500
commit06e3c817b750c131a20e82eed57a17841ea88ed2 (patch)
tree55da529f662c29da5b5fd202b5ece9fb907aa431 /drivers/md/md.c
parent4e59ca7da05f0d5d3ad40365c502c8b0fd24c7e3 (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/md.c')
-rw-r--r--drivers/md/md.c41
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)
2551static struct rdev_sysfs_entry rdev_size = 2551static 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
2555static 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
2566static 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
2587static struct rdev_sysfs_entry rdev_recovery_start =
2588__ATTR(recovery_start, S_IRUGO|S_IWUSR, recovery_start_show, recovery_start_store);
2589
2554static struct attribute *rdev_default_attrs[] = { 2590static 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};
2562static ssize_t 2599static 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;