aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-04 14:36:50 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-04 14:36:50 -0400
commit697a067f1ec67f2f8dfafd0a1b95a46997a11f32 (patch)
tree7f0f4bc39ee00944fdc45fd447a0527f77a9582a
parente61aca5158a84932cf9fbbcbf8aef9cef63f5026 (diff)
parent1376512065b23f39d5f9a160948f313397dde972 (diff)
Merge tag 'md-3.11' of git://neil.brown.name/md
Pull md updates from NeilBrown: "Mostly fixes, with a few minor features (eg 'last_sync_action' sysfs file) A couple marked for -stable including one recent bug which causes a RAID10 reshape to complete without moving any data :-( A couple more bugfixes (at least) to come, but haven't confirmed the right solution yet." * tag 'md-3.11' of git://neil.brown.name/md: md/raid10: fix bug which causes all RAID10 reshapes to move no data. md/raid5: allow 5-device RAID6 to be reshaped to 4-device. md/raid10: fix two bugs affecting RAID10 reshape. md: remove doubled description for sync_max, merging it within sync_min/sync_max MD: Remember the last sync operation that was performed md: fix buglet in RAID5 -> RAID0 conversion. md/raid10: check In_sync flag in 'enough()'. md/raid10: locking changes for 'enough()'. md: replace strict_strto*() with kstrto*() md: Wait for md_check_recovery before attempting device removal. dm-raid: silence compiler warning on rebuilds_per_group. DM RAID: Fix raid_resume not reviving failed devices in all cases DM RAID: Break-up untidy function DM RAID: Add ability to restore transiently failed devices on resume
-rw-r--r--Documentation/device-mapper/dm-raid.txt2
-rw-r--r--Documentation/md.txt13
-rw-r--r--drivers/md/bitmap.c8
-rw-r--r--drivers/md/dm-raid.c76
-rw-r--r--drivers/md/md.c53
-rw-r--r--drivers/md/md.h8
-rw-r--r--drivers/md/raid0.c1
-rw-r--r--drivers/md/raid1.c7
-rw-r--r--drivers/md/raid10.c83
-rw-r--r--drivers/md/raid5.c6
10 files changed, 187 insertions, 70 deletions
diff --git a/Documentation/device-mapper/dm-raid.txt b/Documentation/device-mapper/dm-raid.txt
index e9192283e5a5..ef8ba9fa58c4 100644
--- a/Documentation/device-mapper/dm-raid.txt
+++ b/Documentation/device-mapper/dm-raid.txt
@@ -222,3 +222,5 @@ Version History
2221.4.2 Add RAID10 "far" and "offset" algorithm support. 2221.4.2 Add RAID10 "far" and "offset" algorithm support.
2231.5.0 Add message interface to allow manipulation of the sync_action. 2231.5.0 Add message interface to allow manipulation of the sync_action.
224 New status (STATUSTYPE_INFO) fields: sync_action and mismatch_cnt. 224 New status (STATUSTYPE_INFO) fields: sync_action and mismatch_cnt.
2251.5.1 Add ability to restore transiently failed devices on resume.
2261.5.2 'mismatch_cnt' is zero unless [last_]sync_action is "check".
diff --git a/Documentation/md.txt b/Documentation/md.txt
index e0ddd327632d..fbb2fcbf16b6 100644
--- a/Documentation/md.txt
+++ b/Documentation/md.txt
@@ -566,13 +566,6 @@ also have
566 when it reaches the current sync_max (below) and possibly at 566 when it reaches the current sync_max (below) and possibly at
567 other times. 567 other times.
568 568
569 sync_max
570 This is a number of sectors at which point a resync/recovery
571 process will pause. When a resync is active, the value can
572 only ever be increased, never decreased. The value of 'max'
573 effectively disables the limit.
574
575
576 sync_speed 569 sync_speed
577 This shows the current actual speed, in K/sec, of the current 570 This shows the current actual speed, in K/sec, of the current
578 sync_action. It is averaged over the last 30 seconds. 571 sync_action. It is averaged over the last 30 seconds.
@@ -593,6 +586,12 @@ also have
593 that number to reach sync_max. Then you can either increase 586 that number to reach sync_max. Then you can either increase
594 "sync_max", or can write 'idle' to "sync_action". 587 "sync_max", or can write 'idle' to "sync_action".
595 588
589 The value of 'max' for "sync_max" effectively disables the limit.
590 When a resync is active, the value can only ever be increased,
591 never decreased.
592 The value of '0' is the minimum for "sync_min".
593
594
596 595
597Each active md device may also have attributes specific to the 596Each active md device may also have attributes specific to the
598personality module that manages it. 597personality module that manages it.
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 5a2c75499824..a7fd82133b12 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -2002,9 +2002,9 @@ location_store(struct mddev *mddev, const char *buf, size_t len)
2002 } else { 2002 } else {
2003 int rv; 2003 int rv;
2004 if (buf[0] == '+') 2004 if (buf[0] == '+')
2005 rv = strict_strtoll(buf+1, 10, &offset); 2005 rv = kstrtoll(buf+1, 10, &offset);
2006 else 2006 else
2007 rv = strict_strtoll(buf, 10, &offset); 2007 rv = kstrtoll(buf, 10, &offset);
2008 if (rv) 2008 if (rv)
2009 return rv; 2009 return rv;
2010 if (offset == 0) 2010 if (offset == 0)
@@ -2139,7 +2139,7 @@ static ssize_t
2139backlog_store(struct mddev *mddev, const char *buf, size_t len) 2139backlog_store(struct mddev *mddev, const char *buf, size_t len)
2140{ 2140{
2141 unsigned long backlog; 2141 unsigned long backlog;
2142 int rv = strict_strtoul(buf, 10, &backlog); 2142 int rv = kstrtoul(buf, 10, &backlog);
2143 if (rv) 2143 if (rv)
2144 return rv; 2144 return rv;
2145 if (backlog > COUNTER_MAX) 2145 if (backlog > COUNTER_MAX)
@@ -2165,7 +2165,7 @@ chunksize_store(struct mddev *mddev, const char *buf, size_t len)
2165 unsigned long csize; 2165 unsigned long csize;
2166 if (mddev->bitmap) 2166 if (mddev->bitmap)
2167 return -EBUSY; 2167 return -EBUSY;
2168 rv = strict_strtoul(buf, 10, &csize); 2168 rv = kstrtoul(buf, 10, &csize);
2169 if (rv) 2169 if (rv)
2170 return rv; 2170 return rv;
2171 if (csize < 512 || 2171 if (csize < 512 ||
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index 1d3fe1a40a9b..4880b69e2e9e 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -380,7 +380,7 @@ static int validate_region_size(struct raid_set *rs, unsigned long region_size)
380static int validate_raid_redundancy(struct raid_set *rs) 380static int validate_raid_redundancy(struct raid_set *rs)
381{ 381{
382 unsigned i, rebuild_cnt = 0; 382 unsigned i, rebuild_cnt = 0;
383 unsigned rebuilds_per_group, copies, d; 383 unsigned rebuilds_per_group = 0, copies, d;
384 unsigned group_size, last_group_start; 384 unsigned group_size, last_group_start;
385 385
386 for (i = 0; i < rs->md.raid_disks; i++) 386 for (i = 0; i < rs->md.raid_disks; i++)
@@ -504,7 +504,7 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
504 * First, parse the in-order required arguments 504 * First, parse the in-order required arguments
505 * "chunk_size" is the only argument of this type. 505 * "chunk_size" is the only argument of this type.
506 */ 506 */
507 if ((strict_strtoul(argv[0], 10, &value) < 0)) { 507 if ((kstrtoul(argv[0], 10, &value) < 0)) {
508 rs->ti->error = "Bad chunk size"; 508 rs->ti->error = "Bad chunk size";
509 return -EINVAL; 509 return -EINVAL;
510 } else if (rs->raid_type->level == 1) { 510 } else if (rs->raid_type->level == 1) {
@@ -585,7 +585,7 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
585 continue; 585 continue;
586 } 586 }
587 587
588 if (strict_strtoul(argv[i], 10, &value) < 0) { 588 if (kstrtoul(argv[i], 10, &value) < 0) {
589 rs->ti->error = "Bad numerical argument given in raid params"; 589 rs->ti->error = "Bad numerical argument given in raid params";
590 return -EINVAL; 590 return -EINVAL;
591 } 591 }
@@ -1181,7 +1181,7 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv)
1181 argv++; 1181 argv++;
1182 1182
1183 /* number of RAID parameters */ 1183 /* number of RAID parameters */
1184 if (strict_strtoul(argv[0], 10, &num_raid_params) < 0) { 1184 if (kstrtoul(argv[0], 10, &num_raid_params) < 0) {
1185 ti->error = "Cannot understand number of RAID parameters"; 1185 ti->error = "Cannot understand number of RAID parameters";
1186 return -EINVAL; 1186 return -EINVAL;
1187 } 1187 }
@@ -1194,7 +1194,7 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv)
1194 return -EINVAL; 1194 return -EINVAL;
1195 } 1195 }
1196 1196
1197 if ((strict_strtoul(argv[num_raid_params], 10, &num_raid_devs) < 0) || 1197 if ((kstrtoul(argv[num_raid_params], 10, &num_raid_devs) < 0) ||
1198 (num_raid_devs >= INT_MAX)) { 1198 (num_raid_devs >= INT_MAX)) {
1199 ti->error = "Cannot understand number of raid devices"; 1199 ti->error = "Cannot understand number of raid devices";
1200 return -EINVAL; 1200 return -EINVAL;
@@ -1388,6 +1388,7 @@ static void raid_status(struct dm_target *ti, status_type_t type,
1388 * performing a "check" of the array. 1388 * performing a "check" of the array.
1389 */ 1389 */
1390 DMEMIT(" %llu", 1390 DMEMIT(" %llu",
1391 (strcmp(rs->md.last_sync_action, "check")) ? 0 :
1391 (unsigned long long) 1392 (unsigned long long)
1392 atomic64_read(&rs->md.resync_mismatches)); 1393 atomic64_read(&rs->md.resync_mismatches));
1393 break; 1394 break;
@@ -1572,6 +1573,62 @@ static void raid_postsuspend(struct dm_target *ti)
1572 mddev_suspend(&rs->md); 1573 mddev_suspend(&rs->md);
1573} 1574}
1574 1575
1576static void attempt_restore_of_faulty_devices(struct raid_set *rs)
1577{
1578 int i;
1579 uint64_t failed_devices, cleared_failed_devices = 0;
1580 unsigned long flags;
1581 struct dm_raid_superblock *sb;
1582 struct md_rdev *r;
1583
1584 for (i = 0; i < rs->md.raid_disks; i++) {
1585 r = &rs->dev[i].rdev;
1586 if (test_bit(Faulty, &r->flags) && r->sb_page &&
1587 sync_page_io(r, 0, r->sb_size, r->sb_page, READ, 1)) {
1588 DMINFO("Faulty %s device #%d has readable super block."
1589 " Attempting to revive it.",
1590 rs->raid_type->name, i);
1591
1592 /*