Skip to content

Commit 075c8d3

Browse files
committed
md: add error_handlers for raid0 and linear
jira LE-1907 Rebuild_History Non-Buildable kernel-5.14.0-284.30.1.el9_2 commit-author Mariusz Tkaczyk <[email protected]> commit c31fea2 After the commit 9631abd("md: Set MD_BROKEN for RAID1 and RAID10") MD_BROKEN must be set if array is failed because state_store() checks it. If it is set then -EBUSY is returned to userspace. For raid0 and linear MD_BROKEN is not set by error_handler(). As a result mdadm is unable to trigger clean-up actions. It is a regression. This patch adds appropriate error_handler for raid0 and linear. The error handler sets MD_BROKEN for this device. Reviewed-by: Xiao Ni <[email protected]> Signed-off-by: Mariusz Tkaczyk <[email protected]> Signed-off-by: Song Liu <[email protected]> Link: https://lore.kernel.org/r/[email protected] (cherry picked from commit c31fea2) Signed-off-by: Jonathan Maple <[email protected]>
1 parent cad9ac0 commit 075c8d3

File tree

4 files changed

+31
-10
lines changed

4 files changed

+31
-10
lines changed

drivers/md/md-linear.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,8 @@ static bool linear_make_request(struct mddev *mddev, struct bio *bio)
223223
bio_sector < start_sector))
224224
goto out_of_bounds;
225225

226-
if (unlikely(is_mddev_broken(tmp_dev->rdev, "linear"))) {
226+
if (unlikely(is_rdev_broken(tmp_dev->rdev))) {
227+
md_error(mddev, tmp_dev->rdev);
227228
bio_io_error(bio);
228229
return true;
229230
}
@@ -270,6 +271,16 @@ static void linear_status (struct seq_file *seq, struct mddev *mddev)
270271
seq_printf(seq, " %dk rounding", mddev->chunk_sectors / 2);
271272
}
272273

274+
static void linear_error(struct mddev *mddev, struct md_rdev *rdev)
275+
{
276+
if (!test_and_set_bit(MD_BROKEN, &mddev->flags)) {
277+
char *md_name = mdname(mddev);
278+
279+
pr_crit("md/linear%s: Disk failure on %pg detected, failing array.\n",
280+
md_name, rdev->bdev);
281+
}
282+
}
283+
273284
static void linear_quiesce(struct mddev *mddev, int state)
274285
{
275286
}
@@ -286,6 +297,7 @@ static struct md_personality linear_personality =
286297
.hot_add_disk = linear_add,
287298
.size = linear_size,
288299
.quiesce = linear_quiesce,
300+
.error_handler = linear_error,
289301
};
290302

291303
static int __init linear_init (void)

drivers/md/md.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7984,6 +7984,9 @@ void md_error(struct mddev *mddev, struct md_rdev *rdev)
79847984
return;
79857985
mddev->pers->error_handler(mddev, rdev);
79867986

7987+
if (mddev->pers->level == 0 || mddev->pers->level == LEVEL_LINEAR)
7988+
return;
7989+
79877990
if (mddev->degraded && !test_bit(MD_BROKEN, &mddev->flags))
79887991
set_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
79897992
sysfs_notify_dirent_safe(rdev->sysfs_state);

drivers/md/md.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -790,15 +790,9 @@ extern void mddev_destroy_serial_pool(struct mddev *mddev, struct md_rdev *rdev,
790790
struct md_rdev *md_find_rdev_nr_rcu(struct mddev *mddev, int nr);
791791
struct md_rdev *md_find_rdev_rcu(struct mddev *mddev, dev_t dev);
792792

793-
static inline bool is_mddev_broken(struct md_rdev *rdev, const char *md_type)
793+
static inline bool is_rdev_broken(struct md_rdev *rdev)
794794
{
795-
if (!disk_live(rdev->bdev->bd_disk)) {
796-
if (!test_and_set_bit(MD_BROKEN, &rdev->mddev->flags))
797-
pr_warn("md: %s: %s array has a missing/failed member\n",
798-
mdname(rdev->mddev), md_type);
799-
return true;
800-
}
801-
return false;
795+
return !disk_live(rdev->bdev->bd_disk);
802796
}
803797

804798
static inline void rdev_dec_pending(struct md_rdev *rdev, struct mddev *mddev)

drivers/md/raid0.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,8 +569,9 @@ static bool raid0_make_request(struct mddev *mddev, struct bio *bio)
569569
return true;
570570
}
571571

572-
if (unlikely(is_mddev_broken(tmp_dev, "raid0"))) {
572+
if (unlikely(is_rdev_broken(tmp_dev))) {
573573
bio_io_error(bio);
574+
md_error(mddev, tmp_dev);
574575
return true;
575576
}
576577

@@ -592,6 +593,16 @@ static void raid0_status(struct seq_file *seq, struct mddev *mddev)
592593
return;
593594
}
594595

596+
static void raid0_error(struct mddev *mddev, struct md_rdev *rdev)
597+
{
598+
if (!test_and_set_bit(MD_BROKEN, &mddev->flags)) {
599+
char *md_name = mdname(mddev);
600+
601+
pr_crit("md/raid0%s: Disk failure on %pg detected, failing array.\n",
602+
md_name, rdev->bdev);
603+
}
604+
}
605+
595606
static void *raid0_takeover_raid45(struct mddev *mddev)
596607
{
597608
struct md_rdev *rdev;
@@ -767,6 +778,7 @@ static struct md_personality raid0_personality=
767778
.size = raid0_size,
768779
.takeover = raid0_takeover,
769780
.quiesce = raid0_quiesce,
781+
.error_handler = raid0_error,
770782
};
771783

772784
static int __init raid0_init (void)

0 commit comments

Comments
 (0)