* [PATCH v5 00/15] md/md-bitmap: introduce CONFIG_MD_BITMAP
@ 2025-07-07 1:26 Yu Kuai
2025-07-07 1:26 ` [PATCH v5 01/15] md/raid1: change r1conf->r1bio_pool to a pointer type Yu Kuai
` (16 more replies)
0 siblings, 17 replies; 20+ messages in thread
From: Yu Kuai @ 2025-07-07 1:26 UTC (permalink / raw)
To: agk, snitzer, mpatocka, song, yukuai3
Cc: dm-devel, linux-raid, linux-kernel, yukuai1, yi.zhang, yangerkun,
johnny.chenyi
From: Yu Kuai <yukuai3@huawei.com>
Changes in v5:
- rebase on the top of md-6.17;
- fix compile problem if md-mod is build as module;
- fix two problems for lvm2 dm-raid tests, patch 5,13
- other cleanups;
Changes in v4:
- rebase on the top of other patchset;
Changes in v3:
- update commit message.
Changes in v2:
- don't export apis, and don't support build md-bitmap as module
Due to known performance issues with md-bitmap and the unreasonable
implementations like following:
- self-managed pages, bitmap_storage->filemap;
- self-managed IO submitting like filemap_write_page();
- global spin_lock
...
I have decided not to continue optimizing based on the current bitmap
implementation, and plan to invent a new lock-less bitmap. And a new
kconfig option is a good way for isolation.
However, we still encourage anyone who wants to continue optimizing the
current implementation
Yu Kuai (15):
md/raid1: change r1conf->r1bio_pool to a pointer type
md/raid1: remove struct pool_info and related code
md/md-bitmap: remove the parameter 'init' for bitmap_ops->resize()
md/md-bitmap: merge md_bitmap_group into bitmap_operations
md/md-bitmap: add a new parameter 'flush' to bitmap_ops->enabled
md/md-bitmap: add md_bitmap_registered/enabled() helper
md/md-bitmap: handle the case bitmap is not enabled before
start_sync()
md/md-bitmap: handle the case bitmap is not enabled before end_sync()
md/raid1: check bitmap before behind write
md/raid1: check before referencing mddev->bitmap_ops
md/raid10: check before referencing mddev->bitmap_ops
md/raid5: check before referencing mddev->bitmap_ops
md/dm-raid: check before referencing mddev->bitmap_ops
md: check before referencing mddev->bitmap_ops
md/md-bitmap: introduce CONFIG_MD_BITMAP
drivers/md/Kconfig | 18 +++++
drivers/md/Makefile | 3 +-
drivers/md/dm-raid.c | 18 +++--
drivers/md/md-bitmap.c | 74 +++++++++---------
drivers/md/md-bitmap.h | 62 ++++++++++++++-
drivers/md/md-cluster.c | 2 +-
drivers/md/md.c | 112 +++++++++++++++++++--------
drivers/md/md.h | 4 +-
drivers/md/raid1-10.c | 2 +-
drivers/md/raid1.c | 163 +++++++++++++++++++---------------------
drivers/md/raid1.h | 22 +-----
drivers/md/raid10.c | 49 ++++++------
drivers/md/raid5.c | 30 ++++----
13 files changed, 330 insertions(+), 229 deletions(-)
--
2.39.2
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v5 01/15] md/raid1: change r1conf->r1bio_pool to a pointer type
2025-07-07 1:26 [PATCH v5 00/15] md/md-bitmap: introduce CONFIG_MD_BITMAP Yu Kuai
@ 2025-07-07 1:26 ` Yu Kuai
2025-07-07 1:26 ` [PATCH v5 02/15] md/raid1: remove struct pool_info and related code Yu Kuai
` (15 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Yu Kuai @ 2025-07-07 1:26 UTC (permalink / raw)
To: agk, snitzer, mpatocka, song, yukuai3
Cc: dm-devel, linux-raid, linux-kernel, yukuai1, yi.zhang, yangerkun,
johnny.chenyi
From: Yu Kuai <yukuai3@huawei.com>
In raid1_reshape(), newpool is a stack variable.
mempool_init() initializes newpool->wait with the stack address.
After assigning newpool to conf->r1bio_pool, the wait queue
need to be reinitialized, which is not ideal.
Change raid1_conf->r1bio_pool to a pointer type and
replace mempool_init() with mempool_create_kmalloc_pool() to
avoid referencing a stack-based wait queue.
Signed-off-by: Wang Jinchao <wangjinchao600@gmail.com>
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
---
drivers/md/raid1.c | 39 ++++++++++++++++++---------------------
drivers/md/raid1.h | 2 +-
2 files changed, 19 insertions(+), 22 deletions(-)
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index fd4ce2a4136f..8249cbb89fec 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -255,7 +255,7 @@ static void free_r1bio(struct r1bio *r1_bio)
struct r1conf *conf = r1_bio->mddev->private;
put_all_bios(conf, r1_bio);
- mempool_free(r1_bio, &conf->r1bio_pool);
+ mempool_free(r1_bio, conf->r1bio_pool);
}
static void put_buf(struct r1bio *r1_bio)
@@ -1305,9 +1305,8 @@ alloc_r1bio(struct mddev *mddev, struct bio *bio)
struct r1conf *conf = mddev->private;
struct r1bio *r1_bio;
- r1_bio = mempool_alloc(&conf->r1bio_pool, GFP_NOIO);
- /* Ensure no bio records IO_BLOCKED */
- memset(r1_bio->bios, 0, conf->raid_disks * sizeof(r1_bio->bios[0]));
+ r1_bio = mempool_alloc(conf->r1bio_pool, GFP_NOIO);
+ memset(r1_bio, 0, offsetof(struct r1bio, bios[conf->raid_disks * 2]));
init_r1bio(r1_bio, mddev, bio);
return r1_bio;
}
@@ -3084,6 +3083,7 @@ static struct r1conf *setup_conf(struct mddev *mddev)
int i;
struct raid1_info *disk;
struct md_rdev *rdev;
+ size_t r1bio_size;
int err = -ENOMEM;
conf = kzalloc(sizeof(struct r1conf), GFP_KERNEL);
@@ -3124,9 +3124,10 @@ static struct r1conf *setup_conf(struct mddev *mddev)
if (!conf->poolinfo)
goto abort;
conf->poolinfo->raid_disks = mddev->raid_disks * 2;
- err = mempool_init(&conf->r1bio_pool, NR_RAID_BIOS, r1bio_pool_alloc,
- rbio_pool_free, conf->poolinfo);
- if (err)
+
+ r1bio_size = offsetof(struct r1bio, bios[mddev->raid_disks * 2]);
+ conf->r1bio_pool = mempool_create_kmalloc_pool(NR_RAID_BIOS, r1bio_size);
+ if (!conf->r1bio_pool)
goto abort;
err = bioset_init(&conf->bio_split, BIO_POOL_SIZE, 0, 0);
@@ -3197,7 +3198,7 @@ static struct r1conf *setup_conf(struct mddev *mddev)
abort:
if (conf) {
- mempool_exit(&conf->r1bio_pool);
+ mempool_destroy(conf->r1bio_pool);
kfree(conf->mirrors);
safe_put_page(conf->tmppage);
kfree(conf->poolinfo);
@@ -3310,7 +3311,7 @@ static void raid1_free(struct mddev *mddev, void *priv)
{
struct r1conf *conf = priv;
- mempool_exit(&conf->r1bio_pool);
+ mempool_destroy(conf->r1bio_pool);
kfree(conf->mirrors);
safe_put_page(conf->tmppage);
kfree(conf->poolinfo);
@@ -3366,17 +3367,14 @@ static int raid1_reshape(struct mddev *mddev)
* At the same time, we "pack" the devices so that all the missing
* devices have the higher raid_disk numbers.
*/
- mempool_t newpool, oldpool;
+ mempool_t *newpool, *oldpool;
struct pool_info *newpoolinfo;
+ size_t new_r1bio_size;
struct raid1_info *newmirrors;
struct r1conf *conf = mddev->private;
int cnt, raid_disks;
unsigned long flags;
int d, d2;
- int ret;
-
- memset(&newpool, 0, sizeof(newpool));
- memset(&oldpool, 0, sizeof(oldpool));
/* Cannot change chunk_size, layout, or level */
if (mddev->chunk_sectors != mddev->new_chunk_sectors ||
@@ -3408,18 +3406,18 @@ static int raid1_reshape(struct mddev *mddev)
newpoolinfo->mddev = mddev;
newpoolinfo->raid_disks = raid_disks * 2;
- ret = mempool_init(&newpool, NR_RAID_BIOS, r1bio_pool_alloc,
- rbio_pool_free, newpoolinfo);
- if (ret) {
+ new_r1bio_size = offsetof(struct r1bio, bios[raid_disks * 2]);
+ newpool = mempool_create_kmalloc_pool(NR_RAID_BIOS, new_r1bio_size);
+ if (!newpool) {
kfree(newpoolinfo);
- return ret;
+ return -ENOMEM;
}
newmirrors = kzalloc(array3_size(sizeof(struct raid1_info),
raid_disks, 2),
GFP_KERNEL);
if (!newmirrors) {
kfree(newpoolinfo);
- mempool_exit(&newpool);
+ mempool_destroy(newpool);
return -ENOMEM;
}
@@ -3428,7 +3426,6 @@ static int raid1_reshape(struct mddev *mddev)
/* ok, everything is stopped */
oldpool = conf->r1bio_pool;
conf->r1bio_pool = newpool;
- init_waitqueue_head(&conf->r1bio_pool.wait);
for (d = d2 = 0; d < conf->raid_disks; d++) {
struct md_rdev *rdev = conf->mirrors[d].rdev;
@@ -3460,7 +3457,7 @@ static int raid1_reshape(struct mddev *mddev)
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
md_wakeup_thread(mddev->thread);
- mempool_exit(&oldpool);
+ mempool_destroy(oldpool);
return 0;
}
diff --git a/drivers/md/raid1.h b/drivers/md/raid1.h
index 33f318fcc268..652c347b1a70 100644
--- a/drivers/md/raid1.h
+++ b/drivers/md/raid1.h
@@ -118,7 +118,7 @@ struct r1conf {
* mempools - it changes when the array grows or shrinks
*/
struct pool_info *poolinfo;
- mempool_t r1bio_pool;
+ mempool_t *r1bio_pool;
mempool_t r1buf_pool;
struct bio_set bio_split;
--
2.39.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v5 02/15] md/raid1: remove struct pool_info and related code
2025-07-07 1:26 [PATCH v5 00/15] md/md-bitmap: introduce CONFIG_MD_BITMAP Yu Kuai
2025-07-07 1:26 ` [PATCH v5 01/15] md/raid1: change r1conf->r1bio_pool to a pointer type Yu Kuai
@ 2025-07-07 1:26 ` Yu Kuai
2025-07-07 1:26 ` [PATCH v5 03/15] md/md-bitmap: remove the parameter 'init' for bitmap_ops->resize() Yu Kuai
` (14 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Yu Kuai @ 2025-07-07 1:26 UTC (permalink / raw)
To: agk, snitzer, mpatocka, song, yukuai3
Cc: dm-devel, linux-raid, linux-kernel, yukuai1, yi.zhang, yangerkun,
johnny.chenyi
From: Yu Kuai <yukuai3@huawei.com>
The struct pool_info was originally introduced mainly to support reshape
operations, serving as a parameter for mempool_init() when raid_disks
changes. Now that mempool_create_kmalloc_pool() is sufficient for this
purpose, struct pool_info and its related code are no longer needed.
Remove struct pool_info and all associated code.
Signed-off-by: Wang Jinchao <wangjinchao600@gmail.com>
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
---
drivers/md/raid1.c | 49 +++++++++++++---------------------------------
drivers/md/raid1.h | 20 -------------------
2 files changed, 14 insertions(+), 55 deletions(-)
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 8249cbb89fec..3a31e230727c 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -127,10 +127,9 @@ static inline struct r1bio *get_resync_r1bio(struct bio *bio)
return get_resync_pages(bio)->raid_bio;
}
-static void * r1bio_pool_alloc(gfp_t gfp_flags, void *data)
+static void *r1bio_pool_alloc(gfp_t gfp_flags, struct r1conf *conf)
{
- struct pool_info *pi = data;
- int size = offsetof(struct r1bio, bios[pi->raid_disks]);
+ int size = offsetof(struct r1bio, bios[conf->raid_disks * 2]);
/* allocate a r1bio with room for raid_disks entries in the bios array */
return kzalloc(size, gfp_flags);
@@ -145,18 +144,18 @@ static void * r1bio_pool_alloc(gfp_t gfp_flags, void *data)
static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data)
{
- struct pool_info *pi = data;
+ struct r1conf *conf = data;
struct r1bio *r1_bio;
struct bio *bio;
int need_pages;
int j;
struct resync_pages *rps;
- r1_bio = r1bio_pool_alloc(gfp_flags, pi);
+ r1_bio = r1bio_pool_alloc(gfp_flags, conf);
if (!r1_bio)
return NULL;
- rps = kmalloc_array(pi->raid_disks, sizeof(struct resync_pages),
+ rps = kmalloc_array(conf->raid_disks * 2, sizeof(struct resync_pages),
gfp_flags);
if (!rps)
goto out_free_r1bio;
@@ -164,7 +163,7 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data)
/*
* Allocate bios : 1 for reading, n-1 for writing
*/
- for (j = pi->raid_disks ; j-- ; ) {
+ for (j = conf->raid_disks * 2; j-- ; ) {
bio = bio_kmalloc(RESYNC_PAGES, gfp_flags);
if (!bio)
goto out_free_bio;
@@ -177,11 +176,11 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data)
* If this is a user-requested check/repair, allocate
* RESYNC_PAGES for each bio.
*/
- if (test_bit(MD_RECOVERY_REQUESTED, &pi->mddev->recovery))
- need_pages = pi->raid_disks;
+ if (test_bit(MD_RECOVERY_REQUESTED, &conf->mddev->recovery))
+ need_pages = conf->raid_disks * 2;
else
need_pages = 1;
- for (j = 0; j < pi->raid_disks; j++) {
+ for (j = 0; j < conf->raid_disks * 2; j++) {
struct resync_pages *rp = &rps[j];
bio = r1_bio->bios[j];
@@ -207,7 +206,7 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data)
resync_free_pages(&rps[j]);
out_free_bio:
- while (++j < pi->raid_disks) {
+ while (++j < conf->raid_disks * 2) {
bio_uninit(r1_bio->bios[j]);
kfree(r1_bio->bios[j]);
}
@@ -220,12 +219,12 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data)
static void r1buf_pool_free(void *__r1_bio, void *data)
{
- struct pool_info *pi = data;
+ struct r1conf *conf = data;
int i;
struct r1bio *r1bio = __r1_bio;
struct resync_pages *rp = NULL;
- for (i = pi->raid_disks; i--; ) {
+ for (i = conf->raid_disks * 2; i--; ) {
rp = get_resync_pages(r1bio->bios[i]);
resync_free_pages(rp);
bio_uninit(r1bio->bios[i]);
@@ -2745,7 +2744,7 @@ static int init_resync(struct r1conf *conf)
BUG_ON(mempool_initialized(&conf->r1buf_pool));
return mempool_init(&conf->r1buf_pool, buffs, r1buf_pool_alloc,
- r1buf_pool_free, conf->poolinfo);
+ r1buf_pool_free, conf);
}
static struct r1bio *raid1_alloc_init_r1buf(struct r1conf *conf)
@@ -2755,7 +2754,7 @@ static struct r1bio *raid1_alloc_init_r1buf(struct r1conf *conf)
struct bio *bio;
int i;
- for (i = conf->poolinfo->raid_disks; i--; ) {
+ for (i = conf->raid_disks * 2; i--; ) {
bio = r1bio->bios[i];
rps = bio->bi_private;
bio_reset(bio, NULL, 0);
@@ -3120,11 +3119,6 @@ static struct r1conf *setup_conf(struct mddev *mddev)
if (!conf->tmppage)
goto abort;
- conf->poolinfo = kzalloc(sizeof(*conf->poolinfo), GFP_KERNEL);
- if (!conf->poolinfo)
- goto abort;
- conf->poolinfo->raid_disks = mddev->raid_disks * 2;
-
r1bio_size = offsetof(struct r1bio, bios[mddev->raid_disks * 2]);
conf->r1bio_pool = mempool_create_kmalloc_pool(NR_RAID_BIOS, r1bio_size);
if (!conf->r1bio_pool)
@@ -3134,8 +3128,6 @@ static struct r1conf *setup_conf(struct mddev *mddev)
if (err)
goto abort;
- conf->poolinfo->mddev = mddev;
-
err = -EINVAL;
spin_lock_init(&conf->device_lock);
conf->raid_disks = mddev->raid_disks;
@@ -3201,7 +3193,6 @@ static struct r1conf *setup_conf(struct mddev *mddev)
mempool_destroy(conf->r1bio_pool);
kfree(conf->mirrors);
safe_put_page(conf->tmppage);
- kfree(conf->poolinfo);
kfree(conf->nr_pending);
kfree(conf->nr_waiting);
kfree(conf->nr_queued);
@@ -3314,7 +3305,6 @@ static void raid1_free(struct mddev *mddev, void *priv)
mempool_destroy(conf->r1bio_pool);
kfree(conf->mirrors);
safe_put_page(conf->tmppage);
- kfree(conf->poolinfo);
kfree(conf->nr_pending);
kfree(conf->nr_waiting);
kfree(conf->nr_queued);
@@ -3368,7 +3358,6 @@ static int raid1_reshape(struct mddev *mddev)
* devices have the higher raid_disk numbers.
*/
mempool_t *newpool, *oldpool;
- struct pool_info *newpoolinfo;
size_t new_r1bio_size;
struct raid1_info *newmirrors;
struct r1conf *conf = mddev->private;
@@ -3400,23 +3389,15 @@ static int raid1_reshape(struct mddev *mddev)
return -EBUSY;
}
- newpoolinfo = kmalloc(sizeof(*newpoolinfo), GFP_KERNEL);
- if (!newpoolinfo)
- return -ENOMEM;
- newpoolinfo->mddev = mddev;
- newpoolinfo->raid_disks = raid_disks * 2;
-
new_r1bio_size = offsetof(struct r1bio, bios[raid_disks * 2]);
newpool = mempool_create_kmalloc_pool(NR_RAID_BIOS, new_r1bio_size);
if (!newpool) {
- kfree(newpoolinfo);
return -ENOMEM;
}
newmirrors = kzalloc(array3_size(sizeof(struct raid1_info),
raid_disks, 2),
GFP_KERNEL);
if (!newmirrors) {
- kfree(newpoolinfo);
mempool_destroy(newpool);
return -ENOMEM;
}
@@ -3442,8 +3423,6 @@ static int raid1_reshape(struct mddev *mddev)
}
kfree(conf->mirrors);
conf->mirrors = newmirrors;
- kfree(conf->poolinfo);
- conf->poolinfo = newpoolinfo;
spin_lock_irqsave(&conf->device_lock, flags);
mddev->degraded += (raid_disks - conf->raid_disks);
diff --git a/drivers/md/raid1.h b/drivers/md/raid1.h
index 652c347b1a70..d236ef179cfb 100644
--- a/drivers/md/raid1.h
+++ b/drivers/md/raid1.h
@@ -49,22 +49,6 @@ struct raid1_info {
sector_t seq_start;
};
-/*
- * memory pools need a pointer to the mddev, so they can force an unplug
- * when memory is tight, and a count of the number of drives that the
- * pool was allocated for, so they know how much to allocate and free.
- * mddev->raid_disks cannot be used, as it can change while a pool is active
- * These two datums are stored in a kmalloced struct.
- * The 'raid_disks' here is twice the raid_disks in r1conf.
- * This allows space for each 'real' device can have a replacement in the
- * second half of the array.
- */
-
-struct pool_info {
- struct mddev *mddev;
- int raid_disks;
-};
-
struct r1conf {
struct mddev *mddev;
struct raid1_info *mirrors; /* twice 'raid_disks' to
@@ -114,10 +98,6 @@ struct r1conf {
*/
int recovery_disabled;
- /* poolinfo contains information about the content of the
- * mempools - it changes when the array grows or shrinks
- */
- struct pool_info *poolinfo;
mempool_t *r1bio_pool;
mempool_t r1buf_pool;
--
2.39.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v5 03/15] md/md-bitmap: remove the parameter 'init' for bitmap_ops->resize()
2025-07-07 1:26 [PATCH v5 00/15] md/md-bitmap: introduce CONFIG_MD_BITMAP Yu Kuai
2025-07-07 1:26 ` [PATCH v5 01/15] md/raid1: change r1conf->r1bio_pool to a pointer type Yu Kuai
2025-07-07 1:26 ` [PATCH v5 02/15] md/raid1: remove struct pool_info and related code Yu Kuai
@ 2025-07-07 1:26 ` Yu Kuai
2025-07-25 2:49 ` Xiao Ni
2025-07-07 1:27 ` [PATCH v5 04/15] md/md-bitmap: merge md_bitmap_group into bitmap_operations Yu Kuai
` (13 subsequent siblings)
16 siblings, 1 reply; 20+ messages in thread
From: Yu Kuai @ 2025-07-07 1:26 UTC (permalink / raw)
To: agk, snitzer, mpatocka, song, yukuai3
Cc: dm-devel, linux-raid, linux-kernel, yukuai1, yi.zhang, yangerkun,
johnny.chenyi
From: Yu Kuai <yukuai3@huawei.com>
It's set to 'false' for all callers, hence it's useless and can be
removed.
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
---
drivers/md/dm-raid.c | 2 +-
drivers/md/md-bitmap.c | 5 ++---
drivers/md/md-bitmap.h | 3 +--
drivers/md/md-cluster.c | 2 +-
drivers/md/raid1.c | 2 +-
drivers/md/raid10.c | 8 ++++----
drivers/md/raid5.c | 2 +-
7 files changed, 11 insertions(+), 13 deletions(-)
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index d296770478b2..9757c32ea1f5 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -4068,7 +4068,7 @@ static int raid_preresume(struct dm_target *ti)
int chunksize = to_bytes(rs->requested_bitmap_chunk_sectors) ?: mddev->bitmap_info.chunksize;
r = mddev->bitmap_ops->resize(mddev, mddev->dev_sectors,
- chunksize, false);
+ chunksize);
if (r)
DMERR("Failed to resize bitmap");
}
diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
index bd694910b01b..fc7282304b00 100644
--- a/drivers/md/md-bitmap.c
+++ b/drivers/md/md-bitmap.c
@@ -2594,15 +2594,14 @@ static int __bitmap_resize(struct bitmap *bitmap, sector_t blocks,
return ret;
}
-static int bitmap_resize(struct mddev *mddev, sector_t blocks, int chunksize,
- bool init)
+static int bitmap_resize(struct mddev *mddev, sector_t blocks, int chunksize)
{
struct bitmap *bitmap = mddev->bitmap;
if (!bitmap)
return 0;
- return __bitmap_resize(bitmap, blocks, chunksize, init);
+ return __bitmap_resize(bitmap, blocks, chunksize, false);
}
static ssize_t
diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h
index 59e9dd45cfde..28c1f1c1cc83 100644
--- a/drivers/md/md-bitmap.h
+++ b/drivers/md/md-bitmap.h
@@ -64,8 +64,7 @@ struct md_bitmap_stats {
struct bitmap_operations {
bool (*enabled)(struct mddev *mddev);
int (*create)(struct mddev *mddev);
- int (*resize)(struct mddev *mddev, sector_t blocks, int chunksize,
- bool init);
+ int (*resize)(struct mddev *mddev, sector_t blocks, int chunksize);
int (*load)(struct mddev *mddev);
void (*destroy)(struct mddev *mddev);
diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c
index 94221d964d4f..db6bbc8eebbc 100644
--- a/drivers/md/md-cluster.c
+++ b/drivers/md/md-cluster.c
@@ -630,7 +630,7 @@ static int process_recvd_msg(struct mddev *mddev, struct cluster_msg *msg)
if (le64_to_cpu(msg->high) != mddev->pers->size(mddev, 0, 0))
ret = mddev->bitmap_ops->resize(mddev,
le64_to_cpu(msg->high),
- 0, false);
+ 0);
break;
default:
ret = -1;
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 3a31e230727c..39ebe0fadacd 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -3329,7 +3329,7 @@ static int raid1_resize(struct mddev *mddev, sector_t sectors)
mddev->array_sectors > newsize)
return -EINVAL;
- ret = mddev->bitmap_ops->resize(mddev, newsize, 0, false);
+ ret = mddev->bitmap_ops->resize(mddev, newsize, 0);
if (ret)
return ret;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index b74780af4c22..d2ef96be0150 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -4233,7 +4233,7 @@ static int raid10_resize(struct mddev *mddev, sector_t sectors)
mddev->array_sectors > size)
return -EINVAL;
- ret = mddev->bitmap_ops->resize(mddev, size, 0, false);
+ ret = mddev->bitmap_ops->resize(mddev, size, 0);
if (ret)
return ret;
@@ -4502,7 +4502,7 @@ static int raid10_start_reshape(struct mddev *mddev)
newsize = raid10_size(mddev, 0, conf->geo.raid_disks);
if (!mddev_is_clustered(mddev)) {
- ret = mddev->bitmap_ops->resize(mddev, newsize, 0, false);
+ ret = mddev->bitmap_ops->resize(mddev, newsize, 0);
if (ret)
goto abort;
else
@@ -4524,13 +4524,13 @@ static int raid10_start_reshape(struct mddev *mddev)
MD_FEATURE_RESHAPE_ACTIVE)) || (oldsize == newsize))
goto out;
- ret = mddev->bitmap_ops->resize(mddev, newsize, 0, false);
+ ret = mddev->bitmap_ops->resize(mddev, newsize, 0);
if (ret)
goto abort;
ret = mddev->cluster_ops->resize_bitmaps(mddev, newsize, oldsize);
if (ret) {
- mddev->bitmap_ops->resize(mddev, oldsize, 0, false);
+ mddev->bitmap_ops->resize(mddev, oldsize, 0);
goto abort;
}
}
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 7ec61ee7b218..999752ec636e 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -8322,7 +8322,7 @@ static int raid5_resize(struct mddev *mddev, sector_t sectors)
mddev->array_sectors > newsize)
return -EINVAL;
- ret = mddev->bitmap_ops->resize(mddev, sectors, 0, false);
+ ret = mddev->bitmap_ops->resize(mddev, sectors, 0);
if (ret)
return ret;
--
2.39.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v5 04/15] md/md-bitmap: merge md_bitmap_group into bitmap_operations
2025-07-07 1:26 [PATCH v5 00/15] md/md-bitmap: introduce CONFIG_MD_BITMAP Yu Kuai
` (2 preceding siblings ...)
2025-07-07 1:26 ` [PATCH v5 03/15] md/md-bitmap: remove the parameter 'init' for bitmap_ops->resize() Yu Kuai
@ 2025-07-07 1:27 ` Yu Kuai
2025-07-25 3:42 ` Xiao Ni
2025-07-07 1:27 ` [PATCH v5 05/15] md/md-bitmap: add a new parameter 'flush' to bitmap_ops->enabled Yu Kuai
` (12 subsequent siblings)
16 siblings, 1 reply; 20+ messages in thread
From: Yu Kuai @ 2025-07-07 1:27 UTC (permalink / raw)
To: agk, snitzer, mpatocka, song, yukuai3
Cc: dm-devel, linux-raid, linux-kernel, yukuai1, yi.zhang, yangerkun,
johnny.chenyi
From: Yu Kuai <yukuai3@huawei.com>
Now that all bitmap implementations are internal, it doesn't make sense
to export md_bitmap_group anymore.
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
---
drivers/md/md-bitmap.c | 5 ++++-
drivers/md/md-bitmap.h | 2 ++
drivers/md/md.c | 6 +++++-
drivers/md/md.h | 1 -
4 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
index fc7282304b00..0ba1da35aa84 100644
--- a/drivers/md/md-bitmap.c
+++ b/drivers/md/md-bitmap.c
@@ -2990,7 +2990,8 @@ static struct attribute *md_bitmap_attrs[] = {
&max_backlog_used.attr,
NULL
};
-const struct attribute_group md_bitmap_group = {
+
+static struct attribute_group md_bitmap_group = {
.name = "bitmap",
.attrs = md_bitmap_attrs,
};
@@ -3026,6 +3027,8 @@ static struct bitmap_operations bitmap_ops = {
.copy_from_slot = bitmap_copy_from_slot,
.set_pages = bitmap_set_pages,
.free = md_bitmap_free,
+
+ .group = &md_bitmap_group,
};
void mddev_set_bitmap_ops(struct mddev *mddev)
diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h
index 28c1f1c1cc83..0ceb9e97d21f 100644
--- a/drivers/md/md-bitmap.h
+++ b/drivers/md/md-bitmap.h
@@ -100,6 +100,8 @@ struct bitmap_operations {
sector_t *hi, bool clear_bits);
void (*set_pages)(void *data, unsigned long pages);
void (*free)(void *data);
+
+ struct attribute_group *group;
};
/* the bitmap API */
diff --git a/drivers/md/md.c b/drivers/md/md.c
index bda3ef814d97..7ed95e5e43fc 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -5749,7 +5749,6 @@ static const struct attribute_group md_redundancy_group = {
static const struct attribute_group *md_attr_groups[] = {
&md_default_group,
- &md_bitmap_group,
NULL,
};
@@ -5996,6 +5995,11 @@ struct mddev *md_alloc(dev_t dev, char *name)
return ERR_PTR(error);
}
+ if (mddev->bitmap_ops && mddev->bitmap_ops->group)
+ if (sysfs_create_group(&mddev->kobj, mddev->bitmap_ops->group))
+ pr_warn("md: cannot register extra bitmap attributes for %s\n",
+ mdname(mddev));
+
kobject_uevent(&mddev->kobj, KOBJ_ADD);
mddev->sysfs_state = sysfs_get_dirent_safe(mddev->kobj.sd, "array_state");
mddev->sysfs_level = sysfs_get_dirent_safe(mddev->kobj.sd, "level");
diff --git a/drivers/md/md.h b/drivers/md/md.h
index 67b365621507..d6fba4240f97 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -796,7 +796,6 @@ struct md_sysfs_entry {
ssize_t (*show)(struct mddev *, char *);
ssize_t (*store)(struct mddev *, const char *, size_t);
};
-extern const struct attribute_group md_bitmap_group;
static inline struct kernfs_node *sysfs_get_dirent_safe(struct kernfs_node *sd, char *name)
{
--
2.39.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v5 05/15] md/md-bitmap: add a new parameter 'flush' to bitmap_ops->enabled
2025-07-07 1:26 [PATCH v5 00/15] md/md-bitmap: introduce CONFIG_MD_BITMAP Yu Kuai
` (3 preceding siblings ...)
2025-07-07 1:27 ` [PATCH v5 04/15] md/md-bitmap: merge md_bitmap_group into bitmap_operations Yu Kuai
@ 2025-07-07 1:27 ` Yu Kuai
2025-07-07 1:27 ` [PATCH v5 06/15] md/md-bitmap: add md_bitmap_registered/enabled() helper Yu Kuai
` (11 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Yu Kuai @ 2025-07-07 1:27 UTC (permalink / raw)
To: agk, snitzer, mpatocka, song, yukuai3
Cc: dm-devel, linux-raid, linux-kernel, yukuai1, yi.zhang, yangerkun,
johnny.chenyi
From: Yu Kuai <yukuai3@huawei.com>
The method is only used from raid1/raid10 IO path, to check if write
bio should be pluged, the parameter is always set to true for now,
following patch will use this helper in other context like updating
superblock.
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
---
drivers/md/md-bitmap.c | 19 +++++++++++++------
drivers/md/md-bitmap.h | 2 +-
drivers/md/raid1-10.c | 2 +-
3 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
index 0ba1da35aa84..3f52716ea6f5 100644
--- a/drivers/md/md-bitmap.c
+++ b/drivers/md/md-bitmap.c
@@ -232,20 +232,27 @@ static inline char *bmname(struct bitmap *bitmap)
return bitmap->mddev ? mdname(bitmap->mddev) : "mdX";
}
-static bool __bitmap_enabled(struct bitmap *bitmap)
+static bool __bitmap_enabled(struct bitmap *bitmap, bool flush)
{
- return bitmap->storage.filemap &&
- !test_bit(BITMAP_STALE, &bitmap->flags);
+ if (!flush)
+ return true;
+
+ /*
+ * If caller want to flush bitmap pages to underlying disks, check if
+ * there are cached pages in filemap.
+ */
+ return !test_bit(BITMAP_STALE, &bitmap->flags) &&
+ bitmap->storage.filemap != NULL;
}
-static bool bitmap_enabled(struct mddev *mddev)
+static bool bitmap_enabled(struct mddev *mddev, bool flush)
{
struct bitmap *bitmap = mddev->bitmap;
if (!bitmap)
return false;
- return __bitmap_enabled(bitmap);
+ return __bitmap_enabled(bitmap, flush);
}
/*
@@ -1244,7 +1251,7 @@ static void __bitmap_unplug(struct bitmap *bitmap)
int dirty, need_write;
int writing = 0;
- if (!__bitmap_enabled(bitmap))
+ if (!__bitmap_enabled(bitmap, true))
return;
/* look at each page to see if there are any set bits that need to be
diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h
index 0ceb9e97d21f..63d91831655f 100644
--- a/drivers/md/md-bitmap.h
+++ b/drivers/md/md-bitmap.h
@@ -62,7 +62,7 @@ struct md_bitmap_stats {
};
struct bitmap_operations {
- bool (*enabled)(struct mddev *mddev);
+ bool (*enabled)(struct mddev *mddev, bool flush);
int (*create)(struct mddev *mddev);
int (*resize)(struct mddev *mddev, sector_t blocks, int chunksize);
diff --git a/drivers/md/raid1-10.c b/drivers/md/raid1-10.c
index b8b3a9069701..4ad051d49cdc 100644
--- a/drivers/md/raid1-10.c
+++ b/drivers/md/raid1-10.c
@@ -140,7 +140,7 @@ static inline bool raid1_add_bio_to_plug(struct mddev *mddev, struct bio *bio,
* If bitmap is not enabled, it's safe to submit the io directly, and
* this can get optimal performance.
*/
- if (!mddev->bitmap_ops->enabled(mddev)) {
+ if (!mddev->bitmap_ops->enabled(mddev, true)) {
raid1_submit_write(bio);
return true;
}
--
2.39.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v5 06/15] md/md-bitmap: add md_bitmap_registered/enabled() helper
2025-07-07 1:26 [PATCH v5 00/15] md/md-bitmap: introduce CONFIG_MD_BITMAP Yu Kuai
` (4 preceding siblings ...)
2025-07-07 1:27 ` [PATCH v5 05/15] md/md-bitmap: add a new parameter 'flush' to bitmap_ops->enabled Yu Kuai
@ 2025-07-07 1:27 ` Yu Kuai
2025-07-07 1:27 ` [PATCH v5 07/15] md/md-bitmap: handle the case bitmap is not enabled before start_sync() Yu Kuai
` (10 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Yu Kuai @ 2025-07-07 1:27 UTC (permalink / raw)
To: agk, snitzer, mpatocka, song, yukuai3
Cc: dm-devel, linux-raid, linux-kernel, yukuai1, yi.zhang, yangerkun,
johnny.chenyi
From: Yu Kuai <yukuai3@huawei.com>
There are no functional changes, prepare to handle the case that
mddev->bitmap_ops can be NULL, which is possible after introducing
CONFIG_MD_BITMAP.
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
---
drivers/md/md-bitmap.c | 16 ++++------------
drivers/md/md-bitmap.h | 19 ++++++++++++++++++-
drivers/md/raid1-10.c | 2 +-
3 files changed, 23 insertions(+), 14 deletions(-)
diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
index 3f52716ea6f5..da2dcb3d2122 100644
--- a/drivers/md/md-bitmap.c
+++ b/drivers/md/md-bitmap.c
@@ -232,8 +232,10 @@ static inline char *bmname(struct bitmap *bitmap)
return bitmap->mddev ? mdname(bitmap->mddev) : "mdX";
}
-static bool __bitmap_enabled(struct bitmap *bitmap, bool flush)
+static bool bitmap_enabled(void *data, bool flush)
{
+ struct bitmap *bitmap = data;
+
if (!flush)
return true;
@@ -245,16 +247,6 @@ static bool __bitmap_enabled(struct bitmap *bitmap, bool flush)
bitmap->storage.filemap != NULL;
}
-static bool bitmap_enabled(struct mddev *mddev, bool flush)
-{
- struct bitmap *bitmap = mddev->bitmap;
-
- if (!bitmap)
- return false;
-
- return __bitmap_enabled(bitmap, flush);
-}
-
/*
* check a page and, if necessary, allocate it (or hijack it if the alloc fails)
*
@@ -1251,7 +1243,7 @@ static void __bitmap_unplug(struct bitmap *bitmap)
int dirty, need_write;
int writing = 0;
- if (!__bitmap_enabled(bitmap, true))
+ if (!bitmap_enabled(bitmap, true))
return;
/* look at each page to see if there are any set bits that need to be
diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h
index 63d91831655f..a36ed32ec0d5 100644
--- a/drivers/md/md-bitmap.h
+++ b/drivers/md/md-bitmap.h
@@ -62,7 +62,7 @@ struct md_bitmap_stats {
};
struct bitmap_operations {
- bool (*enabled)(struct mddev *mddev, bool flush);
+ bool (*enabled)(void *data, bool flush);
int (*create)(struct mddev *mddev);
int (*resize)(struct mddev *mddev, sector_t blocks, int chunksize);
@@ -107,4 +107,21 @@ 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;
+}
+
+static inline bool md_bitmap_enabled(struct mddev *mddev, bool flush)
+{
+ /* bitmap_ops must be registered before creating bitmap. */
+ if (!md_bitmap_registered(mddev))
+ return false;
+
+ if (!mddev->bitmap)
+ return false;
+
+ return mddev->bitmap_ops->enabled(mddev->bitmap, flush);
+}
+
#endif
diff --git a/drivers/md/raid1-10.c b/drivers/md/raid1-10.c
index 4ad051d49cdc..0ad8b28ab7c2 100644
--- a/drivers/md/raid1-10.c
+++ b/drivers/md/raid1-10.c
@@ -140,7 +140,7 @@ static inline bool raid1_add_bio_to_plug(struct mddev *mddev, struct bio *bio,
* If bitmap is not enabled, it's safe to submit the io directly, and
* this can get optimal performance.
*/
- if (!mddev->bitmap_ops->enabled(mddev, true)) {
+ if (!md_bitmap_enabled(mddev, true)) {
raid1_submit_write(bio);
return true;
}
--
2.39.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v5 07/15] md/md-bitmap: handle the case bitmap is not enabled before start_sync()
2025-07-07 1:26 [PATCH v5 00/15] md/md-bitmap: introduce CONFIG_MD_BITMAP Yu Kuai
` (5 preceding siblings ...)
2025-07-07 1:27 ` [PATCH v5 06/15] md/md-bitmap: add md_bitmap_registered/enabled() helper Yu Kuai
@ 2025-07-07 1:27 ` Yu Kuai
2025-07-07 1:27 ` [PATCH v5 08/15] md/md-bitmap: handle the case bitmap is not enabled before end_sync() Yu Kuai
` (9 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Yu Kuai @ 2025-07-07 1:27 UTC (permalink / raw)
To: agk, snitzer, mpatocka, song, yukuai3
Cc: dm-devel, linux-raid, linux-kernel, yukuai1, yi.zhang, yangerkun,
johnny.chenyi
From: Yu Kuai <yukuai3@huawei.com>
This case can be handled without knowing internal implementation.
Prepare to introduce CONFIG_MD_BITMAP.
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
---
drivers/md/md-bitmap.c | 8 +-------
drivers/md/md-bitmap.h | 12 ++++++++++++
drivers/md/raid1.c | 6 +++---
drivers/md/raid10.c | 15 ++++++---------
drivers/md/raid5.c | 7 ++-----
5 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
index da2dcb3d2122..ee676d4670ea 100644
--- a/drivers/md/md-bitmap.c
+++ b/drivers/md/md-bitmap.c
@@ -1787,15 +1787,9 @@ static bool __bitmap_start_sync(struct bitmap *bitmap, sector_t offset,
sector_t *blocks, bool degraded)
{
bitmap_counter_t *bmc;
- bool rv;
+ bool rv = false;
- if (bitmap == NULL) {/* FIXME or bitmap set as 'failed' */
- *blocks = 1024;
- return true; /* always resync if no bitmap */
- }
spin_lock_irq(&bitmap->counts.lock);
-
- rv = false;
bmc = md_bitmap_get_counter(&bitmap->counts, offset, blocks, 0);
if (bmc) {
/* locked */
diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h
index a36ed32ec0d5..7a16de62ee35 100644
--- a/drivers/md/md-bitmap.h
+++ b/drivers/md/md-bitmap.h
@@ -124,4 +124,16 @@ static inline bool md_bitmap_enabled(struct mddev *mddev, bool flush)
return mddev->bitmap_ops->enabled(mddev->bitmap, flush);
}
+static inline bool md_bitmap_start_sync(struct mddev *mddev, sector_t offset,
+ sector_t *blocks, bool degraded)
+{
+ /* always resync if no bitmap */
+ if (!md_bitmap_enabled(mddev, false)) {
+ *blocks = 1024;
+ return true;
+ }
+
+ return mddev->bitmap_ops->start_sync(mddev, offset, blocks, degraded);
+}
+
#endif
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 39ebe0fadacd..1f3f2046afe0 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -2828,7 +2828,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
/* before building a request, check if we can skip these blocks..
* This call the bitmap_start_sync doesn't actually record anything
*/
- if (!mddev->bitmap_ops->start_sync(mddev, sector_nr, &sync_blocks, true) &&
+ if (!md_bitmap_start_sync(mddev, sector_nr, &sync_blocks, true) &&
!conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
/* We can skip this block, and probably several more */
*skipped = 1;
@@ -3003,8 +3003,8 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
if (len == 0)
break;
if (sync_blocks == 0) {
- if (!mddev->bitmap_ops->start_sync(mddev, sector_nr,
- &sync_blocks, still_degraded) &&
+ if (!md_bitmap_start_sync(mddev, sector_nr,
+ &sync_blocks, still_degraded) &&
!conf->fullsync &&
!test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
break;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index d2ef96be0150..764a8d99c45e 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -3346,9 +3346,8 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
* we only need to recover the block if it is set in
* the bitmap
*/
- must_sync = mddev->bitmap_ops->start_sync(mddev, sect,
- &sync_blocks,
- true);
+ must_sync = md_bitmap_start_sync(mddev, sect,
+ &sync_blocks, true);
if (sync_blocks < max_sync)
max_sync = sync_blocks;
if (!must_sync &&
@@ -3391,9 +3390,8 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
}
}
- must_sync = mddev->bitmap_ops->start_sync(mddev, sect,
- &sync_blocks, still_degraded);
-
+ md_bitmap_start_sync(mddev, sect, &sync_blocks,
+ still_degraded);
any_working = 0;
for (j=0; j<conf->copies;j++) {
int k;
@@ -3569,9 +3567,8 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
mddev_is_clustered(mddev) &&
(sector_nr + 2 * RESYNC_SECTORS > conf->cluster_sync_high));
- if (!mddev->bitmap_ops->start_sync(mddev, sector_nr,
- &sync_blocks,
- mddev->degraded) &&
+ if (!md_bitmap_start_sync(mddev, sector_nr, &sync_blocks,
+ mddev->degraded) &&
!conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED,
&mddev->recovery)) {
/* We can skip this block */
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 999752ec636e..8168acf7d3e7 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -6525,8 +6525,7 @@ static inline sector_t raid5_sync_request(struct mddev *mddev, sector_t sector_n
}
if (!test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) &&
!conf->fullsync &&
- !mddev->bitmap_ops->start_sync(mddev, sector_nr, &sync_blocks,
- true) &&
+ !md_bitmap_start_sync(mddev, sector_nr, &sync_blocks, true) &&
sync_blocks >= RAID5_STRIPE_SECTORS(conf)) {
/* we can skip this block, and probably more */
do_div(sync_blocks, RAID5_STRIPE_SECTORS(conf));
@@ -6557,9 +6556,7 @@ static inline sector_t raid5_sync_request(struct mddev *mddev, sector_t sector_n
still_degraded = true;
}
- mddev->bitmap_ops->start_sync(mddev, sector_nr, &sync_blocks,
- still_degraded);
-
+ md_bitmap_start_sync(mddev, sector_nr, &sync_blocks, still_degraded);
set_bit(STRIPE_SYNC_REQUESTED, &sh->state);
set_bit(STRIPE_HANDLE, &sh->state);
--
2.39.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v5 08/15] md/md-bitmap: handle the case bitmap is not enabled before end_sync()
2025-07-07 1:26 [PATCH v5 00/15] md/md-bitmap: introduce CONFIG_MD_BITMAP Yu Kuai
` (6 preceding siblings ...)
2025-07-07 1:27 ` [PATCH v5 07/15] md/md-bitmap: handle the case bitmap is not enabled before start_sync() Yu Kuai
@ 2025-07-07 1:27 ` Yu Kuai
2025-07-07 1:27 ` [PATCH v5 09/15] md/raid1: check bitmap before behind write Yu Kuai
` (8 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Yu Kuai @ 2025-07-07 1:27 UTC (permalink / raw)
To: agk, snitzer, mpatocka, song, yukuai3
Cc: dm-devel, linux-raid, linux-kernel, yukuai1, yi.zhang, yangerkun,
johnny.chenyi
From: Yu Kuai <yukuai3@huawei.com>
This case can be handled without knowing internal implementation.
Prepare to introduce CONFIG_MD_BITMAP.
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
---
drivers/md/md-bitmap.c | 4 ----
drivers/md/md-bitmap.h | 11 +++++++++++
drivers/md/raid1.c | 6 +++---
drivers/md/raid10.c | 8 +++-----
drivers/md/raid5.c | 4 ++--
5 files changed, 19 insertions(+), 14 deletions(-)
diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
index ee676d4670ea..a079cbe2e6f1 100644
--- a/drivers/md/md-bitmap.c
+++ b/drivers/md/md-bitmap.c
@@ -1838,10 +1838,6 @@ static void __bitmap_end_sync(struct bitmap *bitmap, sector_t offset,
bitmap_counter_t *bmc;
unsigned long flags;
- if (bitmap == NULL) {
- *blocks = 1024;
- return;
- }
spin_lock_irqsave(&bitmap->counts.lock, flags);
bmc = md_bitmap_get_counter(&bitmap->counts, offset, blocks, 0);
if (bmc == NULL)
diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h
index 7a16de62ee35..61cfc650c69c 100644
--- a/drivers/md/md-bitmap.h
+++ b/drivers/md/md-bitmap.h
@@ -136,4 +136,15 @@ static inline bool md_bitmap_start_sync(struct mddev *mddev, sector_t offset,
return mddev->bitmap_ops->start_sync(mddev, offset, blocks, degraded);
}
+static inline void md_bitmap_end_sync(struct mddev *mddev, sector_t offset,
+ sector_t *blocks)
+{
+ if (!md_bitmap_enabled(mddev, false)) {
+ *blocks = 1024;
+ return;
+ }
+
+ mddev->bitmap_ops->end_sync(mddev, offset, blocks);
+}
+
#endif
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 1f3f2046afe0..a46ce996ea9c 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -2056,7 +2056,7 @@ static void abort_sync_write(struct mddev *mddev, struct r1bio *r1_bio)
/* make sure these bits don't get cleared. */
do {
- mddev->bitmap_ops->end_sync(mddev, s, &sync_blocks);
+ md_bitmap_end_sync(mddev, s, &sync_blocks);
s += sync_blocks;
sectors_to_go -= sync_blocks;
} while (sectors_to_go > 0);
@@ -2803,8 +2803,8 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
* We can find the current addess in mddev->curr_resync
*/
if (mddev->curr_resync < max_sector) /* aborted */
- mddev->bitmap_ops->end_sync(mddev, mddev->curr_resync,
- &sync_blocks);
+ md_bitmap_end_sync(mddev, mddev->curr_resync,
+ &sync_blocks);
else /* completed sync */
conf->fullsync = 0;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 764a8d99c45e..c0aa19935881 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -3216,15 +3216,13 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
if (mddev->curr_resync < max_sector) { /* aborted */
if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
- mddev->bitmap_ops->end_sync(mddev,
- mddev->curr_resync,
- &sync_blocks);
+ md_bitmap_end_sync(mddev, mddev->curr_resync,
+ &sync_blocks);
else for (i = 0; i < conf->geo.raid_disks; i++) {
sector_t sect =
raid10_find_virt(conf, mddev->curr_resync, i);
- mddev->bitmap_ops->end_sync(mddev, sect,
- &sync_blocks);
+ md_bitmap_end_sync(mddev, sect, &sync_blocks);
}
} else {
/* completed sync */
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 8168acf7d3e7..156504ed0dd4 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -6492,8 +6492,8 @@ static inline sector_t raid5_sync_request(struct mddev *mddev, sector_t sector_n
}
if (mddev->curr_resync < max_sector) /* aborted */
- mddev->bitmap_ops->end_sync(mddev, mddev->curr_resync,
- &sync_blocks);
+ md_bitmap_end_sync(mddev, mddev->curr_resync,
+ &sync_blocks);
else /* completed sync */
conf->fullsync = 0;
mddev->bitmap_ops->close_sync(mddev);
--
2.39.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v5 09/15] md/raid1: check bitmap before behind write
2025-07-07 1:26 [PATCH v5 00/15] md/md-bitmap: introduce CONFIG_MD_BITMAP Yu Kuai
` (7 preceding siblings ...)
2025-07-07 1:27 ` [PATCH v5 08/15] md/md-bitmap: handle the case bitmap is not enabled before end_sync() Yu Kuai
@ 2025-07-07 1:27 ` Yu Kuai
2025-07-07 1:27 ` [PATCH v5 10/15] md/raid1: check before referencing mddev->bitmap_ops Yu Kuai
` (7 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Yu Kuai @ 2025-07-07 1:27 UTC (permalink / raw)
To: agk, snitzer, mpatocka, song, yukuai3
Cc: dm-devel, linux-raid, linux-kernel, yukuai1, yi.zhang, yangerkun,
johnny.chenyi
From: Yu Kuai <yukuai3@huawei.com>
behind write rely on bitmap, because the number of IO are recorded in
bitmap->behind_writes, and callers rely on bitmap_wait_behind_writes()
to wait for IO to be done.
However, currently callers doesn't check if bitmap is enabeld before
calling into behind methods. Hence if behind write start without bitmap,
readers will not wait for slow write IO to be done and old data can be
read in some corner cases.
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
---
drivers/md/md-bitmap.c | 6 ------
drivers/md/raid1.c | 45 ++++++++++++++++++++++++++----------------
2 files changed, 28 insertions(+), 23 deletions(-)
diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
index a079cbe2e6f1..5bd75fa6ee1d 100644
--- a/drivers/md/md-bitmap.c
+++ b/drivers/md/md-bitmap.c
@@ -2049,9 +2049,6 @@ static void bitmap_start_behind_write(struct mddev *mddev)
struct bitmap *bitmap = mddev->bitmap;
int bw;
- if (!bitmap)
- return;
-
atomic_inc(&bitmap->behind_writes);
bw = atomic_read(&bitmap->behind_writes);
if (bw > bitmap->behind_writes_used)
@@ -2065,9 +2062,6 @@ static void bitmap_end_behind_write(struct mddev *mddev)
{
struct bitmap *bitmap = mddev->bitmap;
- if (!bitmap)
- return;
-
if (atomic_dec_and_test(&bitmap->behind_writes))
wake_up(&bitmap->behind_wait);
pr_debug("dec write-behind count %d/%lu\n",
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index a46ce996ea9c..015eabb502ec 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1366,7 +1366,8 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
(unsigned long long)r1_bio->sector,
mirror->rdev->bdev);
- if (test_bit(WriteMostly, &mirror->rdev->flags)) {
+ if (test_bit(WriteMostly, &mirror->rdev->flags) &&
+ md_bitmap_enabled(mddev, false)) {
/*
* Reading from a write-mostly device must take care not to
* over-take any writes that are 'behind'
@@ -1452,6 +1453,30 @@ static bool wait_blocked_rdev(struct mddev *mddev, struct bio *bio)
return true;
}
+static void raid1_start_write_behind(struct mddev *mddev, struct r1bio *r1_bio,
+ struct bio *bio)
+{
+ unsigned long max_write_behind = mddev->bitmap_info.max_write_behind;
+ struct md_bitmap_stats stats;
+ int err;
+
+ /* behind write rely on bitmap, see bitmap_operations */
+ if (!md_bitmap_enabled(mddev, false))
+ return;
+
+ err = mddev->bitmap_ops->get_stats(mddev->bitmap, &stats);
+ if (err)
+ return;
+
+ /* Don't do behind IO if reader is waiting, or there are too many. */
+ if (!stats.behind_wait && stats.behind_writes < max_write_behind)
+ alloc_behind_master_bio(r1_bio, bio);
+
+ if (test_bit(R1BIO_BehindIO, &r1_bio->state))
+ mddev->bitmap_ops->start_behind_write(mddev);
+
+}
+
static void raid1_write_request(struct mddev *mddev, struct bio *bio,
int max_write_sectors)
{
@@ -1612,22 +1637,8 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
continue;
if (first_clone) {
- unsigned long max_write_behind =
- mddev->bitmap_info.max_write_behind;
- struct md_bitmap_stats stats;
- int err;
-
- /* do behind I/O ?
- * Not if there are too many, or cannot
- * allocate memory, or a reader on WriteMostly
- * is waiting for behind writes to flush */
- err = mddev->bitmap_ops->get_stats(mddev->bitmap, &stats);
- if (!err && write_behind && !stats.behind_wait &&
- stats.behind_writes < max_write_behind)
- alloc_behind_master_bio(r1_bio, bio);
-
- if (test_bit(R1BIO_BehindIO, &r1_bio->state))
- mddev->bitmap_ops->start_behind_write(mddev);
+ if (write_behind)
+ raid1_start_write_behind(mddev, r1_bio, bio);
first_clone = 0;
}
--
2.39.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v5 10/15] md/raid1: check before referencing mddev->bitmap_ops
2025-07-07 1:26 [PATCH v5 00/15] md/md-bitmap: introduce CONFIG_MD_BITMAP Yu Kuai
` (8 preceding siblings ...)
2025-07-07 1:27 ` [PATCH v5 09/15] md/raid1: check bitmap before behind write Yu Kuai
@ 2025-07-07 1:27 ` Yu Kuai
2025-07-07 1:27 ` [PATCH v5 11/15] md/raid10: " Yu Kuai
` (6 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Yu Kuai @ 2025-07-07 1:27 UTC (permalink / raw)
To: agk, snitzer, mpatocka, song, yukuai3
Cc: dm-devel, linux-raid, linux-kernel, yukuai1, yi.zhang, yangerkun,
johnny.chenyi
From: Yu Kuai <yukuai3@huawei.com>
Prepare to introduce CONFIG_MD_BITMAP.
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
---
drivers/md/raid1.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 015eabb502ec..ea6a134be9d5 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -2819,7 +2819,8 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
else /* completed sync */
conf->fullsync = 0;
- mddev->bitmap_ops->close_sync(mddev);
+ if (md_bitmap_enabled(mddev, false))
+ mddev->bitmap_ops->close_sync(mddev);
close_sync(conf);
if (mddev_is_clustered(mddev)) {
@@ -2856,10 +2857,11 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
/* we are incrementing sector_nr below. To be safe, we check against
* sector_nr + two times RESYNC_SECTORS
*/
-
- mddev->bitmap_ops->cond_end_sync(mddev, sector_nr,
- mddev_is_clustered(mddev) &&
- (sector_nr + 2 * RESYNC_SECTORS > conf->cluster_sync_high));
+ if (md_bitmap_enabled(mddev, false))
+ mddev->bitmap_ops->cond_end_sync(mddev, sector_nr,
+ mddev_is_clustered(mddev) &&
+ (sector_nr + 2 * RESYNC_SECTORS >
+ conf->cluster_sync_high));
if (raise_barrier(conf, sector_nr))
return 0;
@@ -3334,15 +3336,17 @@ static int raid1_resize(struct mddev *mddev, sector_t sectors)
* worth it.
*/
sector_t newsize = raid1_size(mddev, sectors, 0);
- int ret;
if (mddev->external_size &&
mddev->array_sectors > newsize)
return -EINVAL;
- ret = mddev->bitmap_ops->resize(mddev, newsize, 0);
- if (ret)
- return ret;
+ if (md_bitmap_enabled(mddev, false)) {
+ int ret = mddev->bitmap_ops->resize(mddev, newsize, 0);
+
+ if (ret)
+ return ret;
+ }
md_set_array_sectors(mddev, newsize);
if (sectors > mddev->dev_sectors &&
--
2.39.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v5 11/15] md/raid10: check before referencing mddev->bitmap_ops
2025-07-07 1:26 [PATCH v5 00/15] md/md-bitmap: introduce CONFIG_MD_BITMAP Yu Kuai
` (9 preceding siblings ...)
2025-07-07 1:27 ` [PATCH v5 10/15] md/raid1: check before referencing mddev->bitmap_ops Yu Kuai
@ 2025-07-07 1:27 ` Yu Kuai
2025-07-07 1:27 ` [PATCH v5 12/15] md/raid5: " Yu Kuai
` (5 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Yu Kuai @ 2025-07-07 1:27 UTC (permalink / raw)
To: agk, snitzer, mpatocka, song, yukuai3
Cc: dm-devel, linux-raid, linux-kernel, yukuai1, yi.zhang, yangerkun,
johnny.chenyi
From: Yu Kuai <yukuai3@huawei.com>
Prepare to introduce CONFIG_MD_BITMAP.
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
---
drivers/md/raid10.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index c0aa19935881..5397b7e20399 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -3242,7 +3242,8 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
}
conf->fullsync = 0;
}
- mddev->bitmap_ops->close_sync(mddev);
+ if (md_bitmap_enabled(mddev, false))
+ mddev->bitmap_ops->close_sync(mddev);
close_sync(conf);
*skipped = 1;
return sectors_skipped;
@@ -3561,7 +3562,8 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
* safety reason, which ensures curr_resync_completed is
* updated in bitmap_cond_end_sync.
*/
- mddev->bitmap_ops->cond_end_sync(mddev, sector_nr,
+ if (md_bitmap_enabled(mddev, false))
+ mddev->bitmap_ops->cond_end_sync(mddev, sector_nr,
mddev_is_clustered(mddev) &&
(sector_nr + 2 * RESYNC_SECTORS > conf->cluster_sync_high));
@@ -4214,7 +4216,6 @@ static int raid10_resize(struct mddev *mddev, sector_t sectors)
*/
struct r10conf *conf = mddev->private;
sector_t oldsize, size;
- int ret;
if (mddev->reshape_position != MaxSector)
return -EBUSY;
@@ -4228,9 +4229,12 @@ static int raid10_resize(struct mddev *mddev, sector_t sectors)
mddev->array_sectors > size)
return -EINVAL;
- ret = mddev->bitmap_ops->resize(mddev, size, 0);
- if (ret)
- return ret;
+ if (md_bitmap_enabled(mddev, false)) {
+ int ret = mddev->bitmap_ops->resize(mddev, size, 0);
+
+ if (ret)
+ return ret;
+ }
md_set_array_sectors(mddev, size);
if (sectors > mddev->dev_sectors &&
@@ -4496,7 +4500,8 @@ static int raid10_start_reshape(struct mddev *mddev)
oldsize = raid10_size(mddev, 0, 0);
newsize = raid10_size(mddev, 0, conf->geo.raid_disks);
- if (!mddev_is_clustered(mddev)) {
+ if (!mddev_is_clustered(mddev) &&
+ md_bitmap_enabled(mddev, false)) {
ret = mddev->bitmap_ops->resize(mddev, newsize, 0);
if (ret)
goto abort;
@@ -4519,6 +4524,7 @@ static int raid10_start_reshape(struct mddev *mddev)
MD_FEATURE_RESHAPE_ACTIVE)) || (oldsize == newsize))
goto out;
+ /* cluster can't be setup without bitmap */
ret = mddev->bitmap_ops->resize(mddev, newsize, 0);
if (ret)
goto abort;
--
2.39.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v5 12/15] md/raid5: check before referencing mddev->bitmap_ops
2025-07-07 1:26 [PATCH v5 00/15] md/md-bitmap: introduce CONFIG_MD_BITMAP Yu Kuai
` (10 preceding siblings ...)
2025-07-07 1:27 ` [PATCH v5 11/15] md/raid10: " Yu Kuai
@ 2025-07-07 1:27 ` Yu Kuai
2025-07-07 1:27 ` [PATCH v5 13/15] md/dm-raid: " Yu Kuai
` (4 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Yu Kuai @ 2025-07-07 1:27 UTC (permalink / raw)
To: agk, snitzer, mpatocka, song, yukuai3
Cc: dm-devel, linux-raid, linux-kernel, yukuai1, yi.zhang, yangerkun,
johnny.chenyi
From: Yu Kuai <yukuai3@huawei.com>
Prepare to introduce CONFIG_MD_BITMAP.
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
---
drivers/md/raid5.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 156504ed0dd4..519bbfb67dcb 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -6496,7 +6496,8 @@ static inline sector_t raid5_sync_request(struct mddev *mddev, sector_t sector_n
&sync_blocks);
else /* completed sync */
conf->fullsync = 0;
- mddev->bitmap_ops->close_sync(mddev);
+ if (md_bitmap_enabled(mddev, false))
+ mddev->bitmap_ops->close_sync(mddev);
return 0;
}
@@ -6534,7 +6535,8 @@ static inline sector_t raid5_sync_request(struct mddev *mddev, sector_t sector_n
return sync_blocks * RAID5_STRIPE_SECTORS(conf);
}
- mddev->bitmap_ops->cond_end_sync(mddev, sector_nr, false);
+ if (md_bitmap_enabled(mddev, false))
+ mddev->bitmap_ops->cond_end_sync(mddev, sector_nr, false);
sh = raid5_get_active_stripe(conf, NULL, sector_nr,
R5_GAS_NOBLOCK);
@@ -6760,7 +6762,8 @@ static void raid5d(struct md_thread *thread)
/* Now is a good time to flush some bitmap updates */
conf->seq_flush++;
spin_unlock_irq(&conf->device_lock);
- mddev->bitmap_ops->unplug(mddev, true);
+ if (md_bitmap_enabled(mddev, true))
+ mddev->bitmap_ops->unplug(mddev, true);
spin_lock_irq(&conf->device_lock);
conf->seq_write = conf->seq_flush;
activate_bit_delay(conf, conf->temp_inactive_list);
@@ -8309,7 +8312,6 @@ static int raid5_resize(struct mddev *mddev, sector_t sectors)
*/
sector_t newsize;
struct r5conf *conf = mddev->private;
- int ret;
if (raid5_has_log(conf) || raid5_has_ppl(conf))
return -EINVAL;
@@ -8319,9 +8321,12 @@ static int raid5_resize(struct mddev *mddev, sector_t sectors)
mddev->array_sectors > newsize)
return -EINVAL;
- ret = mddev->bitmap_ops->resize(mddev, sectors, 0);
- if (ret)
- return ret;
+ if (md_bitmap_enabled(mddev, false)) {
+ int ret = mddev->bitmap_ops->resize(mddev, sectors, 0);
+
+ if (ret)
+ return ret;
+ }
md_set_array_sectors(mddev, newsize);
if (sectors > mddev->dev_sectors &&
--
2.39.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v5 13/15] md/dm-raid: check before referencing mddev->bitmap_ops
2025-07-07 1:26 [PATCH v5 00/15] md/md-bitmap: introduce CONFIG_MD_BITMAP Yu Kuai
` (11 preceding siblings ...)
2025-07-07 1:27 ` [PATCH v5 12/15] md/raid5: " Yu Kuai
@ 2025-07-07 1:27 ` Yu Kuai
2025-07-07 1:27 ` [PATCH v5 14/15] md: " Yu Kuai
` (3 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Yu Kuai @ 2025-07-07 1:27 UTC (permalink / raw)
To: agk, snitzer, mpatocka, song, yukuai3
Cc: dm-devel, linux-raid, linux-kernel, yukuai1, yi.zhang, yangerkun,
johnny.chenyi
From: Yu Kuai <yukuai3@huawei.com>
Prepare to introduce CONFIG_MD_BITMAP.
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
---
drivers/md/dm-raid.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index 9757c32ea1f5..f11b4e1d9b75 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -3950,9 +3950,11 @@ static int __load_dirty_region_bitmap(struct raid_set *rs)
!test_and_set_bit(RT_FLAG_RS_BITMAP_LOADED, &rs->runtime_flags)) {
struct mddev *mddev = &rs->md;
- r = mddev->bitmap_ops->load(mddev);
- if (r)
- DMERR("Failed to load bitmap");
+ if (md_bitmap_enabled(mddev, false)) {
+ r = mddev->bitmap_ops->load(mddev);
+ if (r)
+ DMERR("Failed to load bitmap");
+ }
}
return r;
@@ -4067,10 +4069,12 @@ static int raid_preresume(struct dm_target *ti)
mddev->bitmap_info.chunksize != to_bytes(rs->requested_bitmap_chunk_sectors)))) {
int chunksize = to_bytes(rs->requested_bitmap_chunk_sectors) ?: mddev->bitmap_info.chunksize;
- r = mddev->bitmap_ops->resize(mddev, mddev->dev_sectors,
- chunksize);
- if (r)
- DMERR("Failed to resize bitmap");
+ if (md_bitmap_enabled(mddev, false)) {
+ r = mddev->bitmap_ops->resize(mddev, mddev->dev_sectors,
+ chunksize);
+ if (r)
+ DMERR("Failed to resize bitmap");
+ }
}
/* Check for any resize/reshape on @rs and adjust/initiate */
--
2.39.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v5 14/15] md: check before referencing mddev->bitmap_ops
2025-07-07 1:26 [PATCH v5 00/15] md/md-bitmap: introduce CONFIG_MD_BITMAP Yu Kuai
` (12 preceding siblings ...)
2025-07-07 1:27 ` [PATCH v5 13/15] md/dm-raid: " Yu Kuai
@ 2025-07-07 1:27 ` Yu Kuai
2025-07-07 1:27 ` [PATCH v5 15/15] md/md-bitmap: introduce CONFIG_MD_BITMAP Yu Kuai
` (2 subsequent siblings)
16 siblings, 0 replies; 20+ messages in thread
From: Yu Kuai @ 2025-07-07 1:27 UTC (permalink / raw)
To: agk, snitzer, mpatocka, song, yukuai3
Cc: dm-devel, linux-raid, linux-kernel, yukuai1, yi.zhang, yangerkun,
johnny.chenyi
From: Yu Kuai <yukuai3@huawei.com>
Prepare to introduce CONFIG_MD_BITMAP.
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
---
drivers/md/md.c | 68 ++++++++++++++++++++++++++++++++++---------------
1 file changed, 48 insertions(+), 20 deletions(-)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 7ed95e5e43fc..2f7e8d77e7ef 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1346,6 +1346,9 @@ static u64 md_bitmap_events_cleared(struct mddev *mddev)
struct md_bitmap_stats stats;
int err;
+ if (!md_bitmap_enabled(mddev, false))
+ return 0;
+
err = mddev->bitmap_ops->get_stats(mddev->bitmap, &stats);
if (err)
return 0;
@@ -2303,13 +2306,15 @@ static int
super_1_allow_new_offset(struct md_rdev *rdev,
unsigned long long new_offset)
{
+ struct mddev *mddev = rdev->mddev;
+
/* All necessary checks on new >= old have been done */
if (new_offset >= rdev->data_offset)
return 1;
/* with 1.0 metadata, there is no metadata to tread on
* so we can always move back */
- if (rdev->mddev->minor_version == 0)
+ if (mddev->minor_version == 0)
return 1;
/* otherwise we must be sure not to step on
@@ -2321,8 +2326,7 @@ super_1_allow_new_offset(struct md_rdev *rdev,
if (rdev->sb_start + (32+4)*2 > new_offset)
return 0;
- if (!rdev->mddev->bitmap_info.file) {
- struct mddev *mddev = rdev->mddev;
+ if (md_bitmap_registered(mddev) && !mddev->bitmap_info.file) {
struct md_bitmap_stats stats;
int err;
@@ -2794,7 +2798,8 @@ void md_update_sb(struct mddev *mddev, int force_change)
mddev_add_trace_msg(mddev, "md md_update_sb");
rewrite:
- mddev->bitmap_ops->update_sb(mddev->bitmap);
+ if (md_bitmap_enabled(mddev, false))
+ mddev->bitmap_ops->update_sb(mddev->bitmap);
rdev_for_each(rdev, mddev) {
if (rdev->sb_loaded != 1)
continue; /* no noise on spare devices */
@@ -4670,6 +4675,9 @@ bitmap_store(struct mddev *mddev, const char *buf, size_t len)
unsigned long chunk, end_chunk;
int err;
+ if (!md_bitmap_enabled(mddev, false))
+ return len;
+
err = mddev_lock(mddev);
if (err)
return err;
@@ -5995,7 +6003,7 @@ struct mddev *md_alloc(dev_t dev, char *name)
return ERR_PTR(error);
}
- if (mddev->bitmap_ops && mddev->bitmap_ops->group)
+ if (md_bitmap_registered(mddev) && mddev->bitmap_ops->group)
if (sysfs_create_group(&mddev->kobj, mddev->bitmap_ops->group))
pr_warn("md: cannot register extra bitmap attributes for %s\n",
mdname(mddev));
@@ -6239,7 +6247,7 @@ int md_run(struct mddev *mddev)
(unsigned long long)pers->size(mddev, 0, 0) / 2);
err = -EINVAL;
}
- if (err == 0 && pers->sync_request &&
+ if (err == 0 && pers->sync_request && md_bitmap_registered(mddev) &&
(mddev->bitmap_info.file || mddev->bitmap_info.offset)) {
err = mddev->bitmap_ops->create(mddev);
if (err)
@@ -6314,7 +6322,8 @@ int md_run(struct mddev *mddev)
pers->free(mddev, mddev->private);
mddev->private = NULL;
put_pers(pers);
- mddev->bitmap_ops->destroy(mddev);
+ if (md_bitmap_registered(mddev))
+ mddev->bitmap_ops->destroy(mddev);
abort:
bioset_exit(&mddev->io_clone_set);
exit_sync_set:
@@ -6334,10 +6343,12 @@ int do_md_run(struct mddev *mddev)
if (err)
goto out;
- err = mddev->bitmap_ops->load(mddev);
- if (err) {
- mddev->bitmap_ops->destroy(mddev);
- goto out;
+ if (md_bitmap_registered(mddev)) {
+ err = mddev->bitmap_ops->load(mddev);
+ if (err) {
+ mddev->bitmap_ops->destroy(mddev);
+ goto out;
+ }
}
if (mddev_is_clustered(mddev))
@@ -6476,7 +6487,8 @@ static void __md_stop_writes(struct mddev *mddev)
mddev->pers->quiesce(mddev, 0);
}
- mddev->bitmap_ops->flush(mddev);
+ if (md_bitmap_enabled(mddev, true))
+ mddev->bitmap_ops->flush(mddev);
if (md_is_rdwr(mddev) &&
((!mddev->in_sync && !mddev_is_clustered(mddev)) ||
@@ -6503,7 +6515,8 @@ EXPORT_SYMBOL_GPL(md_stop_writes);
static void mddev_detach(struct mddev *mddev)
{
- mddev->bitmap_ops->wait_behind_writes(mddev);
+ if (md_bitmap_enabled(mddev, false))
+ mddev->bitmap_ops->wait_behind_writes(mddev);
if (mddev->pers && mddev->pers->quiesce && !is_md_suspended(mddev)) {
mddev->pers->quiesce(mddev, 1);
mddev->pers->quiesce(mddev, 0);
@@ -6519,7 +6532,8 @@ static void __md_stop(struct mddev *mddev)
{
struct md_personality *pers = mddev->pers;
- mddev->bitmap_ops->destroy(mddev);
+ if (md_bitmap_registered(mddev))
+ mddev->bitmap_ops->destroy(mddev);
mddev_detach(mddev);
spin_lock(&mddev->lock);
mddev->pers = NULL;
@@ -7236,6 +7250,9 @@ static int set_bitmap_file(struct mddev *mddev, int fd)
{
int err = 0;
+ if (!md_bitmap_registered(mddev))
+ return -EINVAL;
+
if (mddev->pers) {
if (!mddev->pers->quiesce || !mddev->thread)
return -EBUSY;
@@ -7586,6 +7603,14 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info)
rv = update_raid_disks(mddev, info->raid_disks);
if ((state ^ info->state) & (1<<MD_SB_BITMAP_PRESENT)) {
+ /*
+ * Metadata says bitmap existed, however kernel can't find
+ * registered bitmap.
+ */
+ if (WARN_ON_ONCE(!md_bitmap_registered(mddev))) {
+ rv = -EINVAL;
+ goto err;
+ }
if (mddev->pers->quiesce == NULL || mddev->thread == NULL) {
rv = -EINVAL;
goto err;
@@ -8420,6 +8445,9 @@ static void md_bitmap_status(struct seq_file *seq, struct mddev *mddev)
unsigned long chunk_kb;
int err;
+ if (!md_bitmap_enabled(mddev, false))
+ return;
+
err = mddev->bitmap_ops->get_stats(mddev->bitmap, &stats);
if (err)
return;
@@ -8822,7 +8850,7 @@ static void md_end_clone_io(struct bio *bio)
struct bio *orig_bio = md_io_clone->orig_bio;
struct mddev *mddev = md_io_clone->mddev;
- if (bio_data_dir(orig_bio) == WRITE && mddev->bitmap)
+ if (bio_data_dir(orig_bio) == WRITE && md_bitmap_enabled(mddev, false))
md_bitmap_end(mddev, md_io_clone);
if (bio->bi_status && !orig_bio->bi_status)
@@ -8849,7 +8877,7 @@ static void md_clone_bio(struct mddev *mddev, struct bio **bio)
if (blk_queue_io_stat(bdev->bd_disk->queue))
md_io_clone->start_time = bio_start_io_acct(*bio);
- if (bio_data_dir(*bio) == WRITE && mddev->bitmap) {
+ if (bio_data_dir(*bio) == WRITE && md_bitmap_enabled(mddev, false)) {
md_io_clone->offset = (*bio)->bi_iter.bi_sector;
md_io_clone->sectors = bio_sectors(*bio);
md_bitmap_start(mddev, md_io_clone);
@@ -8873,7 +8901,7 @@ void md_free_cloned_bio(struct bio *bio)
struct bio *orig_bio = md_io_clone->orig_bio;
struct mddev *mddev = md_io_clone->mddev;
- if (bio_data_dir(orig_bio) == WRITE && mddev->bitmap)
+ if (bio_data_dir(orig_bio) == WRITE && md_bitmap_enabled(mddev, false))
md_bitmap_end(mddev, md_io_clone);
if (bio->bi_status && !orig_bio->bi_status)
@@ -9598,7 +9626,7 @@ static void md_start_sync(struct work_struct *ws)
* We are adding a device or devices to an array which has the bitmap
* stored on all devices. So make sure all bitmap pages get written.
*/
- if (spares)
+ if (spares && md_bitmap_enabled(mddev, true))
mddev->bitmap_ops->write_all(mddev);
name = test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) ?
@@ -9686,7 +9714,7 @@ static void unregister_sync_thread(struct mddev *mddev)
*/
void md_check_recovery(struct mddev *mddev)
{
- if (mddev->bitmap)
+ if (md_bitmap_enabled(mddev, false))
mddev->bitmap_ops->daemon_work(mddev);
if (signal_pending(current)) {
@@ -10066,7 +10094,7 @@ static void check_sb_changes(struct mddev *mddev, struct md_rdev *rdev)
ret = mddev->pers->resize(mddev, le64_to_cpu(sb->size));
if (ret)
pr_info("md-cluster: resize failed\n");
- else
+ else if (md_bitmap_enabled(mddev, false))
mddev->bitmap_ops->update_sb(mddev->bitmap);
}
--
2.39.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v5 15/15] md/md-bitmap: introduce CONFIG_MD_BITMAP
2025-07-07 1:26 [PATCH v5 00/15] md/md-bitmap: introduce CONFIG_MD_BITMAP Yu Kuai
` (13 preceding siblings ...)
2025-07-07 1:27 ` [PATCH v5 14/15] md: " Yu Kuai
@ 2025-07-07 1:27 ` Yu Kuai
2025-07-28 5:37 ` [PATCH v5 00/15] " Xiao Ni
2025-07-30 18:21 ` Yu Kuai
16 siblings, 0 replies; 20+ messages in thread
From: Yu Kuai @ 2025-07-07 1:27 UTC (permalink / raw)
To: agk, snitzer, mpatocka, song, yukuai3
Cc: dm-devel, linux-raid, linux-kernel, yukuai1, yi.zhang, yangerkun,
johnny.chenyi
From: Yu Kuai <yukuai3@huawei.com>
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.
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
---
drivers/md/Kconfig | 18 ++++++++++++++++++
drivers/md/Makefile | 3 ++-
drivers/md/md-bitmap.c | 23 +++++++++++++++++++++--
drivers/md/md-bitmap.h | 17 +++++++++++++++--
drivers/md/md.c | 40 ++++++++++++++++++++++++++++------------
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 5bd75fa6ee1d..28dd66ab8df9 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);
@@ -2980,6 +2982,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,
@@ -3014,7 +3022,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 2f7e8d77e7ef..c2a90d8ec06d 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);
@@ -670,15 +669,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;
}
@@ -706,7 +724,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);
@@ -717,6 +734,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);
}
@@ -10038,8 +10056,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;
@@ -10048,11 +10070,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;
@@ -10071,12 +10088,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;
}
@@ -10379,8 +10395,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 d6fba4240f97..b7dc8253efd8 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);
--
2.39.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v5 03/15] md/md-bitmap: remove the parameter 'init' for bitmap_ops->resize()
2025-07-07 1:26 ` [PATCH v5 03/15] md/md-bitmap: remove the parameter 'init' for bitmap_ops->resize() Yu Kuai
@ 2025-07-25 2:49 ` Xiao Ni
0 siblings, 0 replies; 20+ messages in thread
From: Xiao Ni @ 2025-07-25 2:49 UTC (permalink / raw)
To: Yu Kuai
Cc: agk, snitzer, mpatocka, song, yukuai3, dm-devel, linux-raid,
linux-kernel, yi.zhang, yangerkun, johnny.chenyi
On Mon, Jul 7, 2025 at 9:36 AM Yu Kuai <yukuai1@huaweicloud.com> wrote:
>
> From: Yu Kuai <yukuai3@huawei.com>
>
> It's set to 'false' for all callers, hence it's useless and can be
> removed.
>
> Signed-off-by: Yu Kuai <yukuai3@huawei.com>
> ---
> drivers/md/dm-raid.c | 2 +-
> drivers/md/md-bitmap.c | 5 ++---
> drivers/md/md-bitmap.h | 3 +--
> drivers/md/md-cluster.c | 2 +-
> drivers/md/raid1.c | 2 +-
> drivers/md/raid10.c | 8 ++++----
> drivers/md/raid5.c | 2 +-
> 7 files changed, 11 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
> index d296770478b2..9757c32ea1f5 100644
> --- a/drivers/md/dm-raid.c
> +++ b/drivers/md/dm-raid.c
> @@ -4068,7 +4068,7 @@ static int raid_preresume(struct dm_target *ti)
> int chunksize = to_bytes(rs->requested_bitmap_chunk_sectors) ?: mddev->bitmap_info.chunksize;
>
> r = mddev->bitmap_ops->resize(mddev, mddev->dev_sectors,
> - chunksize, false);
> + chunksize);
> if (r)
> DMERR("Failed to resize bitmap");
> }
> diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
> index bd694910b01b..fc7282304b00 100644
> --- a/drivers/md/md-bitmap.c
> +++ b/drivers/md/md-bitmap.c
> @@ -2594,15 +2594,14 @@ static int __bitmap_resize(struct bitmap *bitmap, sector_t blocks,
> return ret;
> }
>
> -static int bitmap_resize(struct mddev *mddev, sector_t blocks, int chunksize,
> - bool init)
> +static int bitmap_resize(struct mddev *mddev, sector_t blocks, int chunksize)
> {
> struct bitmap *bitmap = mddev->bitmap;
>
> if (!bitmap)
> return 0;
>
> - return __bitmap_resize(bitmap, blocks, chunksize, init);
> + return __bitmap_resize(bitmap, blocks, chunksize, false);
> }
>
> static ssize_t
> diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h
> index 59e9dd45cfde..28c1f1c1cc83 100644
> --- a/drivers/md/md-bitmap.h
> +++ b/drivers/md/md-bitmap.h
> @@ -64,8 +64,7 @@ struct md_bitmap_stats {
> struct bitmap_operations {
> bool (*enabled)(struct mddev *mddev);
> int (*create)(struct mddev *mddev);
> - int (*resize)(struct mddev *mddev, sector_t blocks, int chunksize,
> - bool init);
> + int (*resize)(struct mddev *mddev, sector_t blocks, int chunksize);
>
> int (*load)(struct mddev *mddev);
> void (*destroy)(struct mddev *mddev);
> diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c
> index 94221d964d4f..db6bbc8eebbc 100644
> --- a/drivers/md/md-cluster.c
> +++ b/drivers/md/md-cluster.c
> @@ -630,7 +630,7 @@ static int process_recvd_msg(struct mddev *mddev, struct cluster_msg *msg)
> if (le64_to_cpu(msg->high) != mddev->pers->size(mddev, 0, 0))
> ret = mddev->bitmap_ops->resize(mddev,
> le64_to_cpu(msg->high),
> - 0, false);
> + 0);
> break;
> default:
> ret = -1;
> diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
> index 3a31e230727c..39ebe0fadacd 100644
> --- a/drivers/md/raid1.c
> +++ b/drivers/md/raid1.c
> @@ -3329,7 +3329,7 @@ static int raid1_resize(struct mddev *mddev, sector_t sectors)
> mddev->array_sectors > newsize)
> return -EINVAL;
>
> - ret = mddev->bitmap_ops->resize(mddev, newsize, 0, false);
> + ret = mddev->bitmap_ops->resize(mddev, newsize, 0);
> if (ret)
> return ret;
>
> diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
> index b74780af4c22..d2ef96be0150 100644
> --- a/drivers/md/raid10.c
> +++ b/drivers/md/raid10.c
> @@ -4233,7 +4233,7 @@ static int raid10_resize(struct mddev *mddev, sector_t sectors)
> mddev->array_sectors > size)
> return -EINVAL;
>
> - ret = mddev->bitmap_ops->resize(mddev, size, 0, false);
> + ret = mddev->bitmap_ops->resize(mddev, size, 0);
> if (ret)
> return ret;
>
> @@ -4502,7 +4502,7 @@ static int raid10_start_reshape(struct mddev *mddev)
> newsize = raid10_size(mddev, 0, conf->geo.raid_disks);
>
> if (!mddev_is_clustered(mddev)) {
> - ret = mddev->bitmap_ops->resize(mddev, newsize, 0, false);
> + ret = mddev->bitmap_ops->resize(mddev, newsize, 0);
> if (ret)
> goto abort;
> else
> @@ -4524,13 +4524,13 @@ static int raid10_start_reshape(struct mddev *mddev)
> MD_FEATURE_RESHAPE_ACTIVE)) || (oldsize == newsize))
> goto out;
>
> - ret = mddev->bitmap_ops->resize(mddev, newsize, 0, false);
> + ret = mddev->bitmap_ops->resize(mddev, newsize, 0);
> if (ret)
> goto abort;
>
> ret = mddev->cluster_ops->resize_bitmaps(mddev, newsize, oldsize);
> if (ret) {
> - mddev->bitmap_ops->resize(mddev, oldsize, 0, false);
> + mddev->bitmap_ops->resize(mddev, oldsize, 0);
> goto abort;
> }
> }
> diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
> index 7ec61ee7b218..999752ec636e 100644
> --- a/drivers/md/raid5.c
> +++ b/drivers/md/raid5.c
> @@ -8322,7 +8322,7 @@ static int raid5_resize(struct mddev *mddev, sector_t sectors)
> mddev->array_sectors > newsize)
> return -EINVAL;
>
> - ret = mddev->bitmap_ops->resize(mddev, sectors, 0, false);
> + ret = mddev->bitmap_ops->resize(mddev, sectors, 0);
> if (ret)
> return ret;
>
> --
> 2.39.2
>
>
Looks good to me.
Reviewed-by: Xiao Ni <xni@redhat.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v5 04/15] md/md-bitmap: merge md_bitmap_group into bitmap_operations
2025-07-07 1:27 ` [PATCH v5 04/15] md/md-bitmap: merge md_bitmap_group into bitmap_operations Yu Kuai
@ 2025-07-25 3:42 ` Xiao Ni
0 siblings, 0 replies; 20+ messages in thread
From: Xiao Ni @ 2025-07-25 3:42 UTC (permalink / raw)
To: Yu Kuai
Cc: agk, snitzer, mpatocka, song, yukuai3, dm-devel, linux-raid,
linux-kernel, yi.zhang, yangerkun, johnny.chenyi
On Mon, Jul 7, 2025 at 9:35 AM Yu Kuai <yukuai1@huaweicloud.com> wrote:
>
> From: Yu Kuai <yukuai3@huawei.com>
>
> Now that all bitmap implementations are internal, it doesn't make sense
> to export md_bitmap_group anymore.
>
> Signed-off-by: Yu Kuai <yukuai3@huawei.com>
> ---
> drivers/md/md-bitmap.c | 5 ++++-
> drivers/md/md-bitmap.h | 2 ++
> drivers/md/md.c | 6 +++++-
> drivers/md/md.h | 1 -
> 4 files changed, 11 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
> index fc7282304b00..0ba1da35aa84 100644
> --- a/drivers/md/md-bitmap.c
> +++ b/drivers/md/md-bitmap.c
> @@ -2990,7 +2990,8 @@ static struct attribute *md_bitmap_attrs[] = {
> &max_backlog_used.attr,
> NULL
> };
> -const struct attribute_group md_bitmap_group = {
> +
> +static struct attribute_group md_bitmap_group = {
> .name = "bitmap",
> .attrs = md_bitmap_attrs,
> };
> @@ -3026,6 +3027,8 @@ static struct bitmap_operations bitmap_ops = {
> .copy_from_slot = bitmap_copy_from_slot,
> .set_pages = bitmap_set_pages,
> .free = md_bitmap_free,
> +
> + .group = &md_bitmap_group,
> };
>
> void mddev_set_bitmap_ops(struct mddev *mddev)
> diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h
> index 28c1f1c1cc83..0ceb9e97d21f 100644
> --- a/drivers/md/md-bitmap.h
> +++ b/drivers/md/md-bitmap.h
> @@ -100,6 +100,8 @@ struct bitmap_operations {
> sector_t *hi, bool clear_bits);
> void (*set_pages)(void *data, unsigned long pages);
> void (*free)(void *data);
> +
> + struct attribute_group *group;
> };
>
> /* the bitmap API */
> diff --git a/drivers/md/md.c b/drivers/md/md.c
> index bda3ef814d97..7ed95e5e43fc 100644
> --- a/drivers/md/md.c
> +++ b/drivers/md/md.c
> @@ -5749,7 +5749,6 @@ static const struct attribute_group md_redundancy_group = {
>
> static const struct attribute_group *md_attr_groups[] = {
> &md_default_group,
> - &md_bitmap_group,
> NULL,
> };
>
> @@ -5996,6 +5995,11 @@ struct mddev *md_alloc(dev_t dev, char *name)
> return ERR_PTR(error);
> }
>
> + if (mddev->bitmap_ops && mddev->bitmap_ops->group)
> + if (sysfs_create_group(&mddev->kobj, mddev->bitmap_ops->group))
> + pr_warn("md: cannot register extra bitmap attributes for %s\n",
> + mdname(mddev));
> +
> kobject_uevent(&mddev->kobj, KOBJ_ADD);
> mddev->sysfs_state = sysfs_get_dirent_safe(mddev->kobj.sd, "array_state");
> mddev->sysfs_level = sysfs_get_dirent_safe(mddev->kobj.sd, "level");
> diff --git a/drivers/md/md.h b/drivers/md/md.h
> index 67b365621507..d6fba4240f97 100644
> --- a/drivers/md/md.h
> +++ b/drivers/md/md.h
> @@ -796,7 +796,6 @@ struct md_sysfs_entry {
> ssize_t (*show)(struct mddev *, char *);
> ssize_t (*store)(struct mddev *, const char *, size_t);
> };
> -extern const struct attribute_group md_bitmap_group;
>
> static inline struct kernfs_node *sysfs_get_dirent_safe(struct kernfs_node *sd, char *name)
> {
> --
> 2.39.2
>
>
Looks good to me.
Reviewed-by: Xiao Ni <xni@redhat.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v5 00/15] md/md-bitmap: introduce CONFIG_MD_BITMAP
2025-07-07 1:26 [PATCH v5 00/15] md/md-bitmap: introduce CONFIG_MD_BITMAP Yu Kuai
` (14 preceding siblings ...)
2025-07-07 1:27 ` [PATCH v5 15/15] md/md-bitmap: introduce CONFIG_MD_BITMAP Yu Kuai
@ 2025-07-28 5:37 ` Xiao Ni
2025-07-30 18:21 ` Yu Kuai
16 siblings, 0 replies; 20+ messages in thread
From: Xiao Ni @ 2025-07-28 5:37 UTC (permalink / raw)
To: Yu Kuai
Cc: agk, snitzer, mpatocka, song, yukuai3, dm-devel, linux-raid,
linux-kernel, yi.zhang, yangerkun, johnny.chenyi
On Mon, Jul 7, 2025 at 9:36 AM Yu Kuai <yukuai1@huaweicloud.com> wrote:
>
> From: Yu Kuai <yukuai3@huawei.com>
>
> Changes in v5:
> - rebase on the top of md-6.17;
> - fix compile problem if md-mod is build as module;
> - fix two problems for lvm2 dm-raid tests, patch 5,13
> - other cleanups;
> Changes in v4:
> - rebase on the top of other patchset;
> Changes in v3:
> - update commit message.
> Changes in v2:
> - don't export apis, and don't support build md-bitmap as module
>
> Due to known performance issues with md-bitmap and the unreasonable
> implementations like following:
>
> - self-managed pages, bitmap_storage->filemap;
> - self-managed IO submitting like filemap_write_page();
> - global spin_lock
> ...
>
> I have decided not to continue optimizing based on the current bitmap
> implementation, and plan to invent a new lock-less bitmap. And a new
> kconfig option is a good way for isolation.
>
> However, we still encourage anyone who wants to continue optimizing the
> current implementation
>
> Yu Kuai (15):
> md/raid1: change r1conf->r1bio_pool to a pointer type
> md/raid1: remove struct pool_info and related code
> md/md-bitmap: remove the parameter 'init' for bitmap_ops->resize()
> md/md-bitmap: merge md_bitmap_group into bitmap_operations
> md/md-bitmap: add a new parameter 'flush' to bitmap_ops->enabled
> md/md-bitmap: add md_bitmap_registered/enabled() helper
> md/md-bitmap: handle the case bitmap is not enabled before
> start_sync()
> md/md-bitmap: handle the case bitmap is not enabled before end_sync()
> md/raid1: check bitmap before behind write
> md/raid1: check before referencing mddev->bitmap_ops
> md/raid10: check before referencing mddev->bitmap_ops
> md/raid5: check before referencing mddev->bitmap_ops
> md/dm-raid: check before referencing mddev->bitmap_ops
> md: check before referencing mddev->bitmap_ops
> md/md-bitmap: introduce CONFIG_MD_BITMAP
>
> drivers/md/Kconfig | 18 +++++
> drivers/md/Makefile | 3 +-
> drivers/md/dm-raid.c | 18 +++--
> drivers/md/md-bitmap.c | 74 +++++++++---------
> drivers/md/md-bitmap.h | 62 ++++++++++++++-
> drivers/md/md-cluster.c | 2 +-
> drivers/md/md.c | 112 +++++++++++++++++++--------
> drivers/md/md.h | 4 +-
> drivers/md/raid1-10.c | 2 +-
> drivers/md/raid1.c | 163 +++++++++++++++++++---------------------
> drivers/md/raid1.h | 22 +-----
> drivers/md/raid10.c | 49 ++++++------
> drivers/md/raid5.c | 30 ++++----
> 13 files changed, 330 insertions(+), 229 deletions(-)
>
> --
> 2.39.2
>
>
The patch set looks good to me.
Reviewed-by: Xiao Ni <xni@redhat.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v5 00/15] md/md-bitmap: introduce CONFIG_MD_BITMAP
2025-07-07 1:26 [PATCH v5 00/15] md/md-bitmap: introduce CONFIG_MD_BITMAP Yu Kuai
` (15 preceding siblings ...)
2025-07-28 5:37 ` [PATCH v5 00/15] " Xiao Ni
@ 2025-07-30 18:21 ` Yu Kuai
16 siblings, 0 replies; 20+ messages in thread
From: Yu Kuai @ 2025-07-30 18:21 UTC (permalink / raw)
To: Yu Kuai, agk, snitzer, mpatocka, song, yukuai3
Cc: dm-devel, linux-raid, linux-kernel, yi.zhang, yangerkun,
johnny.chenyi
在 2025/7/7 9:26, Yu Kuai 写道:
> From: Yu Kuai <yukuai3@huawei.com>
>
> Changes in v5:
> - rebase on the top of md-6.17;
> - fix compile problem if md-mod is build as module;
> - fix two problems for lvm2 dm-raid tests, patch 5,13
> - other cleanups;
> Changes in v4:
> - rebase on the top of other patchset;
> Changes in v3:
> - update commit message.
> Changes in v2:
> - don't export apis, and don't support build md-bitmap as module
>
> Due to known performance issues with md-bitmap and the unreasonable
> implementations like following:
>
> - self-managed pages, bitmap_storage->filemap;
> - self-managed IO submitting like filemap_write_page();
> - global spin_lock
> ...
>
> I have decided not to continue optimizing based on the current bitmap
> implementation, and plan to invent a new lock-less bitmap. And a new
> kconfig option is a good way for isolation.
>
> However, we still encourage anyone who wants to continue optimizing the
> current implementation
>
> Yu Kuai (15):
> md/raid1: change r1conf->r1bio_pool to a pointer type
> md/raid1: remove struct pool_info and related code
> md/md-bitmap: remove the parameter 'init' for bitmap_ops->resize()
> md/md-bitmap: merge md_bitmap_group into bitmap_operations
> md/md-bitmap: add a new parameter 'flush' to bitmap_ops->enabled
> md/md-bitmap: add md_bitmap_registered/enabled() helper
> md/md-bitmap: handle the case bitmap is not enabled before
> start_sync()
> md/md-bitmap: handle the case bitmap is not enabled before end_sync()
> md/raid1: check bitmap before behind write
> md/raid1: check before referencing mddev->bitmap_ops
> md/raid10: check before referencing mddev->bitmap_ops
> md/raid5: check before referencing mddev->bitmap_ops
> md/dm-raid: check before referencing mddev->bitmap_ops
> md: check before referencing mddev->bitmap_ops
> md/md-bitmap: introduce CONFIG_MD_BITMAP
>
> drivers/md/Kconfig | 18 +++++
> drivers/md/Makefile | 3 +-
> drivers/md/dm-raid.c | 18 +++--
> drivers/md/md-bitmap.c | 74 +++++++++---------
> drivers/md/md-bitmap.h | 62 ++++++++++++++-
> drivers/md/md-cluster.c | 2 +-
> drivers/md/md.c | 112 +++++++++++++++++++--------
> drivers/md/md.h | 4 +-
> drivers/md/raid1-10.c | 2 +-
> drivers/md/raid1.c | 163 +++++++++++++++++++---------------------
> drivers/md/raid1.h | 22 +-----
> drivers/md/raid10.c | 49 ++++++------
> drivers/md/raid5.c | 30 ++++----
> 13 files changed, 330 insertions(+), 229 deletions(-)
>
Applied to md-6.17
Thanks
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2025-07-30 18:21 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-07 1:26 [PATCH v5 00/15] md/md-bitmap: introduce CONFIG_MD_BITMAP Yu Kuai
2025-07-07 1:26 ` [PATCH v5 01/15] md/raid1: change r1conf->r1bio_pool to a pointer type Yu Kuai
2025-07-07 1:26 ` [PATCH v5 02/15] md/raid1: remove struct pool_info and related code Yu Kuai
2025-07-07 1:26 ` [PATCH v5 03/15] md/md-bitmap: remove the parameter 'init' for bitmap_ops->resize() Yu Kuai
2025-07-25 2:49 ` Xiao Ni
2025-07-07 1:27 ` [PATCH v5 04/15] md/md-bitmap: merge md_bitmap_group into bitmap_operations Yu Kuai
2025-07-25 3:42 ` Xiao Ni
2025-07-07 1:27 ` [PATCH v5 05/15] md/md-bitmap: add a new parameter 'flush' to bitmap_ops->enabled Yu Kuai
2025-07-07 1:27 ` [PATCH v5 06/15] md/md-bitmap: add md_bitmap_registered/enabled() helper Yu Kuai
2025-07-07 1:27 ` [PATCH v5 07/15] md/md-bitmap: handle the case bitmap is not enabled before start_sync() Yu Kuai
2025-07-07 1:27 ` [PATCH v5 08/15] md/md-bitmap: handle the case bitmap is not enabled before end_sync() Yu Kuai
2025-07-07 1:27 ` [PATCH v5 09/15] md/raid1: check bitmap before behind write Yu Kuai
2025-07-07 1:27 ` [PATCH v5 10/15] md/raid1: check before referencing mddev->bitmap_ops Yu Kuai
2025-07-07 1:27 ` [PATCH v5 11/15] md/raid10: " Yu Kuai
2025-07-07 1:27 ` [PATCH v5 12/15] md/raid5: " Yu Kuai
2025-07-07 1:27 ` [PATCH v5 13/15] md/dm-raid: " Yu Kuai
2025-07-07 1:27 ` [PATCH v5 14/15] md: " Yu Kuai
2025-07-07 1:27 ` [PATCH v5 15/15] md/md-bitmap: introduce CONFIG_MD_BITMAP Yu Kuai
2025-07-28 5:37 ` [PATCH v5 00/15] " Xiao Ni
2025-07-30 18:21 ` Yu Kuai
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).