Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 697a067

Browse files
committed
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
2 parents e61aca5 + 1376512 commit 697a067

File tree

10 files changed

+187
-70
lines changed

10 files changed

+187
-70
lines changed

Documentation/device-mapper/dm-raid.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,3 +222,5 @@ Version History
222222
1.4.2 Add RAID10 "far" and "offset" algorithm support.
223223
1.5.0 Add message interface to allow manipulation of the sync_action.
224224
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".

Documentation/md.txt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -566,13 +566,6 @@ also have
566566
when it reaches the current sync_max (below) and possibly at
567567
other times.
568568

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-
576569
sync_speed
577570
This shows the current actual speed, in K/sec, of the current
578571
sync_action. It is averaged over the last 30 seconds.
@@ -593,6 +586,12 @@ also have
593586
that number to reach sync_max. Then you can either increase
594587
"sync_max", or can write 'idle' to "sync_action".
595588

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+
596595

597596
Each active md device may also have attributes specific to the
598597
personality module that manages it.

drivers/md/bitmap.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2002,9 +2002,9 @@ location_store(struct mddev *mddev, const char *buf, size_t len)
20022002
} else {
20032003
int rv;
20042004
if (buf[0] == '+')
2005-
rv = strict_strtoll(buf+1, 10, &offset);
2005+
rv = kstrtoll(buf+1, 10, &offset);
20062006
else
2007-
rv = strict_strtoll(buf, 10, &offset);
2007+
rv = kstrtoll(buf, 10, &offset);
20082008
if (rv)
20092009
return rv;
20102010
if (offset == 0)
@@ -2139,7 +2139,7 @@ static ssize_t
21392139
backlog_store(struct mddev *mddev, const char *buf, size_t len)
21402140
{
21412141
unsigned long backlog;
2142-
int rv = strict_strtoul(buf, 10, &backlog);
2142+
int rv = kstrtoul(buf, 10, &backlog);
21432143
if (rv)
21442144
return rv;
21452145
if (backlog > COUNTER_MAX)
@@ -2165,7 +2165,7 @@ chunksize_store(struct mddev *mddev, const char *buf, size_t len)
21652165
unsigned long csize;
21662166
if (mddev->bitmap)
21672167
return -EBUSY;
2168-
rv = strict_strtoul(buf, 10, &csize);
2168+
rv = kstrtoul(buf, 10, &csize);
21692169
if (rv)
21702170
return rv;
21712171
if (csize < 512 ||

drivers/md/dm-raid.c

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ static int validate_region_size(struct raid_set *rs, unsigned long region_size)
380380
static int validate_raid_redundancy(struct raid_set *rs)
381381
{
382382
unsigned i, rebuild_cnt = 0;
383-
unsigned rebuilds_per_group, copies, d;
383+
unsigned rebuilds_per_group = 0, copies, d;
384384
unsigned group_size, last_group_start;
385385

386386
for (i = 0; i < rs->md.raid_disks; i++)
@@ -504,7 +504,7 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
504504
* First, parse the in-order required arguments
505505
* "chunk_size" is the only argument of this type.
506506
*/
507-
if ((strict_strtoul(argv[0], 10, &value) < 0)) {
507+
if ((kstrtoul(argv[0], 10, &value) < 0)) {
508508
rs->ti->error = "Bad chunk size";
509509
return -EINVAL;
510510
} else if (rs->raid_type->level == 1) {
@@ -585,7 +585,7 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
585585
continue;
586586
}
587587

588-
if (strict_strtoul(argv[i], 10, &value) < 0) {
588+
if (kstrtoul(argv[i], 10, &value) < 0) {
589589
rs->ti->error = "Bad numerical argument given in raid params";
590590
return -EINVAL;
591591
}
@@ -1181,7 +1181,7 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv)
11811181
argv++;
11821182

11831183
/* 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) {
11851185
ti->error = "Cannot understand number of RAID parameters";
11861186
return -EINVAL;
11871187
}
@@ -1194,7 +1194,7 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv)
11941194
return -EINVAL;
11951195
}
11961196

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) ||
11981198
(num_raid_devs >= INT_MAX)) {
11991199
ti->error = "Cannot understand number of raid devices";
12001200
return -EINVAL;
@@ -1388,6 +1388,7 @@ static void raid_status(struct dm_target *ti, status_type_t type,
13881388
* performing a "check" of the array.
13891389
*/
13901390
DMEMIT(" %llu",
1391+
(strcmp(rs->md.last_sync_action, "check")) ? 0 :
13911392
(unsigned long long)
13921393
atomic64_read(&rs->md.resync_mismatches));
13931394
break;
@@ -1572,6 +1573,62 @@ static void raid_postsuspend(struct dm_target *ti)
15721573
mddev_suspend(&rs->md);
15731574
}
15741575

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+
/*
1593+
* Faulty bit may be set, but sometimes the array can
1594+
* be suspended before the personalities can respond
1595+
* by removing the device from the array (i.e. calling
1596+
* 'hot_remove_disk'). If they haven't yet removed
1597+
* the failed device, its 'raid_disk' number will be
1598+
* '>= 0' - meaning we must call this function
1599+
* ourselves.
1600+
*/
1601+
if ((r->raid_disk >= 0) &&
1602+
(r->mddev->pers->hot_remove_disk(r->mddev, r) != 0))
1603+
/* Failed to revive this device, try next */
1604+
continue;
1605+
1606+
r->raid_disk = i;
1607+
r->saved_raid_disk = i;
1608+
flags = r->flags;
1609+
clear_bit(Faulty, &r->flags);
1610+
clear_bit(WriteErrorSeen, &r->flags);
1611+
clear_bit(In_sync, &r->flags);
1612+
if (r->mddev->pers->hot_add_disk(r->mddev, r)) {
1613+
r->raid_disk = -1;
1614+
r->saved_raid_disk = -1;
1615+
r->flags = flags;
1616+
} else {
1617+
r->recovery_offset = 0;
1618+
cleared_failed_devices |= 1 << i;
1619+
}
1620+
}
1621+
}
1622+
if (cleared_failed_devices) {
1623+
rdev_for_each(r, &rs->md) {
1624+
sb = page_address(r->sb_page);
1625+
failed_devices = le64_to_cpu(sb->failed_devices);
1626+
failed_devices &= ~cleared_failed_devices;
1627+
sb->failed_devices = cpu_to_le64(failed_devices);
1628+
}
1629+
}
1630+
}
1631+
15751632
static void raid_resume(struct dm_target *ti)
15761633
{
15771634
struct raid_set *rs = ti->private;
@@ -1580,6 +1637,13 @@ static void raid_resume(struct dm_target *ti)
15801637
if (!rs->bitmap_loaded) {
15811638
bitmap_load(&rs->md);
15821639
rs->bitmap_loaded = 1;
1640+
} else {
1641+
/*
1642+
* A secondary resume while the device is active.
1643+
* Take this opportunity to check whether any failed
1644+
* devices are reachable again.
1645+
*/
1646+
attempt_restore_of_faulty_devices(rs);
15831647
}
15841648

15851649
clear_bit(MD_RECOVERY_FROZEN, &rs->md.recovery);
@@ -1588,7 +1652,7 @@ static void raid_resume(struct dm_target *ti)
15881652

15891653
static struct target_type raid_target = {
15901654
.name = "raid",
1591-
.version = {1, 5, 0},
1655+
.version = {1, 5, 2},
15921656
.module = THIS_MODULE,
15931657
.ctr = raid_ctr,
15941658
.dtr = raid_dtr,

drivers/md/md.c

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,7 @@ void mddev_init(struct mddev *mddev)
521521
init_waitqueue_head(&mddev->recovery_wait);
522522
mddev->reshape_position = MaxSector;
523523
mddev->reshape_backwards = 0;
524+
mddev->last_sync_action = "none";
524525
mddev->resync_min = 0;
525526
mddev->resync_max = MaxSector;
526527
mddev->level = LEVEL_NONE;
@@ -2867,7 +2868,7 @@ static ssize_t
28672868
offset_store(struct md_rdev *rdev, const char *buf, size_t len)
28682869
{
28692870
unsigned long long offset;
2870-
if (strict_strtoull(buf, 10, &offset) < 0)
2871+
if (kstrtoull(buf, 10, &offset) < 0)
28712872
return -EINVAL;
28722873
if (rdev->mddev->pers && rdev->raid_disk >= 0)
28732874
return -EBUSY;
@@ -2895,7 +2896,7 @@ static ssize_t new_offset_store(struct md_rdev *rdev,
28952896
unsigned long long new_offset;
28962897
struct mddev *mddev = rdev->mddev;
28972898

2898-
if (strict_strtoull(buf, 10, &new_offset) < 0)
2899+
if (kstrtoull(buf, 10, &new_offset) < 0)
28992900
return -EINVAL;
29002901

29012902
if (mddev->sync_thread)
@@ -2961,7 +2962,7 @@ static int strict_blocks_to_sectors(const char *buf, sector_t *sectors)
29612962
unsigned long long blocks;
29622963
sector_t new;
29632964

2964-
if (strict_strtoull(buf, 10, &blocks) < 0)
2965+
if (kstrtoull(buf, 10, &blocks) < 0)
29652966
return -EINVAL;
29662967

29672968
if (blocks & 1ULL << (8 * sizeof(blocks) - 1))
@@ -3069,7 +3070,7 @@ static ssize_t recovery_start_store(struct md_rdev *rdev, const char *buf, size_
30693070

30703071
if (cmd_match(buf, "none"))
30713072
recovery_start = MaxSector;
3072-
else if (strict_strtoull(buf, 10, &recovery_start))
3073+
else if (kstrtoull(buf, 10, &recovery_start))
30733074
return -EINVAL;
30743075

30753076
if (rdev->mddev->pers &&
@@ -3497,7 +3498,7 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
34973498
if (clevel[len-1] == '\n')
34983499
len--;
34993500
clevel[len] = 0;
3500-
if (strict_strtol(clevel, 10, &level))
3501+
if (kstrtol(clevel, 10, &level))
35013502
level = LEVEL_NONE;
35023503

35033504
if (request_module("md-%s", clevel) != 0)
@@ -4272,6 +4273,17 @@ action_store(struct mddev *mddev, const char *page, size_t len)
42724273
return len;
42734274
}
42744275

4276+
static struct md_sysfs_entry md_scan_mode =
4277+
__ATTR(sync_action, S_IRUGO|S_IWUSR, action_show, action_store);
4278+
4279+
static ssize_t
4280+
last_sync_action_show(struct mddev *mddev, char *page)
4281+
{
4282+
return sprintf(page, "%s\n", mddev->last_sync_action);
4283+
}
4284+
4285+
static struct md_sysfs_entry md_last_scan_mode = __ATTR_RO(last_sync_action);
4286+
42754287
static ssize_t
42764288
mismatch_cnt_show(struct mddev *mddev, char *page)
42774289
{
@@ -4280,10 +4292,6 @@ mismatch_cnt_show(struct mddev *mddev, char *page)
42804292
atomic64_read(&mddev->resync_mismatches));
42814293
}
42824294

4283-
static struct md_sysfs_entry md_scan_mode =
4284-
__ATTR(sync_action, S_IRUGO|S_IWUSR, action_show, action_store);
4285-
4286-
42874295
static struct md_sysfs_entry md_mismatches = __ATTR_RO(mismatch_cnt);
42884296

42894297
static ssize_t
@@ -4356,7 +4364,7 @@ sync_force_parallel_store(struct mddev *mddev, const char *buf, size_t len)
43564364
{
43574365
long n;
43584366

4359-
if (strict_strtol(buf, 10, &n))
4367+
if (kstrtol(buf, 10, &n))
43604368
return -EINVAL;
43614369

43624370
if (n != 0 && n != 1)
@@ -4424,7 +4432,7 @@ static ssize_t
44244432
min_sync_store(struct mddev *mddev, const char *buf, size_t len)
44254433
{
44264434
unsigned long long min;
4427-
if (strict_strtoull(buf, 10, &min))
4435+
if (kstrtoull(buf, 10, &min))
44284436
return -EINVAL;
44294437
if (min > mddev->resync_max)
44304438
return -EINVAL;
@@ -4461,7 +4469,7 @@ max_sync_store(struct mddev *mddev, const char *buf, size_t len)
44614469
mddev->resync_max = MaxSector;
44624470
else {
44634471
unsigned long long max;
4464-
if (strict_strtoull(buf, 10, &max))
4472+
if (kstrtoull(buf, 10, &max))
44654473
return -EINVAL;
44664474
if (max < mddev->resync_min)
44674475
return -EINVAL;
@@ -4686,6 +4694,7 @@ static struct attribute *md_default_attrs[] = {
46864694

46874695
static struct attribute *md_redundancy_attrs[] = {
46884696
&md_scan_mode.attr,
4697+
&md_last_scan_mode.attr,
46894698
&md_mismatches.attr,
46904699
&md_sync_min.attr,
46914700
&md_sync_max.attr,
@@ -6405,6 +6414,12 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
64056414
/* need to ensure md_delayed_delete() has completed */
64066415
flush_workqueue(md_misc_wq);
64076416

6417+
if (cmd == HOT_REMOVE_DISK)
6418+
/* need to ensure recovery thread has run */
6419+
wait_event_interruptible_timeout(mddev->sb_wait,
6420+
!test_bit(MD_RECOVERY_NEEDED,
6421+
&mddev->flags),
6422+
msecs_to_jiffies(5000));
64086423
err = mddev_lock(mddev);
64096424
if (err) {
64106425
printk(KERN_INFO
@@ -7323,7 +7338,7 @@ void md_do_sync(struct md_thread *thread)
73237338
sector_t last_check;
73247339
int skipped = 0;
73257340
struct md_rdev *rdev;
7326-
char *desc;
7341+
char *desc, *action = NULL;
73277342
struct blk_plug plug;
73287343

73297344
/* just incase thread restarts... */
@@ -7333,17 +7348,21 @@ void md_do_sync(struct md_thread *thread)
73337348
return;
73347349

73357350
if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
7336-
if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery))
7351+
if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery)) {
73377352
desc = "data-check";
7338-
else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
7353+
action = "check";
7354+
} else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
73397355
desc = "requested-resync";
7340-
else
7356+
action = "repair";
7357+
} else
73417358
desc = "resync";
73427359
} else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
73437360
desc = "reshape";
73447361
else
73457362
desc = "recovery";
73467363

7364+
mddev->last_sync_action = action ?: desc;
7365+
73477366
/* we overload curr_resync somewhat here.
73487367
* 0 == not engaged in resync at all
73497368
* 2 == checking that there is no conflict with another sync
@@ -7892,6 +7911,8 @@ void md_check_recovery(struct mddev *mddev)
78927911
md_new_event(mddev);
78937912
}
78947913
unlock:
7914+
wake_up(&mddev->sb_wait);
7915+
78957916
if (!mddev->sync_thread) {
78967917
clear_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
78977918
if (test_and_clear_bit(MD_RECOVERY_RECOVER,

drivers/md/md.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,14 @@ struct mddev {
268268

269269
struct md_thread *thread; /* management thread */
270270
struct md_thread *sync_thread; /* doing resync or reconstruct */
271+
272+
/* 'last_sync_action' is initialized to "none". It is set when a
273+
* sync operation (i.e "data-check", "requested-resync", "resync",
274+
* "recovery", or "reshape") is started. It holds this value even
275+
* when the sync thread is "frozen" (interrupted) or "idle" (stopped
276+
* or finished). It is overwritten when a new sync operation is begun.
277+
*/
278+
char *last_sync_action;
271279
sector_t curr_resync; /* last block scheduled */
272280
/* As resync requests can complete out of order, we cannot easily track
273281
* how much resync has been completed. So we occasionally pause until

drivers/md/raid0.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,7 @@ static void *raid0_takeover_raid45(struct mddev *mddev)
597597
mdname(mddev));
598598
return ERR_PTR(-EINVAL);
599599
}
600+
rdev->sectors = mddev->dev_sectors;
600601
}
601602

602603
/* Set new parameters */

0 commit comments

Comments
 (0)