aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--Documentation/md.txt27
-rw-r--r--drivers/md/md.c41
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
421An active md device will also contain and entry for each active device 440An active md device will also contain and entry for each active device
422in the array. These are named 441in 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)
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;