md/md-bitmap: introduce CONFIG_MD_BITMAP

Now that all implementations are internal, it's sensible to add a config
option for md-bitmap, and it's a good way for isolation.

Link: https://lore.kernel.org/linux-raid/20250707012711.376844-16-yukuai1@huaweicloud.com
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
Reviewed-by: Xiao Ni <xni@redhat.com>
This commit is contained in:
Yu Kuai
2025-09-06 17:12:22 +08:00
parent 26292657ad
commit c27474ac1d
6 changed files with 85 additions and 19 deletions
+18
View File
@@ -37,6 +37,21 @@ config BLK_DEV_MD
If unsure, say N.
config MD_BITMAP
bool "MD RAID bitmap support"
default y
depends on BLK_DEV_MD
help
If you say Y here, support for the write intent bitmap will be
enabled. The bitmap can be used to optimize resync speed after power
failure or readding a disk, limiting it to recorded dirty sectors in
bitmap.
This feature can be added to existing MD array or MD array can be
created with bitmap via mdadm(8).
If unsure, say Y.
config MD_AUTODETECT
bool "Autodetect RAID arrays during kernel boot"
depends on BLK_DEV_MD=y
@@ -54,6 +69,7 @@ config MD_AUTODETECT
config MD_BITMAP_FILE
bool "MD bitmap file support (deprecated)"
default y
depends on MD_BITMAP
help
If you say Y here, support for write intent bitmaps in files on an
external file system is enabled. This is an alternative to the internal
@@ -174,6 +190,7 @@ config MD_RAID456
config MD_CLUSTER
tristate "Cluster Support for MD"
select MD_BITMAP
depends on BLK_DEV_MD
depends on DLM
default n
@@ -393,6 +410,7 @@ config DM_RAID
select MD_RAID1
select MD_RAID10
select MD_RAID456
select MD_BITMAP
select BLK_DEV_MD
help
A dm target that supports RAID1, RAID10, RAID4, RAID5 and RAID6 mappings
+2 -1
View File
@@ -27,7 +27,8 @@ dm-clone-y += dm-clone-target.o dm-clone-metadata.o
dm-verity-y += dm-verity-target.o
dm-zoned-y += dm-zoned-target.o dm-zoned-metadata.o dm-zoned-reclaim.o
md-mod-y += md.o md-bitmap.o
md-mod-y += md.o
md-mod-$(CONFIG_MD_BITMAP) += md-bitmap.o
raid456-y += raid5.o raid5-cache.o raid5-ppl.o
linear-y += md-linear.o
+21 -2
View File
@@ -224,6 +224,8 @@ struct bitmap {
int cluster_slot;
};
static struct workqueue_struct *md_bitmap_wq;
static int __bitmap_resize(struct bitmap *bitmap, sector_t blocks,
int chunksize, bool init);
@@ -2979,6 +2981,12 @@ static struct attribute_group md_bitmap_group = {
};
static struct bitmap_operations bitmap_ops = {
.head = {
.type = MD_BITMAP,
.id = ID_BITMAP,
.name = "bitmap",
},
.enabled = bitmap_enabled,
.create = bitmap_create,
.resize = bitmap_resize,
@@ -3013,7 +3021,18 @@ static struct bitmap_operations bitmap_ops = {
.group = &md_bitmap_group,
};
void mddev_set_bitmap_ops(struct mddev *mddev)
int md_bitmap_init(void)
{
mddev->bitmap_ops = &bitmap_ops;
md_bitmap_wq = alloc_workqueue("md_bitmap", WQ_MEM_RECLAIM | WQ_UNBOUND,
0);
if (!md_bitmap_wq)
return -ENOMEM;
return register_md_submodule(&bitmap_ops.head);
}
void md_bitmap_exit(void)
{
destroy_workqueue(md_bitmap_wq);
unregister_md_submodule(&bitmap_ops.head);
}
+15 -2
View File
@@ -62,6 +62,8 @@ struct md_bitmap_stats {
};
struct bitmap_operations {
struct md_submodule_head head;
bool (*enabled)(void *data, bool flush);
int (*create)(struct mddev *mddev);
int (*resize)(struct mddev *mddev, sector_t blocks, int chunksize);
@@ -105,8 +107,6 @@ struct bitmap_operations {
};
/* the bitmap API */
void mddev_set_bitmap_ops(struct mddev *mddev);
static inline bool md_bitmap_registered(struct mddev *mddev)
{
return mddev->bitmap_ops != NULL;
@@ -147,4 +147,17 @@ static inline void md_bitmap_end_sync(struct mddev *mddev, sector_t offset,
mddev->bitmap_ops->end_sync(mddev, offset, blocks);
}
#ifdef CONFIG_MD_BITMAP
int md_bitmap_init(void);
void md_bitmap_exit(void);
#else
static inline int md_bitmap_init(void)
{
return 0;
}
static inline void md_bitmap_exit(void)
{
}
#endif
#endif
+28 -12
View File
@@ -94,7 +94,6 @@ static struct workqueue_struct *md_wq;
* workqueue whith reconfig_mutex grabbed.
*/
static struct workqueue_struct *md_misc_wq;
struct workqueue_struct *md_bitmap_wq;
static int remove_and_add_spares(struct mddev *mddev,
struct md_rdev *this);
@@ -677,15 +676,34 @@ static void active_io_release(struct percpu_ref *ref)
static void no_op(struct percpu_ref *r) {}
static void mddev_set_bitmap_ops(struct mddev *mddev, enum md_submodule_id id)
{
xa_lock(&md_submodule);
mddev->bitmap_ops = xa_load(&md_submodule, id);
xa_unlock(&md_submodule);
if (!mddev->bitmap_ops)
pr_warn_once("md: can't find bitmap id %d\n", id);
}
static void mddev_clear_bitmap_ops(struct mddev *mddev)
{
mddev->bitmap_ops = NULL;
}
int mddev_init(struct mddev *mddev)
{
/* TODO: support more versions */
mddev_set_bitmap_ops(mddev, ID_BITMAP);
if (percpu_ref_init(&mddev->active_io, active_io_release,
PERCPU_REF_ALLOW_REINIT, GFP_KERNEL))
PERCPU_REF_ALLOW_REINIT, GFP_KERNEL)) {
mddev_clear_bitmap_ops(mddev);
return -ENOMEM;
}
if (percpu_ref_init(&mddev->writes_pending, no_op,
PERCPU_REF_ALLOW_REINIT, GFP_KERNEL)) {
mddev_clear_bitmap_ops(mddev);
percpu_ref_exit(&mddev->active_io);
return -ENOMEM;
}
@@ -713,7 +731,6 @@ int mddev_init(struct mddev *mddev)
mddev->resync_min = 0;
mddev->resync_max = MaxSector;
mddev->level = LEVEL_NONE;
mddev_set_bitmap_ops(mddev);
INIT_WORK(&mddev->sync_work, md_start_sync);
INIT_WORK(&mddev->del_work, mddev_delayed_delete);
@@ -724,6 +741,7 @@ EXPORT_SYMBOL_GPL(mddev_init);
void mddev_destroy(struct mddev *mddev)
{
mddev_clear_bitmap_ops(mddev);
percpu_ref_exit(&mddev->active_io);
percpu_ref_exit(&mddev->writes_pending);
}
@@ -10121,8 +10139,12 @@ static void md_geninit(void)
static int __init md_init(void)
{
int ret = -ENOMEM;
int ret = md_bitmap_init();
if (ret)
return ret;
ret = -ENOMEM;
md_wq = alloc_workqueue("md", WQ_MEM_RECLAIM, 0);
if (!md_wq)
goto err_wq;
@@ -10131,11 +10153,6 @@ static int __init md_init(void)
if (!md_misc_wq)
goto err_misc_wq;
md_bitmap_wq = alloc_workqueue("md_bitmap", WQ_MEM_RECLAIM | WQ_UNBOUND,
0);
if (!md_bitmap_wq)
goto err_bitmap_wq;
ret = __register_blkdev(MD_MAJOR, "md", md_probe);
if (ret < 0)
goto err_md;
@@ -10154,12 +10171,11 @@ static int __init md_init(void)
err_mdp:
unregister_blkdev(MD_MAJOR, "md");
err_md:
destroy_workqueue(md_bitmap_wq);
err_bitmap_wq:
destroy_workqueue(md_misc_wq);
err_misc_wq:
destroy_workqueue(md_wq);
err_wq:
md_bitmap_exit();
return ret;
}
@@ -10465,8 +10481,8 @@ static __exit void md_exit(void)
spin_unlock(&all_mddevs_lock);
destroy_workqueue(md_misc_wq);
destroy_workqueue(md_bitmap_wq);
destroy_workqueue(md_wq);
md_bitmap_exit();
}
subsys_initcall(md_init);
+1 -2
View File
@@ -38,7 +38,7 @@ enum md_submodule_id {
ID_RAID6 = 6,
ID_RAID10 = 10,
ID_CLUSTER,
ID_BITMAP, /* TODO */
ID_BITMAP,
ID_LLBITMAP, /* TODO */
};
@@ -1012,7 +1012,6 @@ struct mdu_array_info_s;
struct mdu_disk_info_s;
extern int mdp_major;
extern struct workqueue_struct *md_bitmap_wq;
void md_autostart_arrays(int part);
int md_set_array_info(struct mddev *mddev, struct mdu_array_info_s *info);
int md_add_new_disk(struct mddev *mddev, struct mdu_disk_info_s *info);