diff options
| author | Yu Kuai <yukuai3@huawei.com> | 2025-07-07 09:27:11 +0800 | 
|---|---|---|
| committer | Yu Kuai <yukuai3@huawei.com> | 2025-09-06 17:12:22 +0800 | 
| commit | c27474ac1d4609af3c1c38ccac252c2575b47b9e (patch) | |
| tree | ec4eff9177433b308223a525d2e40e9afd1db4c9 /drivers/md | |
| parent | 26292657add33b8cb627bd582e7097755e85a3ac (diff) | |
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>
Diffstat (limited to 'drivers/md')
| -rw-r--r-- | drivers/md/Kconfig | 18 | ||||
| -rw-r--r-- | drivers/md/Makefile | 3 | ||||
| -rw-r--r-- | drivers/md/md-bitmap.c | 23 | ||||
| -rw-r--r-- | drivers/md/md-bitmap.h | 17 | ||||
| -rw-r--r-- | drivers/md/md.c | 40 | ||||
| -rw-r--r-- | drivers/md/md.h | 3 | 
6 files changed, 85 insertions, 19 deletions
| diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig index ddb37f6670de..f913579e731c 100644 --- a/drivers/md/Kconfig +++ b/drivers/md/Kconfig @@ -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 diff --git a/drivers/md/Makefile b/drivers/md/Makefile index 87bdfc9fe14c..2e18147a9c40 100644 --- a/drivers/md/Makefile +++ b/drivers/md/Makefile @@ -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 diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 29de99e0de3e..5f62f2fd8f3f 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -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);  } diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index 61cfc650c69c..42f91755a341 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -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 diff --git a/drivers/md/md.c b/drivers/md/md.c index e750ae4883e6..fbc107b52819 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -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); diff --git a/drivers/md/md.h b/drivers/md/md.h index 06364e15e8d1..081152c8de1f 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -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); | 
