Skip to content

Commit 96b9f2d

Browse files
committed
md: check before referencing mddev->bitmap_ops
JIRA: https://issues.redhat.com/browse/RHEL-123668 commit 2629265 Author: Yu Kuai <yukuai3@huawei.com> Date: Mon Jul 7 09:27:10 2025 +0800 md: check before referencing mddev->bitmap_ops Prepare to introduce CONFIG_MD_BITMAP. Link: https://lore.kernel.org/linux-raid/20250707012711.376844-15-yukuai1@huaweicloud.com Signed-off-by: Yu Kuai <yukuai3@huawei.com> Reviewed-by: Xiao Ni <xni@redhat.com> Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
1 parent ac4eecd commit 96b9f2d

File tree

1 file changed

+48
-20
lines changed

1 file changed

+48
-20
lines changed

drivers/md/md.c

Lines changed: 48 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,6 +1352,9 @@ static u64 md_bitmap_events_cleared(struct mddev *mddev)
13521352
struct md_bitmap_stats stats;
13531353
int err;
13541354

1355+
if (!md_bitmap_enabled(mddev, false))
1356+
return 0;
1357+
13551358
err = mddev->bitmap_ops->get_stats(mddev->bitmap, &stats);
13561359
if (err)
13571360
return 0;
@@ -2309,13 +2312,15 @@ static int
23092312
super_1_allow_new_offset(struct md_rdev *rdev,
23102313
unsigned long long new_offset)
23112314
{
2315+
struct mddev *mddev = rdev->mddev;
2316+
23122317
/* All necessary checks on new >= old have been done */
23132318
if (new_offset >= rdev->data_offset)
23142319
return 1;
23152320

23162321
/* with 1.0 metadata, there is no metadata to tread on
23172322
* so we can always move back */
2318-
if (rdev->mddev->minor_version == 0)
2323+
if (mddev->minor_version == 0)
23192324
return 1;
23202325

23212326
/* otherwise we must be sure not to step on
@@ -2327,8 +2332,7 @@ super_1_allow_new_offset(struct md_rdev *rdev,
23272332
if (rdev->sb_start + (32+4)*2 > new_offset)
23282333
return 0;
23292334

2330-
if (!rdev->mddev->bitmap_info.file) {
2331-
struct mddev *mddev = rdev->mddev;
2335+
if (md_bitmap_registered(mddev) && !mddev->bitmap_info.file) {
23322336
struct md_bitmap_stats stats;
23332337
int err;
23342338

@@ -2800,7 +2804,8 @@ void md_update_sb(struct mddev *mddev, int force_change)
28002804

28012805
mddev_add_trace_msg(mddev, "md md_update_sb");
28022806
rewrite:
2803-
mddev->bitmap_ops->update_sb(mddev->bitmap);
2807+
if (md_bitmap_enabled(mddev, false))
2808+
mddev->bitmap_ops->update_sb(mddev->bitmap);
28042809
rdev_for_each(rdev, mddev) {
28052810
if (rdev->sb_loaded != 1)
28062811
continue; /* no noise on spare devices */
@@ -4676,6 +4681,9 @@ bitmap_store(struct mddev *mddev, const char *buf, size_t len)
46764681
unsigned long chunk, end_chunk;
46774682
int err;
46784683

4684+
if (!md_bitmap_enabled(mddev, false))
4685+
return len;
4686+
46794687
err = mddev_lock(mddev);
46804688
if (err)
46814689
return err;
@@ -6043,7 +6051,7 @@ struct mddev *md_alloc(dev_t dev, char *name)
60436051
return ERR_PTR(error);
60446052
}
60456053

6046-
if (mddev->bitmap_ops && mddev->bitmap_ops->group)
6054+
if (md_bitmap_registered(mddev) && mddev->bitmap_ops->group)
60476055
if (sysfs_create_group(&mddev->kobj, mddev->bitmap_ops->group))
60486056
pr_warn("md: cannot register extra bitmap attributes for %s\n",
60496057
mdname(mddev));
@@ -6287,7 +6295,7 @@ int md_run(struct mddev *mddev)
62876295
(unsigned long long)pers->size(mddev, 0, 0) / 2);
62886296
err = -EINVAL;
62896297
}
6290-
if (err == 0 && pers->sync_request &&
6298+
if (err == 0 && pers->sync_request && md_bitmap_registered(mddev) &&
62916299
(mddev->bitmap_info.file || mddev->bitmap_info.offset)) {
62926300
err = mddev->bitmap_ops->create(mddev);
62936301
if (err)
@@ -6362,7 +6370,8 @@ int md_run(struct mddev *mddev)
63626370
pers->free(mddev, mddev->private);
63636371
mddev->private = NULL;
63646372
put_pers(pers);
6365-
mddev->bitmap_ops->destroy(mddev);
6373+
if (md_bitmap_registered(mddev))
6374+
mddev->bitmap_ops->destroy(mddev);
63666375
abort:
63676376
bioset_exit(&mddev->io_clone_set);
63686377
exit_sync_set:
@@ -6382,10 +6391,12 @@ int do_md_run(struct mddev *mddev)
63826391
if (err)
63836392
goto out;
63846393

6385-
err = mddev->bitmap_ops->load(mddev);
6386-
if (err) {
6387-
mddev->bitmap_ops->destroy(mddev);
6388-
goto out;
6394+
if (md_bitmap_registered(mddev)) {
6395+
err = mddev->bitmap_ops->load(mddev);
6396+
if (err) {
6397+
mddev->bitmap_ops->destroy(mddev);
6398+
goto out;
6399+
}
63896400
}
63906401

63916402
if (mddev_is_clustered(mddev))
@@ -6529,7 +6540,8 @@ static void __md_stop_writes(struct mddev *mddev)
65296540
mddev->pers->quiesce(mddev, 0);
65306541
}
65316542

6532-
mddev->bitmap_ops->flush(mddev);
6543+
if (md_bitmap_enabled(mddev, true))
6544+
mddev->bitmap_ops->flush(mddev);
65336545

65346546
if (md_is_rdwr(mddev) &&
65356547
((!mddev->in_sync && !mddev_is_clustered(mddev)) ||
@@ -6556,7 +6568,8 @@ EXPORT_SYMBOL_GPL(md_stop_writes);
65566568

65576569
static void mddev_detach(struct mddev *mddev)
65586570
{
6559-
mddev->bitmap_ops->wait_behind_writes(mddev);
6571+
if (md_bitmap_enabled(mddev, false))
6572+
mddev->bitmap_ops->wait_behind_writes(mddev);
65606573
if (mddev->pers && mddev->pers->quiesce && !is_md_suspended(mddev)) {
65616574
mddev->pers->quiesce(mddev, 1);
65626575
mddev->pers->quiesce(mddev, 0);
@@ -6572,7 +6585,8 @@ static void __md_stop(struct mddev *mddev)
65726585
{
65736586
struct md_personality *pers = mddev->pers;
65746587

6575-
mddev->bitmap_ops->destroy(mddev);
6588+
if (md_bitmap_registered(mddev))
6589+
mddev->bitmap_ops->destroy(mddev);
65766590
mddev_detach(mddev);
65776591
spin_lock(&mddev->lock);
65786592
mddev->pers = NULL;
@@ -7292,6 +7306,9 @@ static int set_bitmap_file(struct mddev *mddev, int fd)
72927306
{
72937307
int err = 0;
72947308

7309+
if (!md_bitmap_registered(mddev))
7310+
return -EINVAL;
7311+
72957312
if (mddev->pers) {
72967313
if (!mddev->pers->quiesce || !mddev->thread)
72977314
return -EBUSY;
@@ -7642,6 +7659,14 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info)
76427659
rv = update_raid_disks(mddev, info->raid_disks);
76437660

76447661
if ((state ^ info->state) & (1<<MD_SB_BITMAP_PRESENT)) {
7662+
/*
7663+
* Metadata says bitmap existed, however kernel can't find
7664+
* registered bitmap.
7665+
*/
7666+
if (WARN_ON_ONCE(!md_bitmap_registered(mddev))) {
7667+
rv = -EINVAL;
7668+
goto err;
7669+
}
76457670
if (mddev->pers->quiesce == NULL || mddev->thread == NULL) {
76467671
rv = -EINVAL;
76477672
goto err;
@@ -8476,6 +8501,9 @@ static void md_bitmap_status(struct seq_file *seq, struct mddev *mddev)
84768501
unsigned long chunk_kb;
84778502
int err;
84788503

8504+
if (!md_bitmap_enabled(mddev, false))
8505+
return;
8506+
84798507
err = mddev->bitmap_ops->get_stats(mddev->bitmap, &stats);
84808508
if (err)
84818509
return;
@@ -8878,7 +8906,7 @@ static void md_end_clone_io(struct bio *bio)
88788906
struct bio *orig_bio = md_io_clone->orig_bio;
88798907
struct mddev *mddev = md_io_clone->mddev;
88808908

8881-
if (bio_data_dir(orig_bio) == WRITE && mddev->bitmap)
8909+
if (bio_data_dir(orig_bio) == WRITE && md_bitmap_enabled(mddev, false))
88828910
md_bitmap_end(mddev, md_io_clone);
88838911

88848912
if (bio->bi_status && !orig_bio->bi_status)
@@ -8905,7 +8933,7 @@ static void md_clone_bio(struct mddev *mddev, struct bio **bio)
89058933
if (blk_queue_io_stat(bdev->bd_disk->queue))
89068934
md_io_clone->start_time = bio_start_io_acct(*bio);
89078935

8908-
if (bio_data_dir(*bio) == WRITE && mddev->bitmap) {
8936+
if (bio_data_dir(*bio) == WRITE && md_bitmap_enabled(mddev, false)) {
89098937
md_io_clone->offset = (*bio)->bi_iter.bi_sector;
89108938
md_io_clone->sectors = bio_sectors(*bio);
89118939
md_bitmap_start(mddev, md_io_clone);
@@ -8929,7 +8957,7 @@ void md_free_cloned_bio(struct bio *bio)
89298957
struct bio *orig_bio = md_io_clone->orig_bio;
89308958
struct mddev *mddev = md_io_clone->mddev;
89318959

8932-
if (bio_data_dir(orig_bio) == WRITE && mddev->bitmap)
8960+
if (bio_data_dir(orig_bio) == WRITE && md_bitmap_enabled(mddev, false))
89338961
md_bitmap_end(mddev, md_io_clone);
89348962

89358963
if (bio->bi_status && !orig_bio->bi_status)
@@ -9667,7 +9695,7 @@ static void md_start_sync(struct work_struct *ws)
96679695
* We are adding a device or devices to an array which has the bitmap
96689696
* stored on all devices. So make sure all bitmap pages get written.
96699697
*/
9670-
if (spares)
9698+
if (spares && md_bitmap_enabled(mddev, true))
96719699
mddev->bitmap_ops->write_all(mddev);
96729700

96739701
name = test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) ?
@@ -9755,7 +9783,7 @@ static void unregister_sync_thread(struct mddev *mddev)
97559783
*/
97569784
void md_check_recovery(struct mddev *mddev)
97579785
{
9758-
if (mddev->bitmap)
9786+
if (md_bitmap_enabled(mddev, false))
97599787
mddev->bitmap_ops->daemon_work(mddev);
97609788

97619789
if (signal_pending(current)) {
@@ -10135,7 +10163,7 @@ static void check_sb_changes(struct mddev *mddev, struct md_rdev *rdev)
1013510163
ret = mddev->pers->resize(mddev, le64_to_cpu(sb->size));
1013610164
if (ret)
1013710165
pr_info("md-cluster: resize failed\n");
10138-
else
10166+
else if (md_bitmap_enabled(mddev, false))
1013910167
mddev->bitmap_ops->update_sb(mddev->bitmap);
1014010168
}
1014110169

0 commit comments

Comments
 (0)