Commit c27474ac authored by Yu Kuai's avatar Yu Kuai
Browse files

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: default avatarYu Kuai <yukuai3@huawei.com>
Reviewed-by: default avatarXiao Ni <xni@redhat.com>
parent 26292657
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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)
{
	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)
{
	mddev->bitmap_ops = &bitmap_ops;
	destroy_workqueue(md_bitmap_wq);
	unregister_md_submodule(&bitmap_ops.head);
}
+15 −2
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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);
Loading