diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-04 14:36:50 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-04 14:36:50 -0400 |
| commit | 697a067f1ec67f2f8dfafd0a1b95a46997a11f32 (patch) | |
| tree | 7f0f4bc39ee00944fdc45fd447a0527f77a9582a | |
| parent | e61aca5158a84932cf9fbbcbf8aef9cef63f5026 (diff) | |
| parent | 1376512065b23f39d5f9a160948f313397dde972 (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.txt | 2 | ||||
| -rw-r--r-- | Documentation/md.txt | 13 | ||||
| -rw-r--r-- | drivers/md/bitmap.c | 8 | ||||
| -rw-r--r-- | drivers/md/dm-raid.c | 76 | ||||
| -rw-r--r-- | drivers/md/md.c | 53 | ||||
| -rw-r--r-- | drivers/md/md.h | 8 | ||||
| -rw-r--r-- | drivers/md/raid0.c | 1 | ||||
| -rw-r--r-- | drivers/md/raid1.c | 7 | ||||
| -rw-r--r-- | drivers/md/raid10.c | 83 | ||||
| -rw-r--r-- | drivers/md/raid5.c | 6 |
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 | |||
| 222 | 1.4.2 Add RAID10 "far" and "offset" algorithm support. | 222 | 1.4.2 Add RAID10 "far" and "offset" algorithm support. |
| 223 | 1.5.0 Add message interface to allow manipulation of the sync_action. | 223 | 1.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. |
| 225 | 1.5.1 Add ability to restore transiently failed devices on resume. | ||
| 226 | 1.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 | ||
| 597 | Each active md device may also have attributes specific to the | 596 | Each active md device may also have attributes specific to the |
| 598 | personality module that manages it. | 597 | personality 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 | |||
| 2139 | backlog_store(struct mddev *mddev, const char *buf, size_t len) | 2139 | backlog_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) | |||
| 380 | static int validate_raid_redundancy(struct raid_set *rs) | 380 | static 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 | ||
| 1576 | static 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 | /* | ||
