Skip to content

Commit b302888

Browse files
committed
Merge tag 'md-7.2-20260531' of https://git.kernel.org/pub/scm/linux/kernel/git/mdraid/linux into for-7.2/block
Pull MD updates and fixes from Yu Kuai: "Bug Fixes: - Only requeue dm-raid bios when dm is suspending. (Benjamin Marzinski) - Reset raid10 read_slot when reusing r10bio for discard. (Chen Cheng) - Fix raid1/raid10 deadlock in read error recovery path. (Abd-Alrhman Masalkhi) - Fix raid1/raid10 error-path detection with md_cloned_bio(). (Abd-Alrhman Masalkhi) - Fix raid1/raid10 bio accounting for split md cloned bios. (Abd-Alrhman Masalkhi) - Fix raid1 nr_pending leak in REQ_ATOMIC bad-block path. (Abd-Alrhman Masalkhi) Improvements: - Skip redundant raid_disks updates when the value is unchanged. (Abd-Alrhman Masalkhi) Cleanups: - Update MAINTAINERS email addresses. (Yu Kuai, Li Nan) - Clean up raid1 read error handling. (Christoph Hellwig) - Move the exceed_read_errors condition out of fix_read_error(). (Christoph Hellwig) - Use str_plural() in raid0 dump_zones(). (Thorsten Blum)" * tag 'md-7.2-20260531' of https://git.kernel.org/pub/scm/linux/kernel/git/mdraid/linux: md/raid0: use str_plural helper in dump_zones raid1: fix nr_pending leak in REQ_ATOMIC bad-block error path md/raid1: move the exceed_read_errors condition out of fix_read_error md/raid1: cleanup handle_read_error md/raid1,raid10: fix bio accounting for split md cloned bios md/raid1,raid10: fix error-path detection with md_cloned_bio() md/raid1,raid10: fix deadlock in read error recovery path md/raid10: reset read_slot when reusing r10bio for discard md: skip redundant raid_disks update when value is unchanged dm-raid: only requeue bios when dm is suspending MAINTAINERS: Update Li Nan's E-mail address MAINTAINERS: update Yu Kuai's email address
2 parents 9310b95 + 717359a commit b302888

8 files changed

Lines changed: 96 additions & 57 deletions

File tree

MAINTAINERS

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4478,7 +4478,7 @@ F: Documentation/filesystems/befs.rst
44784478
F: fs/befs/
44794479

44804480
BFQ I/O SCHEDULER
4481-
M: Yu Kuai <yukuai@fnnas.com>
4481+
M: Yu Kuai <yukuai@fygo.io>
44824482
L: linux-block@vger.kernel.org
44834483
S: Odd Fixes
44844484
F: Documentation/block/bfq-iosched.rst
@@ -24796,8 +24796,8 @@ F: include/linux/property.h
2479624796

2479724797
SOFTWARE RAID (Multiple Disks) SUPPORT
2479824798
M: Song Liu <song@kernel.org>
24799-
M: Yu Kuai <yukuai@fnnas.com>
24800-
R: Li Nan <linan122@huawei.com>
24799+
M: Yu Kuai <yukuai@fygo.io>
24800+
R: Li Nan <magiclinan@didiglobal.com>
2480124801
R: Xiao Ni <xiao@kernel.org>
2480224802
L: linux-raid@vger.kernel.org
2480324803
S: Supported

drivers/md/dm-raid.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3831,6 +3831,7 @@ static void raid_presuspend(struct dm_target *ti)
38313831
* resume, raid_postsuspend() is too late.
38323832
*/
38333833
set_bit(RT_FLAG_RS_FROZEN, &rs->runtime_flags);
3834+
set_bit(MD_DM_SUSPENDING, &mddev->flags);
38343835

38353836
if (!reshape_interrupted(mddev))
38363837
return;
@@ -3847,13 +3848,16 @@ static void raid_presuspend(struct dm_target *ti)
38473848
static void raid_presuspend_undo(struct dm_target *ti)
38483849
{
38493850
struct raid_set *rs = ti->private;
3851+
struct mddev *mddev = &rs->md;
38503852

3853+
clear_bit(MD_DM_SUSPENDING, &mddev->flags);
38513854
clear_bit(RT_FLAG_RS_FROZEN, &rs->runtime_flags);
38523855
}
38533856

38543857
static void raid_postsuspend(struct dm_target *ti)
38553858
{
38563859
struct raid_set *rs = ti->private;
3860+
struct mddev *mddev = &rs->md;
38573861

38583862
if (!test_and_set_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags)) {
38593863
/*
@@ -3864,6 +3868,8 @@ static void raid_postsuspend(struct dm_target *ti)
38643868
mddev_suspend(&rs->md, false);
38653869
rs->md.ro = MD_RDONLY;
38663870
}
3871+
clear_bit(MD_DM_SUSPENDING, &mddev->flags);
3872+
38673873
}
38683874

38693875
static void attempt_restore_of_faulty_devices(struct raid_set *rs)

drivers/md/md.c

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -395,17 +395,24 @@ static bool is_suspended(struct mddev *mddev, struct bio *bio)
395395
bool md_handle_request(struct mddev *mddev, struct bio *bio)
396396
{
397397
check_suspended:
398-
if (is_suspended(mddev, bio)) {
399-
/* Bail out if REQ_NOWAIT is set for the bio */
400-
if (bio->bi_opf & REQ_NOWAIT) {
401-
bio_wouldblock_error(bio);
402-
return true;
398+
if (unlikely(md_cloned_bio(mddev, bio))) {
399+
/*
400+
* This bio is an MD cloned bio and already holds an
401+
* active_io reference, so percpu_ref_get() is safe here.
402+
*/
403+
percpu_ref_get(&mddev->active_io);
404+
} else {
405+
if (is_suspended(mddev, bio)) {
406+
/* Bail out if REQ_NOWAIT is set for the bio */
407+
if (bio->bi_opf & REQ_NOWAIT) {
408+
bio_wouldblock_error(bio);
409+
return true;
410+
}
411+
wait_event(mddev->sb_wait, !is_suspended(mddev, bio));
403412
}
404-
wait_event(mddev->sb_wait, !is_suspended(mddev, bio));
413+
if (!percpu_ref_tryget_live(&mddev->active_io))
414+
goto check_suspended;
405415
}
406-
if (!percpu_ref_tryget_live(&mddev->active_io))
407-
goto check_suspended;
408-
409416
if (!mddev->pers->make_request(mddev, bio)) {
410417
percpu_ref_put(&mddev->active_io);
411418
if (mddev_is_dm(mddev) && mddev->pers->prepare_suspend)
@@ -4414,9 +4421,10 @@ raid_disks_store(struct mddev *mddev, const char *buf, size_t len)
44144421
err = mddev_suspend_and_lock(mddev);
44154422
if (err)
44164423
return err;
4417-
if (mddev->pers)
4418-
err = update_raid_disks(mddev, n);
4419-
else if (mddev->reshape_position != MaxSector) {
4424+
if (mddev->pers) {
4425+
if (n != mddev->raid_disks)
4426+
err = update_raid_disks(mddev, n);
4427+
} else if (mddev->reshape_position != MaxSector) {
44204428
struct md_rdev *rdev;
44214429
int olddisks = mddev->raid_disks - mddev->delta_disks;
44224430

drivers/md/md.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ struct md_cluster_operations;
346346
* @MD_HAS_SUPERBLOCK: There is persistence sb in member disks.
347347
* @MD_FAILLAST_DEV: Allow last rdev to be removed.
348348
* @MD_SERIALIZE_POLICY: Enforce write IO is not reordered, just used by raid1.
349+
* @MD_DM_SUSPENDING: This DM raid device is suspending.
349350
*
350351
* change UNSUPPORTED_MDDEV_FLAGS for each array type if new flag is added
351352
*/
@@ -365,6 +366,7 @@ enum mddev_flags {
365366
MD_HAS_SUPERBLOCK,
366367
MD_FAILLAST_DEV,
367368
MD_SERIALIZE_POLICY,
369+
MD_DM_SUSPENDING,
368370
};
369371

370372
enum mddev_sb_flags {
@@ -1042,6 +1044,11 @@ void mddev_update_io_opt(struct mddev *mddev, unsigned int nr_stripes);
10421044

10431045
extern const struct block_device_operations md_fops;
10441046

1047+
static inline bool md_cloned_bio(struct mddev *mddev, struct bio *bio)
1048+
{
1049+
return bio->bi_pool == &mddev->io_clone_set;
1050+
}
1051+
10451052
/*
10461053
* MD devices can be used undeneath by DM, in which case ->gendisk is NULL.
10471054
*/

drivers/md/raid0.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/seq_file.h>
1515
#include <linux/module.h>
1616
#include <linux/slab.h>
17+
#include <linux/string_choices.h>
1718
#include <trace/events/block.h>
1819
#include "md.h"
1920
#include "raid0.h"
@@ -43,7 +44,7 @@ static void dump_zones(struct mddev *mddev)
4344
int raid_disks = conf->strip_zone[0].nb_dev;
4445
pr_debug("md: RAID0 configuration for %s - %d zone%s\n",
4546
mdname(mddev),
46-
conf->nr_strip_zones, conf->nr_strip_zones==1?"":"s");
47+
conf->nr_strip_zones, str_plural(conf->nr_strip_zones));
4748
for (j = 0; j < conf->nr_strip_zones; j++) {
4849
char line[200];
4950
int len = 0;

drivers/md/raid1.c

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,11 +1343,18 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
13431343
bool r1bio_existed = !!r1_bio;
13441344

13451345
/*
1346-
* If r1_bio is set, we are blocking the raid1d thread
1347-
* so there is a tiny risk of deadlock. So ask for
1346+
* An md cloned bio indicates we are in the error path.
1347+
* This is more reliable than checking r1_bio, which might
1348+
* be NULL even in the error path if a failed bio was split.
1349+
*/
1350+
bool err_path = md_cloned_bio(mddev, bio);
1351+
1352+
/*
1353+
* If we are in the error path, we are blocking the raid1d
1354+
* thread so there is a tiny risk of deadlock. So ask for
13481355
* emergency memory if needed.
13491356
*/
1350-
gfp_t gfp = r1_bio ? (GFP_NOIO | __GFP_HIGH) : GFP_NOIO;
1357+
gfp_t gfp = err_path ? (GFP_NOIO | __GFP_HIGH) : GFP_NOIO;
13511358

13521359
/*
13531360
* Still need barrier for READ in case that whole
@@ -1411,7 +1418,7 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
14111418
}
14121419

14131420
r1_bio->read_disk = rdisk;
1414-
if (!r1bio_existed) {
1421+
if (likely(!md_cloned_bio(mddev, bio))) {
14151422
md_account_bio(mddev, &bio);
14161423
r1_bio->master_bio = bio;
14171424
}
@@ -1596,8 +1603,10 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
15961603
* complexity of supporting that is not worth
15971604
* the benefit.
15981605
*/
1599-
if (bio->bi_opf & REQ_ATOMIC)
1606+
if (bio->bi_opf & REQ_ATOMIC) {
1607+
rdev_dec_pending(rdev, mddev);
16001608
goto err_handle;
1609+
}
16011610

16021611
good_sectors = first_bad - r1_bio->sector;
16031612
if (good_sectors < max_sectors)
@@ -2411,11 +2420,6 @@ static void fix_read_error(struct r1conf *conf, struct r1bio *r1_bio)
24112420
struct mddev *mddev = conf->mddev;
24122421
struct md_rdev *rdev = conf->mirrors[read_disk].rdev;
24132422

2414-
if (exceed_read_errors(mddev, rdev)) {
2415-
r1_bio->bios[r1_bio->read_disk] = IO_BLOCKED;
2416-
return;
2417-
}
2418-
24192423
while(sectors) {
24202424
int s = sectors;
24212425
int d = read_disk;
@@ -2627,35 +2631,36 @@ static void handle_write_finished(struct r1conf *conf, struct r1bio *r1_bio)
26272631

26282632
static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio)
26292633
{
2634+
struct md_rdev *rdev = conf->mirrors[r1_bio->read_disk].rdev;
2635+
struct bio *bio = r1_bio->bios[r1_bio->read_disk];
26302636
struct mddev *mddev = conf->mddev;
2631-
struct bio *bio;
2632-
struct md_rdev *rdev;
26332637
sector_t sector;
26342638

26352639
clear_bit(R1BIO_ReadError, &r1_bio->state);
2636-
/* we got a read error. Maybe the drive is bad. Maybe just
2637-
* the block and we can fix it.
2638-
* We freeze all other IO, and try reading the block from
2639-
* other devices. When we find one, we re-write
2640-
* and check it that fixes the read error.
2641-
* This is all done synchronously while the array is
2642-
* frozen
2643-
*/
26442640

2645-
bio = r1_bio->bios[r1_bio->read_disk];
26462641
bio_put(bio);
26472642
r1_bio->bios[r1_bio->read_disk] = NULL;
26482643

2649-
rdev = conf->mirrors[r1_bio->read_disk].rdev;
2650-
if (mddev->ro == 0
2651-
&& !test_bit(FailFast, &rdev->flags)) {
2652-
freeze_array(conf, 1);
2653-
fix_read_error(conf, r1_bio);
2654-
unfreeze_array(conf);
2655-
} else if (mddev->ro == 0 && test_bit(FailFast, &rdev->flags)) {
2644+
/*
2645+
* We got a read error. Maybe the drive is bad. Maybe just the block
2646+
* and we can fix it.
2647+
*
2648+
* If allowed, freeze all other IO, and try reading the block from other
2649+
* devices. If we find one, we re-write and check it that fixes the
2650+
* read error. This is all done synchronously while the array is
2651+
* frozen.
2652+
*/
2653+
if (mddev->ro) {
2654+
r1_bio->bios[r1_bio->read_disk] = IO_BLOCKED;
2655+
} else if (test_bit(FailFast, &rdev->flags)) {
26562656
md_error(mddev, rdev);
26572657
} else {
2658-
r1_bio->bios[r1_bio->read_disk] = IO_BLOCKED;
2658+
freeze_array(conf, 1);
2659+
if (exceed_read_errors(mddev, rdev))
2660+
r1_bio->bios[r1_bio->read_disk] = IO_BLOCKED;
2661+
else
2662+
fix_read_error(conf, r1_bio);
2663+
unfreeze_array(conf);
26592664
}
26602665

26612666
rdev_dec_pending(rdev, conf->mddev);

drivers/md/raid10.c

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,7 +1146,7 @@ static bool regular_request_wait(struct mddev *mddev, struct r10conf *conf,
11461146
}
11471147

11481148
static void raid10_read_request(struct mddev *mddev, struct bio *bio,
1149-
struct r10bio *r10_bio, bool io_accounting)
1149+
struct r10bio *r10_bio)
11501150
{
11511151
struct r10conf *conf = mddev->private;
11521152
struct bio *read_bio;
@@ -1155,7 +1155,20 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio,
11551155
char b[BDEVNAME_SIZE];
11561156
int slot = r10_bio->read_slot;
11571157
struct md_rdev *err_rdev = NULL;
1158-
gfp_t gfp = GFP_NOIO;
1158+
1159+
/*
1160+
* An md cloned bio indicates we are in the error path.
1161+
* This is more reliable than checking slot, which might
1162+
* be -1 even in the error path if a failed bio was split.
1163+
*/
1164+
bool err_path = md_cloned_bio(mddev, bio);
1165+
1166+
/*
1167+
* If we are in the error path, we are blocking the raid10d
1168+
* thread so there is a tiny risk of deadlock. So ask for
1169+
* emergency memory if needed.
1170+
*/
1171+
gfp_t gfp = err_path ? (GFP_NOIO | __GFP_HIGH) : GFP_NOIO;
11591172

11601173
if (slot >= 0 && r10_bio->devs[slot].rdev) {
11611174
/*
@@ -1166,11 +1179,6 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio,
11661179
* we lose the device name in error messages.
11671180
*/
11681181
int disk;
1169-
/*
1170-
* As we are blocking raid10, it is a little safer to
1171-
* use __GFP_HIGH.
1172-
*/
1173-
gfp = GFP_NOIO | __GFP_HIGH;
11741182

11751183
disk = r10_bio->devs[slot].devnum;
11761184
err_rdev = conf->mirrors[disk].rdev;
@@ -1218,7 +1226,7 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio,
12181226
}
12191227
slot = r10_bio->read_slot;
12201228

1221-
if (io_accounting) {
1229+
if (likely(!md_cloned_bio(mddev, bio))) {
12221230
md_account_bio(mddev, &bio);
12231231
r10_bio->master_bio = bio;
12241232
}
@@ -1544,7 +1552,7 @@ static void __make_request(struct mddev *mddev, struct bio *bio, int sectors)
15441552
conf->geo.raid_disks);
15451553

15461554
if (bio_data_dir(bio) == READ)
1547-
raid10_read_request(mddev, bio, r10_bio, true);
1555+
raid10_read_request(mddev, bio, r10_bio);
15481556
else
15491557
raid10_write_request(mddev, bio, r10_bio);
15501558
}
@@ -1727,6 +1735,7 @@ static int raid10_handle_discard(struct mddev *mddev, struct bio *bio)
17271735
r10_bio->mddev = mddev;
17281736
r10_bio->state = 0;
17291737
r10_bio->sectors = 0;
1738+
r10_bio->read_slot = -1;
17301739
memset(r10_bio->devs, 0, sizeof(r10_bio->devs[0]) * geo->raid_disks);
17311740
wait_blocked_dev(mddev, r10_bio);
17321741

@@ -2858,7 +2867,7 @@ static void handle_read_error(struct mddev *mddev, struct r10bio *r10_bio)
28582867

28592868
rdev_dec_pending(rdev, mddev);
28602869
r10_bio->state = 0;
2861-
raid10_read_request(mddev, r10_bio->master_bio, r10_bio, false);
2870+
raid10_read_request(mddev, r10_bio->master_bio, r10_bio);
28622871
/*
28632872
* allow_barrier after re-submit to ensure no sync io
28642873
* can be issued while regular io pending.

drivers/md/raid5.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6042,8 +6042,11 @@ static enum stripe_result make_stripe_request(struct mddev *mddev,
60426042
raid5_release_stripe(sh);
60436043
out:
60446044
if (ret == STRIPE_SCHEDULE_AND_RETRY && reshape_interrupted(mddev)) {
6045-
bi->bi_status = BLK_STS_RESOURCE;
6046-
ret = STRIPE_WAIT_RESHAPE;
6045+
if (!mddev_is_dm(mddev) ||
6046+
test_bit(MD_DM_SUSPENDING, &mddev->flags)) {
6047+
bi->bi_status = BLK_STS_RESOURCE;
6048+
ret = STRIPE_WAIT_RESHAPE;
6049+
}
60476050
pr_err_ratelimited("dm-raid456: io across reshape position while reshape can't make progress");
60486051
}
60496052
return ret;

0 commit comments

Comments
 (0)