aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 21d26fb5d02..188f4768f1d 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 ea64a68e9c7..e1f3c1715cc 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;