Skip to content

Commit 0b66deb

Browse files
committed
Merge tag 'md-6.13-20241105' of https://git.kernel.org/pub/scm/linux/kernel/git/song/md into for-6.13/block
Pull MD changes from Song: "1. Enhance handling of faulty and blocked devices, by Yu Kuai. 2. raid5-ppl atomic improvement, by Uros Bizjak. 3. md-bitmap fix, by Yuan Can." * tag 'md-6.13-20241105' of https://git.kernel.org/pub/scm/linux/kernel/git/song/md: md/md-bitmap: Add missing destroy_work_on_stack() md/raid5: don't set Faulty rdev for blocked_rdev md/raid10: don't wait for Faulty rdev in wait_blocked_rdev() md/raid1: don't wait for Faulty rdev in wait_blocked_rdev() md/raid1: factor out helper to handle blocked rdev from raid1_write_request() md: don't record new badblocks for faulty rdev md: don't wait faulty rdev in md_wait_for_blocked_rdev() md: add a new helper rdev_blocked() md/raid5-ppl: Use atomic64_inc_return() in ppl_new_iounit()
2 parents 91ff97a + 6012169 commit 0b66deb

File tree

7 files changed

+101
-69
lines changed

7 files changed

+101
-69
lines changed

drivers/md/md-bitmap.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,6 +1285,7 @@ static void bitmap_unplug_async(struct bitmap *bitmap)
12851285

12861286
queue_work(md_bitmap_wq, &unplug_work.work);
12871287
wait_for_completion(&done);
1288+
destroy_work_on_stack(&unplug_work.work);
12881289
}
12891290

12901291
static void bitmap_unplug(struct mddev *mddev, bool sync)

drivers/md/md.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9762,9 +9762,7 @@ EXPORT_SYMBOL(md_reap_sync_thread);
97629762
void md_wait_for_blocked_rdev(struct md_rdev *rdev, struct mddev *mddev)
97639763
{
97649764
sysfs_notify_dirent_safe(rdev->sysfs_state);
9765-
wait_event_timeout(rdev->blocked_wait,
9766-
!test_bit(Blocked, &rdev->flags) &&
9767-
!test_bit(BlockedBadBlocks, &rdev->flags),
9765+
wait_event_timeout(rdev->blocked_wait, !rdev_blocked(rdev),
97689766
msecs_to_jiffies(5000));
97699767
rdev_dec_pending(rdev, mddev);
97709768
}
@@ -9793,6 +9791,17 @@ int rdev_set_badblocks(struct md_rdev *rdev, sector_t s, int sectors,
97939791
{
97949792
struct mddev *mddev = rdev->mddev;
97959793
int rv;
9794+
9795+
/*
9796+
* Recording new badblocks for faulty rdev will force unnecessary
9797+
* super block updating. This is fragile for external management because
9798+
* userspace daemon may trying to remove this device and deadlock may
9799+
* occur. This will be probably solved in the mdadm, but it is safer to
9800+
* avoid it.
9801+
*/
9802+
if (test_bit(Faulty, &rdev->flags))
9803+
return 1;
9804+
97969805
if (is_new)
97979806
s += rdev->new_data_offset;
97989807
else

drivers/md/md.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,6 +1002,30 @@ static inline void mddev_trace_remap(struct mddev *mddev, struct bio *bio,
10021002
trace_block_bio_remap(bio, disk_devt(mddev->gendisk), sector);
10031003
}
10041004

1005+
static inline bool rdev_blocked(struct md_rdev *rdev)
1006+
{
1007+
/*
1008+
* Blocked will be set by error handler and cleared by daemon after
1009+
* updating superblock, meanwhile write IO should be blocked to prevent
1010+
* reading old data after power failure.
1011+
*/
1012+
if (test_bit(Blocked, &rdev->flags))
1013+
return true;
1014+
1015+
/*
1016+
* Faulty device should not be accessed anymore, there is no need to
1017+
* wait for bad block to be acknowledged.
1018+
*/
1019+
if (test_bit(Faulty, &rdev->flags))
1020+
return false;
1021+
1022+
/* rdev is blocked by badblocks. */
1023+
if (test_bit(BlockedBadBlocks, &rdev->flags))
1024+
return true;
1025+
1026+
return false;
1027+
}
1028+
10051029
#define mddev_add_trace_msg(mddev, fmt, args...) \
10061030
do { \
10071031
if (!mddev_is_dm(mddev)) \

drivers/md/raid1.c

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,14 +1412,47 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
14121412
submit_bio_noacct(read_bio);
14131413
}
14141414

1415+
static bool wait_blocked_rdev(struct mddev *mddev, struct bio *bio)
1416+
{
1417+
struct r1conf *conf = mddev->private;
1418+
int disks = conf->raid_disks * 2;
1419+
int i;
1420+
1421+
retry:
1422+
for (i = 0; i < disks; i++) {
1423+
struct md_rdev *rdev = conf->mirrors[i].rdev;
1424+
1425+
if (!rdev)
1426+
continue;
1427+
1428+
/* don't write here until the bad block is acknowledged */
1429+
if (test_bit(WriteErrorSeen, &rdev->flags) &&
1430+
rdev_has_badblock(rdev, bio->bi_iter.bi_sector,
1431+
bio_sectors(bio)) < 0)
1432+
set_bit(BlockedBadBlocks, &rdev->flags);
1433+
1434+
if (rdev_blocked(rdev)) {
1435+
if (bio->bi_opf & REQ_NOWAIT)
1436+
return false;
1437+
1438+
mddev_add_trace_msg(rdev->mddev, "raid1 wait rdev %d blocked",
1439+
rdev->raid_disk);
1440+
atomic_inc(&rdev->nr_pending);
1441+
md_wait_for_blocked_rdev(rdev, rdev->mddev);
1442+
goto retry;
1443+
}
1444+
}
1445+
1446+
return true;
1447+
}
1448+
14151449
static void raid1_write_request(struct mddev *mddev, struct bio *bio,
14161450
int max_write_sectors)
14171451
{
14181452
struct r1conf *conf = mddev->private;
14191453
struct r1bio *r1_bio;
14201454
int i, disks;
14211455
unsigned long flags;
1422-
struct md_rdev *blocked_rdev;
14231456
int first_clone;
14241457
int max_sectors;
14251458
bool write_behind = false;
@@ -1457,7 +1490,11 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
14571490
return;
14581491
}
14591492

1460-
retry_write:
1493+
if (!wait_blocked_rdev(mddev, bio)) {
1494+
bio_wouldblock_error(bio);
1495+
return;
1496+
}
1497+
14611498
r1_bio = alloc_r1bio(mddev, bio);
14621499
r1_bio->sectors = max_write_sectors;
14631500

@@ -1473,7 +1510,6 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
14731510
*/
14741511

14751512
disks = conf->raid_disks * 2;
1476-
blocked_rdev = NULL;
14771513
max_sectors = r1_bio->sectors;
14781514
for (i = 0; i < disks; i++) {
14791515
struct md_rdev *rdev = conf->mirrors[i].rdev;
@@ -1486,11 +1522,6 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
14861522
if (!is_discard && rdev && test_bit(WriteMostly, &rdev->flags))
14871523
write_behind = true;
14881524

1489-
if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) {
1490-
atomic_inc(&rdev->nr_pending);
1491-
blocked_rdev = rdev;
1492-
break;
1493-
}
14941525
r1_bio->bios[i] = NULL;
14951526
if (!rdev || test_bit(Faulty, &rdev->flags)) {
14961527
if (i < conf->raid_disks)
@@ -1506,13 +1537,6 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
15061537

15071538
is_bad = is_badblock(rdev, r1_bio->sector, max_sectors,
15081539
&first_bad, &bad_sectors);
1509-
if (is_bad < 0) {
1510-
/* mustn't write here until the bad block is
1511-
* acknowledged*/
1512-
set_bit(BlockedBadBlocks, &rdev->flags);
1513-
blocked_rdev = rdev;
1514-
break;
1515-
}
15161540
if (is_bad && first_bad <= r1_bio->sector) {
15171541
/* Cannot write here at all */
15181542
bad_sectors -= (r1_bio->sector - first_bad);
@@ -1543,27 +1567,6 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
15431567
r1_bio->bios[i] = bio;
15441568
}
15451569

1546-
if (unlikely(blocked_rdev)) {
1547-
/* Wait for this device to become unblocked */
1548-
int j;
1549-
1550-
for (j = 0; j < i; j++)
1551-
if (r1_bio->bios[j])
1552-
rdev_dec_pending(conf->mirrors[j].rdev, mddev);
1553-
mempool_free(r1_bio, &conf->r1bio_pool);
1554-
allow_barrier(conf, bio->bi_iter.bi_sector);
1555-
1556-
if (bio->bi_opf & REQ_NOWAIT) {
1557-
bio_wouldblock_error(bio);
1558-
return;
1559-
}
1560-
mddev_add_trace_msg(mddev, "raid1 wait rdev %d blocked",
1561-
blocked_rdev->raid_disk);
1562-
md_wait_for_blocked_rdev(blocked_rdev, mddev);
1563-
wait_barrier(conf, bio->bi_iter.bi_sector, false);
1564-
goto retry_write;
1565-
}
1566-
15671570
/*
15681571
* When using a bitmap, we may call alloc_behind_master_bio below.
15691572
* alloc_behind_master_bio allocates a copy of the data payload a page

drivers/md/raid10.c

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,50 +1285,46 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
12851285

12861286
static void wait_blocked_dev(struct mddev *mddev, struct r10bio *r10_bio)
12871287
{
1288-
int i;
12891288
struct r10conf *conf = mddev->private;
12901289
struct md_rdev *blocked_rdev;
1290+
int i;
12911291

12921292
retry_wait:
12931293
blocked_rdev = NULL;
12941294
for (i = 0; i < conf->copies; i++) {
12951295
struct md_rdev *rdev, *rrdev;
12961296

12971297
rdev = conf->mirrors[i].rdev;
1298-
rrdev = conf->mirrors[i].replacement;
1299-
if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) {
1300-
atomic_inc(&rdev->nr_pending);
1301-
blocked_rdev = rdev;
1302-
break;
1303-
}
1304-
if (rrdev && unlikely(test_bit(Blocked, &rrdev->flags))) {
1305-
atomic_inc(&rrdev->nr_pending);
1306-
blocked_rdev = rrdev;
1307-
break;
1308-
}
1309-
1310-
if (rdev && test_bit(WriteErrorSeen, &rdev->flags)) {
1298+
if (rdev) {
13111299
sector_t dev_sector = r10_bio->devs[i].addr;
13121300

13131301
/*
13141302
* Discard request doesn't care the write result
13151303
* so it doesn't need to wait blocked disk here.
13161304
*/
1317-
if (!r10_bio->sectors)
1318-
continue;
1319-
1320-
if (rdev_has_badblock(rdev, dev_sector,
1321-
r10_bio->sectors) < 0) {
1305+
if (test_bit(WriteErrorSeen, &rdev->flags) &&
1306+
r10_bio->sectors &&
1307+
rdev_has_badblock(rdev, dev_sector,
1308+
r10_bio->sectors) < 0)
13221309
/*
1323-
* Mustn't write here until the bad block
1324-
* is acknowledged
1310+
* Mustn't write here until the bad
1311+
* block is acknowledged
13251312
*/
1326-
atomic_inc(&rdev->nr_pending);
13271313
set_bit(BlockedBadBlocks, &rdev->flags);
1314+
1315+
if (rdev_blocked(rdev)) {
13281316
blocked_rdev = rdev;
1317+
atomic_inc(&rdev->nr_pending);
13291318
break;
13301319
}
13311320
}
1321+
1322+
rrdev = conf->mirrors[i].replacement;
1323+
if (rrdev && rdev_blocked(rrdev)) {
1324+
atomic_inc(&rrdev->nr_pending);
1325+
blocked_rdev = rrdev;
1326+
break;
1327+
}
13321328
}
13331329

13341330
if (unlikely(blocked_rdev)) {

drivers/md/raid5-ppl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ static struct ppl_io_unit *ppl_new_iounit(struct ppl_log *log,
258258
memset(pplhdr->reserved, 0xff, PPL_HDR_RESERVED);
259259
pplhdr->signature = cpu_to_le32(ppl_conf->signature);
260260

261-
io->seq = atomic64_add_return(1, &ppl_conf->seq);
261+
io->seq = atomic64_inc_return(&ppl_conf->seq);
262262
pplhdr->generation = cpu_to_le64(io->seq);
263263

264264
return io;

drivers/md/raid5.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4724,14 +4724,13 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s)
47244724
if (rdev) {
47254725
is_bad = rdev_has_badblock(rdev, sh->sector,
47264726
RAID5_STRIPE_SECTORS(conf));
4727-
if (s->blocked_rdev == NULL
4728-
&& (test_bit(Blocked, &rdev->flags)
4729-
|| is_bad < 0)) {
4727+
if (s->blocked_rdev == NULL) {
47304728
if (is_bad < 0)
4731-
set_bit(BlockedBadBlocks,
4732-
&rdev->flags);
4733-
s->blocked_rdev = rdev;
4734-
atomic_inc(&rdev->nr_pending);
4729+
set_bit(BlockedBadBlocks, &rdev->flags);
4730+
if (rdev_blocked(rdev)) {
4731+
s->blocked_rdev = rdev;
4732+
atomic_inc(&rdev->nr_pending);
4733+
}
47354734
}
47364735
}
47374736
clear_bit(R5_Insync, &dev->flags);

0 commit comments

Comments
 (0)