From 2db4fa1b7e1897908d5cd11b1e22233ff0c6ba49 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:11 +0800 Subject: [PATCH 01/42] md/raid1: use md_bitmap_wait_behind_writes() in raid1_read_request() Use the existed helper instead of open coding it to make the code cleaner. There are no functional changes, and also avoid dereferencing bitmap directly to prepare inventing a new bitmap. Noted that this patch also export md_bitmap_wait_behind_writes(), which is necessary for now, and the exported api will be removed in following patches to convert bitmap apis into ops. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-2-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 1 + drivers/md/raid1.c | 7 ++----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 08232d8dc815e..08743dcc70f1f 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -1851,6 +1851,7 @@ void md_bitmap_wait_behind_writes(struct mddev *mddev) atomic_read(&bitmap->behind_writes) == 0); } } +EXPORT_SYMBOL_GPL(md_bitmap_wait_behind_writes); void md_bitmap_destroy(struct mddev *mddev) { diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 531ddfc6efbdd..18aaa7247bba8 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1311,7 +1311,6 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio, struct r1conf *conf = mddev->private; struct raid1_info *mirror; struct bio *read_bio; - struct bitmap *bitmap = mddev->bitmap; const enum req_op op = bio_op(bio); const blk_opf_t do_sync = bio->bi_opf & REQ_SYNC; int max_sectors; @@ -1364,15 +1363,13 @@ 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) && - bitmap) { + if (test_bit(WriteMostly, &mirror->rdev->flags)) { /* * Reading from a write-mostly device must take care not to * over-take any writes that are 'behind' */ mddev_add_trace_msg(mddev, "raid1 wait behind writes"); - wait_event(bitmap->behind_wait, - atomic_read(&bitmap->behind_writes) == 0); + md_bitmap_wait_behind_writes(mddev); } if (max_sectors < bio_sectors(bio)) { From 38f287d7e495ae00d4481702f44ff7ca79f5c9bc Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:12 +0800 Subject: [PATCH 02/42] md/md-bitmap: replace md_bitmap_status() with a new helper md_bitmap_get_stats() There are no functional changes, and the new helper will be used in multiple places in following patches to avoid dereferencing bitmap directly. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-3-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 25 ++++++------------------- drivers/md/md-bitmap.h | 8 +++++++- drivers/md/md.c | 29 ++++++++++++++++++++++++++++- 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 08743dcc70f1f..66ebe12d80ae5 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -2094,32 +2094,19 @@ int md_bitmap_copy_from_slot(struct mddev *mddev, int slot, } EXPORT_SYMBOL_GPL(md_bitmap_copy_from_slot); - -void md_bitmap_status(struct seq_file *seq, struct bitmap *bitmap) +int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats) { - unsigned long chunk_kb; struct bitmap_counts *counts; if (!bitmap) - return; + return -ENOENT; counts = &bitmap->counts; + stats->missing_pages = counts->missing_pages; + stats->pages = counts->pages; + stats->file = bitmap->storage.file; - chunk_kb = bitmap->mddev->bitmap_info.chunksize >> 10; - seq_printf(seq, "bitmap: %lu/%lu pages [%luKB], " - "%lu%s chunk", - counts->pages - counts->missing_pages, - counts->pages, - (counts->pages - counts->missing_pages) - << (PAGE_SHIFT - 10), - chunk_kb ? chunk_kb : bitmap->mddev->bitmap_info.chunksize, - chunk_kb ? "KB" : "B"); - if (bitmap->storage.file) { - seq_printf(seq, ", file: "); - seq_file_path(seq, bitmap->storage.file, " \t\n"); - } - - seq_printf(seq, "\n"); + return 0; } int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks, diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index bb9eb418780a6..b60418e3f5737 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -234,6 +234,12 @@ struct bitmap { int cluster_slot; /* Slot offset for clustered env */ }; +struct md_bitmap_stats { + unsigned long missing_pages; + unsigned long pages; + struct file *file; +}; + /* the bitmap API */ /* these are used only by md/bitmap */ @@ -244,7 +250,7 @@ void md_bitmap_destroy(struct mddev *mddev); void md_bitmap_print_sb(struct bitmap *bitmap); void md_bitmap_update_sb(struct bitmap *bitmap); -void md_bitmap_status(struct seq_file *seq, struct bitmap *bitmap); +int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats); int md_bitmap_setallbits(struct bitmap *bitmap); void md_bitmap_write_all(struct bitmap *bitmap); diff --git a/drivers/md/md.c b/drivers/md/md.c index 23cc77d516763..22731d2717ba3 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -8370,6 +8370,33 @@ static void md_seq_stop(struct seq_file *seq, void *v) spin_unlock(&all_mddevs_lock); } +static void md_bitmap_status(struct seq_file *seq, struct mddev *mddev) +{ + struct md_bitmap_stats stats; + unsigned long used_pages; + unsigned long chunk_kb; + int err; + + err = md_bitmap_get_stats(mddev->bitmap, &stats); + if (err) + return; + + chunk_kb = mddev->bitmap_info.chunksize >> 10; + used_pages = stats.pages - stats.missing_pages; + + seq_printf(seq, "bitmap: %lu/%lu pages [%luKB], %lu%s chunk", + used_pages, stats.pages, used_pages << (PAGE_SHIFT - 10), + chunk_kb ? chunk_kb : mddev->bitmap_info.chunksize, + chunk_kb ? "KB" : "B"); + + if (stats.file) { + seq_puts(seq, ", file: "); + seq_file_path(seq, stats.file, " \t\n"); + } + + seq_putc(seq, '\n'); +} + static int md_seq_show(struct seq_file *seq, void *v) { struct mddev *mddev; @@ -8453,7 +8480,7 @@ static int md_seq_show(struct seq_file *seq, void *v) } else seq_printf(seq, "\n "); - md_bitmap_status(seq, mddev->bitmap); + md_bitmap_status(seq, mddev); seq_printf(seq, "\n"); } From 968153812215d68c27c0c9d90da6ec2f6d17a606 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:13 +0800 Subject: [PATCH 03/42] md: use new helper md_bitmap_get_stats() in update_array_info() There are no functional changes, avoid dereferencing bitmap directly to prepare inventing a new bitmap. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-4-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 22731d2717ba3..0cca8d3acfe30 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -7577,15 +7577,17 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info) if (rv) md_bitmap_destroy(mddev); } else { - /* remove the bitmap */ - if (!mddev->bitmap) { - rv = -ENOENT; + struct md_bitmap_stats stats; + + rv = md_bitmap_get_stats(mddev->bitmap, &stats); + if (rv) goto err; - } - if (mddev->bitmap->storage.file) { + + if (stats.file) { rv = -EINVAL; goto err; } + if (mddev->bitmap_info.nodes) { /* hold PW on all the bitmap lock */ if (md_cluster_ops->lock_all_bitmaps(mddev) <= 0) { From d004442f46ccae9ea90fdda7a2b0516f1d42b88e Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:14 +0800 Subject: [PATCH 04/42] md/md-bitmap: add 'events_cleared' into struct md_bitmap_stats Also add a new helper to get events_cleared to avoid dereferencing bitmap directly to prepare inventing a new bitmap. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-5-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 2 ++ drivers/md/md-bitmap.h | 1 + drivers/md/md.c | 16 ++++++++++++++-- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 66ebe12d80ae5..95afc22bd2557 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -2104,6 +2104,8 @@ int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats) counts = &bitmap->counts; stats->missing_pages = counts->missing_pages; stats->pages = counts->pages; + + stats->events_cleared = bitmap->events_cleared; stats->file = bitmap->storage.file; return 0; diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index b60418e3f5737..751dca2366c35 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -235,6 +235,7 @@ struct bitmap { }; struct md_bitmap_stats { + u64 events_cleared; unsigned long missing_pages; unsigned long pages; struct file *file; diff --git a/drivers/md/md.c b/drivers/md/md.c index 0cca8d3acfe30..cde6663c7fcb8 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1372,6 +1372,18 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor return ret; } +static u64 md_bitmap_events_cleared(struct mddev *mddev) +{ + struct md_bitmap_stats stats; + int err; + + err = md_bitmap_get_stats(mddev->bitmap, &stats); + if (err) + return 0; + + return stats.events_cleared; +} + /* * validate_super for 0.90.0 * note: we are not using "freshest" for 0.9 superblock @@ -1464,7 +1476,7 @@ static int super_90_validate(struct mddev *mddev, struct md_rdev *freshest, stru /* if adding to array with a bitmap, then we can accept an * older device ... but not too old. */ - if (ev1 < mddev->bitmap->events_cleared) + if (ev1 < md_bitmap_events_cleared(mddev)) return 0; if (ev1 < mddev->events) set_bit(Bitmap_sync, &rdev->flags); @@ -1991,7 +2003,7 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *freshest, struc /* If adding to array with a bitmap, then we can accept an * older device, but not too old. */ - if (ev1 < mddev->bitmap->events_cleared) + if (ev1 < md_bitmap_events_cleared(mddev)) return 0; if (ev1 < mddev->events) set_bit(Bitmap_sync, &rdev->flags); From 82697ccf7e495c1ba81e315c2886d6220ff84c2c Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:15 +0800 Subject: [PATCH 05/42] md/md-cluster: fix spares warnings for __le64 drivers/md/md-cluster.c:1220:22: warning: incorrect type in assignment (different base types) drivers/md/md-cluster.c:1220:22: expected unsigned long my_sync_size drivers/md/md-cluster.c:1220:22: got restricted __le64 [usertype] sync_size drivers/md/md-cluster.c:1252:35: warning: incorrect type in assignment (different base types) drivers/md/md-cluster.c:1252:35: expected unsigned long sync_size drivers/md/md-cluster.c:1252:35: got restricted __le64 [usertype] sync_size drivers/md/md-cluster.c:1253:41: warning: restricted __le64 degrades to integer Fix the warnings by using le64_to_cpu() to convet __le64 to integer. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-6-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-cluster.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index 1d0db62f03514..e642361b6526f 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -1217,7 +1217,7 @@ static int cluster_check_sync_size(struct mddev *mddev) struct dlm_lock_resource *bm_lockres; sb = kmap_atomic(bitmap->storage.sb_page); - my_sync_size = sb->sync_size; + my_sync_size = le64_to_cpu(sb->sync_size); kunmap_atomic(sb); for (i = 0; i < node_num; i++) { @@ -1249,8 +1249,8 @@ static int cluster_check_sync_size(struct mddev *mddev) sb = kmap_atomic(bitmap->storage.sb_page); if (sync_size == 0) - sync_size = sb->sync_size; - else if (sync_size != sb->sync_size) { + sync_size = le64_to_cpu(sb->sync_size); + else if (sync_size != le64_to_cpu(sb->sync_size)) { kunmap_atomic(sb); md_bitmap_free(bitmap); return -1; From ec6bb299c7c3dd4ca1724d13d5f5fae3ee54fc65 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:16 +0800 Subject: [PATCH 06/42] md/md-bitmap: add 'sync_size' into struct md_bitmap_stats To avoid dereferencing bitmap directly in md-cluster to prepare inventing a new bitmap. BTW, also fix following checkpatch warnings: WARNING: Deprecated use of 'kmap_atomic', prefer 'kmap_local_page' instead WARNING: Deprecated use of 'kunmap_atomic', prefer 'kunmap_local' instead Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-7-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 6 ++++++ drivers/md/md-bitmap.h | 1 + drivers/md/md-cluster.c | 34 ++++++++++++++++++++-------------- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 95afc22bd2557..33812543d984c 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -2097,10 +2097,15 @@ EXPORT_SYMBOL_GPL(md_bitmap_copy_from_slot); int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats) { struct bitmap_counts *counts; + bitmap_super_t *sb; if (!bitmap) return -ENOENT; + sb = kmap_local_page(bitmap->storage.sb_page); + stats->sync_size = le64_to_cpu(sb->sync_size); + kunmap_local(sb); + counts = &bitmap->counts; stats->missing_pages = counts->missing_pages; stats->pages = counts->pages; @@ -2110,6 +2115,7 @@ int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats) return 0; } +EXPORT_SYMBOL_GPL(md_bitmap_get_stats); int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks, int chunksize, int init) diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index 751dca2366c35..a43a755757691 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -237,6 +237,7 @@ struct bitmap { struct md_bitmap_stats { u64 events_cleared; unsigned long missing_pages; + unsigned long sync_size; unsigned long pages; struct file *file; }; diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index e642361b6526f..e3faf752f0b1f 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -1207,18 +1207,21 @@ static int resize_bitmaps(struct mddev *mddev, sector_t newsize, sector_t oldsiz */ static int cluster_check_sync_size(struct mddev *mddev) { - int i, rv; - bitmap_super_t *sb; - unsigned long my_sync_size, sync_size = 0; - int node_num = mddev->bitmap_info.nodes; int current_slot = md_cluster_ops->slot_number(mddev); + int node_num = mddev->bitmap_info.nodes; struct bitmap *bitmap = mddev->bitmap; - char str[64]; struct dlm_lock_resource *bm_lockres; + struct md_bitmap_stats stats; + unsigned long sync_size = 0; + unsigned long my_sync_size; + char str[64]; + int i, rv; - sb = kmap_atomic(bitmap->storage.sb_page); - my_sync_size = le64_to_cpu(sb->sync_size); - kunmap_atomic(sb); + rv = md_bitmap_get_stats(bitmap, &stats); + if (rv) + return rv; + + my_sync_size = stats.sync_size; for (i = 0; i < node_num; i++) { if (i == current_slot) @@ -1247,15 +1250,18 @@ static int cluster_check_sync_size(struct mddev *mddev) md_bitmap_update_sb(bitmap); lockres_free(bm_lockres); - sb = kmap_atomic(bitmap->storage.sb_page); - if (sync_size == 0) - sync_size = le64_to_cpu(sb->sync_size); - else if (sync_size != le64_to_cpu(sb->sync_size)) { - kunmap_atomic(sb); + rv = md_bitmap_get_stats(bitmap, &stats); + if (rv) { + md_bitmap_free(bitmap); + return rv; + } + + if (sync_size == 0) { + sync_size = stats.sync_size; + } else if (sync_size != stats.sync_size) { md_bitmap_free(bitmap); return -1; } - kunmap_atomic(sb); md_bitmap_free(bitmap); } From 10bc2ac10597ebc0b25afbc72fa4284565548e36 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:17 +0800 Subject: [PATCH 07/42] md/md-bitmap: add 'file_pages' into struct md_bitmap_stats There are no functional changes, avoid dereferencing bitmap directly to prepare inventing a new bitmap. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-8-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 7 +++++-- drivers/md/md-bitmap.h | 1 + drivers/md/md.c | 17 +++++++++++------ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 33812543d984c..ba83b99d61857 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -2096,6 +2096,7 @@ EXPORT_SYMBOL_GPL(md_bitmap_copy_from_slot); int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats) { + struct bitmap_storage *storage; struct bitmap_counts *counts; bitmap_super_t *sb; @@ -2110,9 +2111,11 @@ int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats) stats->missing_pages = counts->missing_pages; stats->pages = counts->pages; - stats->events_cleared = bitmap->events_cleared; - stats->file = bitmap->storage.file; + storage = &bitmap->storage; + stats->file_pages = storage->file_pages; + stats->file = storage->file; + stats->events_cleared = bitmap->events_cleared; return 0; } EXPORT_SYMBOL_GPL(md_bitmap_get_stats); diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index a43a755757691..8701256700879 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -237,6 +237,7 @@ struct bitmap { struct md_bitmap_stats { u64 events_cleared; unsigned long missing_pages; + unsigned long file_pages; unsigned long sync_size; unsigned long pages; struct file *file; diff --git a/drivers/md/md.c b/drivers/md/md.c index cde6663c7fcb8..06c0918111e32 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2335,7 +2335,6 @@ super_1_allow_new_offset(struct md_rdev *rdev, unsigned long long new_offset) { /* All necessary checks on new >= old have been done */ - struct bitmap *bitmap; if (new_offset >= rdev->data_offset) return 1; @@ -2352,11 +2351,17 @@ super_1_allow_new_offset(struct md_rdev *rdev, */ if (rdev->sb_start + (32+4)*2 > new_offset) return 0; - bitmap = rdev->mddev->bitmap; - if (bitmap && !rdev->mddev->bitmap_info.file && - rdev->sb_start + rdev->mddev->bitmap_info.offset + - bitmap->storage.file_pages * (PAGE_SIZE>>9) > new_offset) - return 0; + + if (!rdev->mddev->bitmap_info.file) { + struct md_bitmap_stats stats; + int err; + + err = md_bitmap_get_stats(rdev->mddev->bitmap, &stats); + if (!err && rdev->sb_start + rdev->mddev->bitmap_info.offset + + stats.file_pages * (PAGE_SIZE >> 9) > new_offset) + return 0; + } + if (rdev->badblocks.sector + rdev->badblocks.size > new_offset) return 0; From a0e7744a460ba5ca91f8d6fc4a696ee345b5baa9 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:18 +0800 Subject: [PATCH 08/42] md/md-bitmap: add 'behind_writes' and 'behind_wait' into struct md_bitmap_stats There are no functional changes, avoid dereferencing bitmap directly to prepare inventing a new bitmap. Also fix following checkpatch warning by using wq_has_sleeper(). WARNING: waitqueue_active without comment Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-9-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 2 ++ drivers/md/md-bitmap.h | 3 +++ drivers/md/raid1.c | 13 ++++++++----- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index ba83b99d61857..918510f36e33c 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -2115,6 +2115,8 @@ int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats) stats->file_pages = storage->file_pages; stats->file = storage->file; + stats->behind_writes = atomic_read(&bitmap->behind_writes); + stats->behind_wait = wq_has_sleeper(&bitmap->behind_wait); stats->events_cleared = bitmap->events_cleared; return 0; } diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index 8701256700879..909a661383c69 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -236,6 +236,9 @@ struct bitmap { struct md_bitmap_stats { u64 events_cleared; + int behind_writes; + bool behind_wait; + unsigned long missing_pages; unsigned long file_pages; unsigned long sync_size; diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 18aaa7247bba8..b6c4e44f9b4ba 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1590,16 +1590,19 @@ 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 */ - if (bitmap && write_behind && - (atomic_read(&bitmap->behind_writes) - < mddev->bitmap_info.max_write_behind) && - !waitqueue_active(&bitmap->behind_wait)) { + err = md_bitmap_get_stats(bitmap, &stats); + if (!err && write_behind && !stats.behind_wait && + stats.behind_writes < max_write_behind) alloc_behind_master_bio(r1_bio, bio); - } md_bitmap_startwrite(bitmap, r1_bio->sector, r1_bio->sectors, test_bit(R1BIO_BehindIO, &r1_bio->state)); From 9e4481ce0e55b4ef9795845d8b6770e3f6f4b24d Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:19 +0800 Subject: [PATCH 09/42] md/md-cluster: use helper md_bitmap_get_stats() to get pages in resize_bitmaps() Use the existed helper instead of open coding it, avoid dereferencing bitmap directly to prepare inventing a new bitmap. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-10-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-cluster.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index e3faf752f0b1f..76febdc5d7f66 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -1143,13 +1143,16 @@ static int update_bitmap_size(struct mddev *mddev, sector_t size) static int resize_bitmaps(struct mddev *mddev, sector_t newsize, sector_t oldsize) { - struct bitmap_counts *counts; - char str[64]; - struct dlm_lock_resource *bm_lockres; struct bitmap *bitmap = mddev->bitmap; - unsigned long my_pages = bitmap->counts.pages; + struct md_bitmap_stats stats; + unsigned long my_pages; int i, rv; + rv = md_bitmap_get_stats(bitmap, &stats); + if (rv) + return rv; + + my_pages = stats.pages; /* * We need to ensure all the nodes can grow to a larger * bitmap size before make the reshaping. @@ -1159,6 +1162,10 @@ static int resize_bitmaps(struct mddev *mddev, sector_t newsize, sector_t oldsiz return rv; for (i = 0; i < mddev->bitmap_info.nodes; i++) { + struct dlm_lock_resource *bm_lockres; + struct bitmap_counts *counts; + char str[64]; + if (i == md_cluster_ops->slot_number(mddev)) continue; @@ -1170,6 +1177,9 @@ static int resize_bitmaps(struct mddev *mddev, sector_t newsize, sector_t oldsiz } counts = &bitmap->counts; + rv = md_bitmap_get_stats(bitmap, &stats); + if (rv) + goto out; /* * If we can hold the bitmap lock of one node then * the slot is not occupied, update the pages. @@ -1186,7 +1196,7 @@ static int resize_bitmaps(struct mddev *mddev, sector_t newsize, sector_t oldsiz counts->pages = my_pages; lockres_free(bm_lockres); - if (my_pages != counts->pages) + if (my_pages != stats.pages) /* * Let's revert the bitmap size if one node * can't resize bitmap From 27832ad3f7f0f5080d472fa8621ff92166ca9fac Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:20 +0800 Subject: [PATCH 10/42] md/md-bitmap: add a new helper md_bitmap_set_pages() Currently md-cluster will set bitmap->counts.pages directly, add a helper to do this to avoid dereferencing bitmap directly. Noted that after this patch bitmap is not dereferenced directly anymore and following patches will move the structure inside md-bitmap.c. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-11-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 6 ++++++ drivers/md/md-bitmap.h | 1 + drivers/md/md-cluster.c | 4 +--- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 918510f36e33c..015997b4b8352 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -2094,6 +2094,12 @@ int md_bitmap_copy_from_slot(struct mddev *mddev, int slot, } EXPORT_SYMBOL_GPL(md_bitmap_copy_from_slot); +void md_bitmap_set_pages(struct bitmap *bitmap, unsigned long pages) +{ + bitmap->counts.pages = pages; +} +EXPORT_SYMBOL_GPL(md_bitmap_set_pages); + int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats) { struct bitmap_storage *storage; diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index 909a661383c69..c4d64311c0e81 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -285,6 +285,7 @@ int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks, struct bitmap *get_bitmap_from_slot(struct mddev *mddev, int slot); int md_bitmap_copy_from_slot(struct mddev *mddev, int slot, sector_t *lo, sector_t *hi, bool clear_bits); +void md_bitmap_set_pages(struct bitmap *bitmap, unsigned long pages); void md_bitmap_free(struct bitmap *bitmap); void md_bitmap_wait_behind_writes(struct mddev *mddev); diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index 76febdc5d7f66..59f7fbca783bc 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -1163,7 +1163,6 @@ static int resize_bitmaps(struct mddev *mddev, sector_t newsize, sector_t oldsiz for (i = 0; i < mddev->bitmap_info.nodes; i++) { struct dlm_lock_resource *bm_lockres; - struct bitmap_counts *counts; char str[64]; if (i == md_cluster_ops->slot_number(mddev)) @@ -1175,7 +1174,6 @@ static int resize_bitmaps(struct mddev *mddev, sector_t newsize, sector_t oldsiz bitmap = NULL; goto out; } - counts = &bitmap->counts; rv = md_bitmap_get_stats(bitmap, &stats); if (rv) @@ -1193,7 +1191,7 @@ static int resize_bitmaps(struct mddev *mddev, sector_t newsize, sector_t oldsiz bm_lockres->flags |= DLM_LKF_NOQUEUE; rv = dlm_lock_sync(bm_lockres, DLM_LOCK_PW); if (!rv) - counts->pages = my_pages; + md_bitmap_set_pages(bitmap, my_pages); lockres_free(bm_lockres); if (my_pages != stats.pages) From 7add9db6ba3e9bd12d2be97abbc13f3881a515db Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:21 +0800 Subject: [PATCH 11/42] md/md-bitmap: introduce struct bitmap_operations The structure is empty for now, and will be used in later patches to merge in bitmap operations, so that bitmap implementation won't be exposed. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-12-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 8 ++++++++ drivers/md/md-bitmap.h | 4 ++++ drivers/md/md.c | 1 + drivers/md/md.h | 1 + 4 files changed, 14 insertions(+) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 015997b4b8352..69d9c959fe49a 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -2714,3 +2714,11 @@ const struct attribute_group md_bitmap_group = { .name = "bitmap", .attrs = md_bitmap_attrs, }; + +static struct bitmap_operations bitmap_ops = { +}; + +void mddev_set_bitmap_ops(struct mddev *mddev) +{ + mddev->bitmap_ops = &bitmap_ops; +} diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index c4d64311c0e81..14c21ab42f9ed 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -246,7 +246,11 @@ struct md_bitmap_stats { struct file *file; }; +struct bitmap_operations { +}; + /* the bitmap API */ +void mddev_set_bitmap_ops(struct mddev *mddev); /* these are used only by md/bitmap */ struct bitmap *md_bitmap_create(struct mddev *mddev, int slot); diff --git a/drivers/md/md.c b/drivers/md/md.c index 06c0918111e32..f86e6911318f9 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -772,6 +772,7 @@ 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); diff --git a/drivers/md/md.h b/drivers/md/md.h index a0d6827dced9b..e56193f71ab4e 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -536,6 +536,7 @@ struct mddev { int sync_checkers; /* # of threads checking writes_pending */ struct bitmap *bitmap; /* the bitmap for the device */ + struct bitmap_operations *bitmap_ops; struct { struct file *file; /* the bitmap file */ loff_t offset; /* offset from superblock of From 7545d385ec7e4c0d5e86e7cde4fe3fb8f4555fb9 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:22 +0800 Subject: [PATCH 12/42] md/md-bitmap: simplify md_bitmap_create() + md_bitmap_load() Other than internal api get_bitmap_from_slot(), all other places will set returned bitmap to mddev->bitmap. So move the setting of mddev->bitmap into md_bitmap_create() to simplify code. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-13-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 23 +++++++++++++++-------- drivers/md/md-bitmap.h | 2 +- drivers/md/md.c | 30 +++++++++--------------------- 3 files changed, 25 insertions(+), 30 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 69d9c959fe49a..2f3ff8e641217 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -1879,7 +1879,7 @@ void md_bitmap_destroy(struct mddev *mddev) * if this returns an error, bitmap_destroy must be called to do clean up * once mddev->bitmap is set */ -struct bitmap *md_bitmap_create(struct mddev *mddev, int slot) +static struct bitmap *__bitmap_create(struct mddev *mddev, int slot) { struct bitmap *bitmap; sector_t blocks = mddev->resync_max_sectors; @@ -1966,6 +1966,17 @@ struct bitmap *md_bitmap_create(struct mddev *mddev, int slot) return ERR_PTR(err); } +int md_bitmap_create(struct mddev *mddev, int slot) +{ + struct bitmap *bitmap = __bitmap_create(mddev, slot); + + if (IS_ERR(bitmap)) + return PTR_ERR(bitmap); + + mddev->bitmap = bitmap; + return 0; +} + int md_bitmap_load(struct mddev *mddev) { int err = 0; @@ -2030,7 +2041,7 @@ struct bitmap *get_bitmap_from_slot(struct mddev *mddev, int slot) int rv = 0; struct bitmap *bitmap; - bitmap = md_bitmap_create(mddev, slot); + bitmap = __bitmap_create(mddev, slot); if (IS_ERR(bitmap)) { rv = PTR_ERR(bitmap); return ERR_PTR(rv); @@ -2384,7 +2395,6 @@ location_store(struct mddev *mddev, const char *buf, size_t len) } else { /* No bitmap, OK to set a location */ long long offset; - struct bitmap *bitmap; if (strncmp(buf, "none", 4) == 0) /* nothing to be done */; @@ -2411,13 +2421,10 @@ location_store(struct mddev *mddev, const char *buf, size_t len) } mddev->bitmap_info.offset = offset; - bitmap = md_bitmap_create(mddev, -1); - if (IS_ERR(bitmap)) { - rv = PTR_ERR(bitmap); + rv = md_bitmap_create(mddev, -1); + if (rv) goto out; - } - mddev->bitmap = bitmap; rv = md_bitmap_load(mddev); if (rv) { mddev->bitmap_info.offset = 0; diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index 14c21ab42f9ed..d66f447f4be63 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -253,7 +253,7 @@ struct bitmap_operations { void mddev_set_bitmap_ops(struct mddev *mddev); /* these are used only by md/bitmap */ -struct bitmap *md_bitmap_create(struct mddev *mddev, int slot); +int md_bitmap_create(struct mddev *mddev, int slot); int md_bitmap_load(struct mddev *mddev); void md_bitmap_flush(struct mddev *mddev); void md_bitmap_destroy(struct mddev *mddev); diff --git a/drivers/md/md.c b/drivers/md/md.c index f86e6911318f9..7a041640c313a 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -6224,16 +6224,10 @@ int md_run(struct mddev *mddev) } if (err == 0 && pers->sync_request && (mddev->bitmap_info.file || mddev->bitmap_info.offset)) { - struct bitmap *bitmap; - - bitmap = md_bitmap_create(mddev, -1); - if (IS_ERR(bitmap)) { - err = PTR_ERR(bitmap); + err = md_bitmap_create(mddev, -1); + if (err) pr_warn("%s: failed to create bitmap (%d)\n", mdname(mddev), err); - } else - mddev->bitmap = bitmap; - } if (err) goto bitmap_abort; @@ -7288,14 +7282,10 @@ static int set_bitmap_file(struct mddev *mddev, int fd) err = 0; if (mddev->pers) { if (fd >= 0) { - struct bitmap *bitmap; - - bitmap = md_bitmap_create(mddev, -1); - if (!IS_ERR(bitmap)) { - mddev->bitmap = bitmap; + err = md_bitmap_create(mddev, -1); + if (!err) err = md_bitmap_load(mddev); - } else - err = PTR_ERR(bitmap); + if (err) { md_bitmap_destroy(mddev); fd = -1; @@ -7304,6 +7294,7 @@ static int set_bitmap_file(struct mddev *mddev, int fd) md_bitmap_destroy(mddev); } } + if (fd < 0) { struct file *f = mddev->bitmap_info.file; if (f) { @@ -7572,7 +7563,6 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info) goto err; } if (info->state & (1<bitmap) { rv = -EEXIST; @@ -7586,12 +7576,10 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info) mddev->bitmap_info.default_offset; mddev->bitmap_info.space = mddev->bitmap_info.default_space; - bitmap = md_bitmap_create(mddev, -1); - if (!IS_ERR(bitmap)) { - mddev->bitmap = bitmap; + rv = md_bitmap_create(mddev, -1); + if (!rv) rv = md_bitmap_load(mddev); - } else - rv = PTR_ERR(bitmap); + if (rv) md_bitmap_destroy(mddev); } else { From 04c80e649512f2c24f99052440cc808163eff40c Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:23 +0800 Subject: [PATCH 13/42] md/md-bitmap: merge md_bitmap_create() into bitmap_operations So that the implementation won't be exposed, and it'll be possible to invent a new bitmap by replacing bitmap_operations. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-14-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 5 +++-- drivers/md/md-bitmap.h | 2 +- drivers/md/md.c | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 2f3ff8e641217..c534382f0b570 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -1966,7 +1966,7 @@ static struct bitmap *__bitmap_create(struct mddev *mddev, int slot) return ERR_PTR(err); } -int md_bitmap_create(struct mddev *mddev, int slot) +static int bitmap_create(struct mddev *mddev, int slot) { struct bitmap *bitmap = __bitmap_create(mddev, slot); @@ -2421,7 +2421,7 @@ location_store(struct mddev *mddev, const char *buf, size_t len) } mddev->bitmap_info.offset = offset; - rv = md_bitmap_create(mddev, -1); + rv = bitmap_create(mddev, -1); if (rv) goto out; @@ -2723,6 +2723,7 @@ const struct attribute_group md_bitmap_group = { }; static struct bitmap_operations bitmap_ops = { + .create = bitmap_create, }; void mddev_set_bitmap_ops(struct mddev *mddev) diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index d66f447f4be63..f4c4925102b64 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -247,13 +247,13 @@ struct md_bitmap_stats { }; struct bitmap_operations { + int (*create)(struct mddev *mddev, int slot); }; /* the bitmap API */ void mddev_set_bitmap_ops(struct mddev *mddev); /* these are used only by md/bitmap */ -int md_bitmap_create(struct mddev *mddev, int slot); int md_bitmap_load(struct mddev *mddev); void md_bitmap_flush(struct mddev *mddev); void md_bitmap_destroy(struct mddev *mddev); diff --git a/drivers/md/md.c b/drivers/md/md.c index 7a041640c313a..7e774d4aaadd4 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -6224,7 +6224,7 @@ int md_run(struct mddev *mddev) } if (err == 0 && pers->sync_request && (mddev->bitmap_info.file || mddev->bitmap_info.offset)) { - err = md_bitmap_create(mddev, -1); + err = mddev->bitmap_ops->create(mddev, -1); if (err) pr_warn("%s: failed to create bitmap (%d)\n", mdname(mddev), err); @@ -7282,7 +7282,7 @@ static int set_bitmap_file(struct mddev *mddev, int fd) err = 0; if (mddev->pers) { if (fd >= 0) { - err = md_bitmap_create(mddev, -1); + err = mddev->bitmap_ops->create(mddev, -1); if (!err) err = md_bitmap_load(mddev); @@ -7576,7 +7576,7 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info) mddev->bitmap_info.default_offset; mddev->bitmap_info.space = mddev->bitmap_info.default_space; - rv = md_bitmap_create(mddev, -1); + rv = mddev->bitmap_ops->create(mddev, -1); if (!rv) rv = md_bitmap_load(mddev); From e1e490805958617327be14eaf0ed31d71adc2c54 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:24 +0800 Subject: [PATCH 14/42] md/md-bitmap: merge md_bitmap_load() into bitmap_operations So that the implementation won't be exposed, and it'll be possible to invent a new bitmap by replacing bitmap_operations. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-15-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/dm-raid.c | 4 +++- drivers/md/md-bitmap.c | 6 +++--- drivers/md/md-bitmap.h | 2 +- drivers/md/md.c | 7 ++++--- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 0c3323e0adb2a..c3e201fde4c5d 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -3949,7 +3949,9 @@ static int __load_dirty_region_bitmap(struct raid_set *rs) /* Try loading the bitmap unless "raid0", which does not have one */ if (!rs_is_raid0(rs) && !test_and_set_bit(RT_FLAG_RS_BITMAP_LOADED, &rs->runtime_flags)) { - r = md_bitmap_load(&rs->md); + struct mddev *mddev = &rs->md; + + r = mddev->bitmap_ops->load(mddev); if (r) DMERR("Failed to load bitmap"); } diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index c534382f0b570..c236754df66e6 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -1977,7 +1977,7 @@ static int bitmap_create(struct mddev *mddev, int slot) return 0; } -int md_bitmap_load(struct mddev *mddev) +static int bitmap_load(struct mddev *mddev) { int err = 0; sector_t start = 0; @@ -2033,7 +2033,6 @@ int md_bitmap_load(struct mddev *mddev) out: return err; } -EXPORT_SYMBOL_GPL(md_bitmap_load); /* caller need to free returned bitmap with md_bitmap_free() */ struct bitmap *get_bitmap_from_slot(struct mddev *mddev, int slot) @@ -2425,7 +2424,7 @@ location_store(struct mddev *mddev, const char *buf, size_t len) if (rv) goto out; - rv = md_bitmap_load(mddev); + rv = bitmap_load(mddev); if (rv) { mddev->bitmap_info.offset = 0; md_bitmap_destroy(mddev); @@ -2724,6 +2723,7 @@ const struct attribute_group md_bitmap_group = { static struct bitmap_operations bitmap_ops = { .create = bitmap_create, + .load = bitmap_load, }; void mddev_set_bitmap_ops(struct mddev *mddev) diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index f4c4925102b64..f5b04b61d9e9d 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -248,13 +248,13 @@ struct md_bitmap_stats { struct bitmap_operations { int (*create)(struct mddev *mddev, int slot); + int (*load)(struct mddev *mddev); }; /* the bitmap API */ void mddev_set_bitmap_ops(struct mddev *mddev); /* these are used only by md/bitmap */ -int md_bitmap_load(struct mddev *mddev); void md_bitmap_flush(struct mddev *mddev); void md_bitmap_destroy(struct mddev *mddev); diff --git a/drivers/md/md.c b/drivers/md/md.c index 7e774d4aaadd4..9c63be7aa6a5d 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -6316,7 +6316,8 @@ int do_md_run(struct mddev *mddev) err = md_run(mddev); if (err) goto out; - err = md_bitmap_load(mddev); + + err = mddev->bitmap_ops->load(mddev); if (err) { md_bitmap_destroy(mddev); goto out; @@ -7284,7 +7285,7 @@ static int set_bitmap_file(struct mddev *mddev, int fd) if (fd >= 0) { err = mddev->bitmap_ops->create(mddev, -1); if (!err) - err = md_bitmap_load(mddev); + err = mddev->bitmap_ops->load(mddev); if (err) { md_bitmap_destroy(mddev); @@ -7578,7 +7579,7 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info) mddev->bitmap_info.default_space; rv = mddev->bitmap_ops->create(mddev, -1); if (!rv) - rv = md_bitmap_load(mddev); + rv = mddev->bitmap_ops->load(mddev); if (rv) md_bitmap_destroy(mddev); From a2bd70319290d80127dc4257b8c17df3f027c15d Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:25 +0800 Subject: [PATCH 15/42] md/md-bitmap: merge md_bitmap_destroy() into bitmap_operations So that the implementation won't be exposed, and it'll be possible to invent a new bitmap by replacing bitmap_operations. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-16-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 7 ++++--- drivers/md/md-bitmap.h | 2 +- drivers/md/md.c | 15 ++++++++------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index c236754df66e6..dc898db266d00 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -1853,7 +1853,7 @@ void md_bitmap_wait_behind_writes(struct mddev *mddev) } EXPORT_SYMBOL_GPL(md_bitmap_wait_behind_writes); -void md_bitmap_destroy(struct mddev *mddev) +static void bitmap_destroy(struct mddev *mddev) { struct bitmap *bitmap = mddev->bitmap; @@ -2384,7 +2384,7 @@ location_store(struct mddev *mddev, const char *buf, size_t len) goto out; } - md_bitmap_destroy(mddev); + bitmap_destroy(mddev); mddev->bitmap_info.offset = 0; if (mddev->bitmap_info.file) { struct file *f = mddev->bitmap_info.file; @@ -2427,7 +2427,7 @@ location_store(struct mddev *mddev, const char *buf, size_t len) rv = bitmap_load(mddev); if (rv) { mddev->bitmap_info.offset = 0; - md_bitmap_destroy(mddev); + bitmap_destroy(mddev); goto out; } } @@ -2724,6 +2724,7 @@ const struct attribute_group md_bitmap_group = { static struct bitmap_operations bitmap_ops = { .create = bitmap_create, .load = bitmap_load, + .destroy = bitmap_destroy, }; void mddev_set_bitmap_ops(struct mddev *mddev) diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index f5b04b61d9e9d..c8d27b91241b3 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -249,6 +249,7 @@ struct md_bitmap_stats { struct bitmap_operations { int (*create)(struct mddev *mddev, int slot); int (*load)(struct mddev *mddev); + void (*destroy)(struct mddev *mddev); }; /* the bitmap API */ @@ -256,7 +257,6 @@ void mddev_set_bitmap_ops(struct mddev *mddev); /* these are used only by md/bitmap */ void md_bitmap_flush(struct mddev *mddev); -void md_bitmap_destroy(struct mddev *mddev); void md_bitmap_print_sb(struct bitmap *bitmap); void md_bitmap_update_sb(struct bitmap *bitmap); diff --git a/drivers/md/md.c b/drivers/md/md.c index 9c63be7aa6a5d..eeb17eb1fc028 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -6297,7 +6297,7 @@ int md_run(struct mddev *mddev) pers->free(mddev, mddev->private); mddev->private = NULL; module_put(pers->owner); - md_bitmap_destroy(mddev); + mddev->bitmap_ops->destroy(mddev); abort: bioset_exit(&mddev->io_clone_set); exit_sync_set: @@ -6319,7 +6319,7 @@ int do_md_run(struct mddev *mddev) err = mddev->bitmap_ops->load(mddev); if (err) { - md_bitmap_destroy(mddev); + mddev->bitmap_ops->destroy(mddev); goto out; } @@ -6505,7 +6505,8 @@ static void mddev_detach(struct mddev *mddev) static void __md_stop(struct mddev *mddev) { struct md_personality *pers = mddev->pers; - md_bitmap_destroy(mddev); + + mddev->bitmap_ops->destroy(mddev); mddev_detach(mddev); spin_lock(&mddev->lock); mddev->pers = NULL; @@ -7288,11 +7289,11 @@ static int set_bitmap_file(struct mddev *mddev, int fd) err = mddev->bitmap_ops->load(mddev); if (err) { - md_bitmap_destroy(mddev); + mddev->bitmap_ops->destroy(mddev); fd = -1; } } else if (fd < 0) { - md_bitmap_destroy(mddev); + mddev->bitmap_ops->destroy(mddev); } } @@ -7582,7 +7583,7 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info) rv = mddev->bitmap_ops->load(mddev); if (rv) - md_bitmap_destroy(mddev); + mddev->bitmap_ops->destroy(mddev); } else { struct md_bitmap_stats stats; @@ -7609,7 +7610,7 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info) module_put(md_cluster_mod); mddev->safemode_delay = DEFAULT_SAFEMODE_DELAY; } - md_bitmap_destroy(mddev); + mddev->bitmap_ops->destroy(mddev); mddev->bitmap_info.offset = 0; } } From ca925302e841ff0a0598b283f87c472d92b389f3 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:26 +0800 Subject: [PATCH 16/42] md/md-bitmap: merge md_bitmap_flush() into bitmap_operations So that the implementation won't be exposed, and it'll be possible to invent a new bitmap by replacing bitmap_operations. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-17-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 6 ++---- drivers/md/md-bitmap.h | 2 +- drivers/md/md.c | 3 ++- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index dc898db266d00..0035162fe6f38 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -1773,10 +1773,7 @@ void md_bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long } } -/* - * flush out any pending updates - */ -void md_bitmap_flush(struct mddev *mddev) +static void bitmap_flush(struct mddev *mddev) { struct bitmap *bitmap = mddev->bitmap; long sleep; @@ -2725,6 +2722,7 @@ static struct bitmap_operations bitmap_ops = { .create = bitmap_create, .load = bitmap_load, .destroy = bitmap_destroy, + .flush = bitmap_flush, }; void mddev_set_bitmap_ops(struct mddev *mddev) diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index c8d27b91241b3..c0858665554ef 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -250,13 +250,13 @@ struct bitmap_operations { int (*create)(struct mddev *mddev, int slot); int (*load)(struct mddev *mddev); void (*destroy)(struct mddev *mddev); + void (*flush)(struct mddev *mddev); }; /* the bitmap API */ void mddev_set_bitmap_ops(struct mddev *mddev); /* these are used only by md/bitmap */ -void md_bitmap_flush(struct mddev *mddev); void md_bitmap_print_sb(struct bitmap *bitmap); void md_bitmap_update_sb(struct bitmap *bitmap); diff --git a/drivers/md/md.c b/drivers/md/md.c index eeb17eb1fc028..b422acd4b2a45 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -6463,7 +6463,8 @@ static void __md_stop_writes(struct mddev *mddev) mddev->pers->quiesce(mddev, 1); mddev->pers->quiesce(mddev, 0); } - md_bitmap_flush(mddev); + + mddev->bitmap_ops->flush(mddev); if (md_is_rdwr(mddev) && ((!mddev->in_sync && !mddev_is_clustered(mddev)) || From a0240e3ec753d3caf29edbaf6cf5685c7b447a2a Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:27 +0800 Subject: [PATCH 17/42] md/md-bitmap: make md_bitmap_print_sb() internal md_bitmap_print_sb() is only used inside md-bitmap.c, hence make it static, also rename it to bitmap_print_sb. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-18-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 5 ++--- drivers/md/md-bitmap.h | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 0035162fe6f38..86444cbee56e1 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -512,8 +512,7 @@ void md_bitmap_update_sb(struct bitmap *bitmap) } EXPORT_SYMBOL(md_bitmap_update_sb); -/* print out the bitmap file superblock */ -void md_bitmap_print_sb(struct bitmap *bitmap) +static void bitmap_print_sb(struct bitmap *bitmap) { bitmap_super_t *sb; @@ -760,7 +759,7 @@ static int md_bitmap_read_sb(struct bitmap *bitmap) bitmap->mddev->bitmap_info.space > sectors_reserved) bitmap->mddev->bitmap_info.space = sectors_reserved; } else { - md_bitmap_print_sb(bitmap); + bitmap_print_sb(bitmap); if (bitmap->cluster_slot < 0) md_cluster_stop(bitmap->mddev); } diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index c0858665554ef..5d5811c89b771 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -258,7 +258,6 @@ void mddev_set_bitmap_ops(struct mddev *mddev); /* these are used only by md/bitmap */ -void md_bitmap_print_sb(struct bitmap *bitmap); void md_bitmap_update_sb(struct bitmap *bitmap); int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats); From fe59b34676b4ec6b48a7b436d3422fc9317e047a Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:28 +0800 Subject: [PATCH 18/42] md/md-bitmap: merge md_bitmap_update_sb() into bitmap_operations So that the implementation won't be exposed, and it'll be possible to invent a new bitmap by replacing bitmap_operations. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-19-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 15 ++++++++------- drivers/md/md-bitmap.h | 3 ++- drivers/md/md-cluster.c | 2 +- drivers/md/md.c | 4 ++-- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 86444cbee56e1..23c7d4be3ffdf 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -472,7 +472,7 @@ static void md_bitmap_wait_writes(struct bitmap *bitmap) /* update the event counter and sync the superblock to disk */ -void md_bitmap_update_sb(struct bitmap *bitmap) +static void bitmap_update_sb(struct bitmap *bitmap) { bitmap_super_t *sb; @@ -510,7 +510,6 @@ void md_bitmap_update_sb(struct bitmap *bitmap) write_sb_page(bitmap, bitmap->storage.sb_index, bitmap->storage.sb_page, 1); } -EXPORT_SYMBOL(md_bitmap_update_sb); static void bitmap_print_sb(struct bitmap *bitmap) { @@ -892,7 +891,7 @@ static void md_bitmap_file_unmap(struct bitmap_storage *store) static void md_bitmap_file_kick(struct bitmap *bitmap) { if (!test_and_set_bit(BITMAP_STALE, &bitmap->flags)) { - md_bitmap_update_sb(bitmap); + bitmap_update_sb(bitmap); if (bitmap->storage.file) { pr_warn("%s: kicking failed bitmap file %pD4 from array!\n", @@ -1792,7 +1791,7 @@ static void bitmap_flush(struct mddev *mddev) md_bitmap_daemon_work(mddev); if (mddev->bitmap_info.external) md_super_wait(mddev); - md_bitmap_update_sb(bitmap); + bitmap_update_sb(bitmap); } /* @@ -2022,7 +2021,7 @@ static int bitmap_load(struct mddev *mddev) mddev_set_timeout(mddev, mddev->bitmap_info.daemon_sleep, true); md_wakeup_thread(mddev->thread); - md_bitmap_update_sb(bitmap); + bitmap_update_sb(bitmap); if (test_bit(BITMAP_WRITE_ERROR, &bitmap->flags)) err = -EIO; @@ -2083,7 +2082,7 @@ int md_bitmap_copy_from_slot(struct mddev *mddev, int slot, } if (clear_bits) { - md_bitmap_update_sb(bitmap); + bitmap_update_sb(bitmap); /* BITMAP_PAGE_PENDING is set, but bitmap_unplug needs * BITMAP_PAGE_DIRTY or _NEEDWRITE to write ... */ for (i = 0; i < bitmap->storage.file_pages; i++) @@ -2578,7 +2577,7 @@ backlog_store(struct mddev *mddev, const char *buf, size_t len) mddev_create_serial_pool(mddev, rdev); } if (old_mwb != backlog) - md_bitmap_update_sb(mddev->bitmap); + bitmap_update_sb(mddev->bitmap); mddev_unlock_and_resume(mddev); return len; @@ -2722,6 +2721,8 @@ static struct bitmap_operations bitmap_ops = { .load = bitmap_load, .destroy = bitmap_destroy, .flush = bitmap_flush, + + .update_sb = bitmap_update_sb, }; void mddev_set_bitmap_ops(struct mddev *mddev) diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index 5d5811c89b771..ca0d8696136f6 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -251,6 +251,8 @@ struct bitmap_operations { int (*load)(struct mddev *mddev); void (*destroy)(struct mddev *mddev); void (*flush)(struct mddev *mddev); + + void (*update_sb)(struct bitmap *bitmap); }; /* the bitmap API */ @@ -258,7 +260,6 @@ void mddev_set_bitmap_ops(struct mddev *mddev); /* these are used only by md/bitmap */ -void md_bitmap_update_sb(struct bitmap *bitmap); int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats); int md_bitmap_setallbits(struct bitmap *bitmap); diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index 59f7fbca783bc..ca30881556bdf 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -1255,7 +1255,7 @@ static int cluster_check_sync_size(struct mddev *mddev) bm_lockres->flags |= DLM_LKF_NOQUEUE; rv = dlm_lock_sync(bm_lockres, DLM_LOCK_PW); if (!rv) - md_bitmap_update_sb(bitmap); + mddev->bitmap_ops->update_sb(bitmap); lockres_free(bm_lockres); rv = md_bitmap_get_stats(bitmap, &stats); diff --git a/drivers/md/md.c b/drivers/md/md.c index b422acd4b2a45..5f9df96eab51d 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2838,7 +2838,7 @@ void md_update_sb(struct mddev *mddev, int force_change) mddev_add_trace_msg(mddev, "md md_update_sb"); rewrite: - md_bitmap_update_sb(mddev->bitmap); + mddev->bitmap_ops->update_sb(mddev->bitmap); rdev_for_each(rdev, mddev) { if (rdev->sb_loaded != 1) continue; /* no noise on spare devices */ @@ -10002,7 +10002,7 @@ static void check_sb_changes(struct mddev *mddev, struct md_rdev *rdev) if (ret) pr_info("md-cluster: resize failed\n"); else - md_bitmap_update_sb(mddev->bitmap); + mddev->bitmap_ops->update_sb(mddev->bitmap); } /* Check for change of roles in the active devices */ From 696936838bc18a761ed778910975d51cf2c35e3a Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:29 +0800 Subject: [PATCH 19/42] md/md-bitmap: merge md_bitmap_status() into bitmap_operations So that the implementation won't be exposed, and it'll be possible to invent a new bitmap by replacing bitmap_operations. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-20-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 4 ++-- drivers/md/md-bitmap.h | 3 +-- drivers/md/md-cluster.c | 8 ++++---- drivers/md/md.c | 11 ++++++----- drivers/md/raid1.c | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 23c7d4be3ffdf..b2fbec3997f2d 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -2105,7 +2105,7 @@ void md_bitmap_set_pages(struct bitmap *bitmap, unsigned long pages) } EXPORT_SYMBOL_GPL(md_bitmap_set_pages); -int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats) +static int bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats) { struct bitmap_storage *storage; struct bitmap_counts *counts; @@ -2131,7 +2131,6 @@ int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats) stats->events_cleared = bitmap->events_cleared; return 0; } -EXPORT_SYMBOL_GPL(md_bitmap_get_stats); int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks, int chunksize, int init) @@ -2723,6 +2722,7 @@ static struct bitmap_operations bitmap_ops = { .flush = bitmap_flush, .update_sb = bitmap_update_sb, + .get_stats = bitmap_get_stats, }; void mddev_set_bitmap_ops(struct mddev *mddev) diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index ca0d8696136f6..1df238cb82f09 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -253,6 +253,7 @@ struct bitmap_operations { void (*flush)(struct mddev *mddev); void (*update_sb)(struct bitmap *bitmap); + int (*get_stats)(struct bitmap *bitmap, struct md_bitmap_stats *stats); }; /* the bitmap API */ @@ -260,8 +261,6 @@ void mddev_set_bitmap_ops(struct mddev *mddev); /* these are used only by md/bitmap */ -int md_bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats); - int md_bitmap_setallbits(struct bitmap *bitmap); void md_bitmap_write_all(struct bitmap *bitmap); diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index ca30881556bdf..a5f1135cc1fa9 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -1148,7 +1148,7 @@ static int resize_bitmaps(struct mddev *mddev, sector_t newsize, sector_t oldsiz unsigned long my_pages; int i, rv; - rv = md_bitmap_get_stats(bitmap, &stats); + rv = mddev->bitmap_ops->get_stats(bitmap, &stats); if (rv) return rv; @@ -1175,7 +1175,7 @@ static int resize_bitmaps(struct mddev *mddev, sector_t newsize, sector_t oldsiz goto out; } - rv = md_bitmap_get_stats(bitmap, &stats); + rv = mddev->bitmap_ops->get_stats(bitmap, &stats); if (rv) goto out; /* @@ -1225,7 +1225,7 @@ static int cluster_check_sync_size(struct mddev *mddev) char str[64]; int i, rv; - rv = md_bitmap_get_stats(bitmap, &stats); + rv = mddev->bitmap_ops->get_stats(bitmap, &stats); if (rv) return rv; @@ -1258,7 +1258,7 @@ static int cluster_check_sync_size(struct mddev *mddev) mddev->bitmap_ops->update_sb(bitmap); lockres_free(bm_lockres); - rv = md_bitmap_get_stats(bitmap, &stats); + rv = mddev->bitmap_ops->get_stats(bitmap, &stats); if (rv) { md_bitmap_free(bitmap); return rv; diff --git a/drivers/md/md.c b/drivers/md/md.c index 5f9df96eab51d..6c184748f3174 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1378,7 +1378,7 @@ static u64 md_bitmap_events_cleared(struct mddev *mddev) struct md_bitmap_stats stats; int err; - err = md_bitmap_get_stats(mddev->bitmap, &stats); + err = mddev->bitmap_ops->get_stats(mddev->bitmap, &stats); if (err) return 0; @@ -2354,11 +2354,12 @@ super_1_allow_new_offset(struct md_rdev *rdev, return 0; if (!rdev->mddev->bitmap_info.file) { + struct mddev *mddev = rdev->mddev; struct md_bitmap_stats stats; int err; - err = md_bitmap_get_stats(rdev->mddev->bitmap, &stats); - if (!err && rdev->sb_start + rdev->mddev->bitmap_info.offset + + err = mddev->bitmap_ops->get_stats(mddev->bitmap, &stats); + if (!err && rdev->sb_start + mddev->bitmap_info.offset + stats.file_pages * (PAGE_SIZE >> 9) > new_offset) return 0; } @@ -7588,7 +7589,7 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info) } else { struct md_bitmap_stats stats; - rv = md_bitmap_get_stats(mddev->bitmap, &stats); + rv = mddev->bitmap_ops->get_stats(mddev->bitmap, &stats); if (rv) goto err; @@ -8388,7 +8389,7 @@ static void md_bitmap_status(struct seq_file *seq, struct mddev *mddev) unsigned long chunk_kb; int err; - err = md_bitmap_get_stats(mddev->bitmap, &stats); + err = mddev->bitmap_ops->get_stats(mddev->bitmap, &stats); if (err) return; diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index b6c4e44f9b4ba..d490a9ac484f8 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1599,7 +1599,7 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio, * Not if there are too many, or cannot * allocate memory, or a reader on WriteMostly * is waiting for behind writes to flush */ - err = md_bitmap_get_stats(bitmap, &stats); + err = mddev->bitmap_ops->get_stats(bitmap, &stats); if (!err && write_behind && !stats.behind_wait && stats.behind_writes < max_write_behind) alloc_behind_master_bio(r1_bio, bio); From ea076ceb35d66d29fc0a50c15a4b0248c5122d2c Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:30 +0800 Subject: [PATCH 20/42] md/md-bitmap: remove md_bitmap_setallbits() md_bitmap_setallbits() is not used, hence can be removed. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-21-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index 1df238cb82f09..0bf16f0143ad8 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -261,7 +261,6 @@ void mddev_set_bitmap_ops(struct mddev *mddev); /* these are used only by md/bitmap */ -int md_bitmap_setallbits(struct bitmap *bitmap); void md_bitmap_write_all(struct bitmap *bitmap); void md_bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e); From b26313cb96f1b3fd6f07d3243f6cd426c5cbaf39 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:31 +0800 Subject: [PATCH 21/42] md/md-bitmap: merge bitmap_write_all() into bitmap_operations So that the implementation won't be exposed, and it'll be possible to invent a new bitmap by replacing bitmap_operations. Also change the parameter from bitmap to mddev, to avoid access bitmap outside md-bitmap.c as much as possible. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-22-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 14 +++++++------- drivers/md/md-bitmap.h | 3 +-- drivers/md/md.c | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index b2fbec3997f2d..47d074bf292d2 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -1224,22 +1224,21 @@ static int md_bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) return ret; } -void md_bitmap_write_all(struct bitmap *bitmap) +/* just flag bitmap pages as needing to be written. */ +static void bitmap_write_all(struct mddev *mddev) { - /* We don't actually write all bitmap blocks here, - * just flag them as needing to be written - */ int i; + struct bitmap *bitmap = mddev->bitmap; if (!bitmap || !bitmap->storage.filemap) return; + + /* Only one copy, so nothing needed */ if (bitmap->storage.file) - /* Only one copy, so nothing needed */ return; for (i = 0; i < bitmap->storage.file_pages; i++) - set_page_attr(bitmap, i, - BITMAP_PAGE_NEEDWRITE); + set_page_attr(bitmap, i, BITMAP_PAGE_NEEDWRITE); bitmap->allclean = 0; } @@ -2720,6 +2719,7 @@ static struct bitmap_operations bitmap_ops = { .load = bitmap_load, .destroy = bitmap_destroy, .flush = bitmap_flush, + .write_all = bitmap_write_all, .update_sb = bitmap_update_sb, .get_stats = bitmap_get_stats, diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index 0bf16f0143ad8..89cd60a7bb071 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -251,6 +251,7 @@ struct bitmap_operations { int (*load)(struct mddev *mddev); void (*destroy)(struct mddev *mddev); void (*flush)(struct mddev *mddev); + void (*write_all)(struct mddev *mddev); void (*update_sb)(struct bitmap *bitmap); int (*get_stats)(struct bitmap *bitmap, struct md_bitmap_stats *stats); @@ -261,8 +262,6 @@ void mddev_set_bitmap_ops(struct mddev *mddev); /* these are used only by md/bitmap */ -void md_bitmap_write_all(struct bitmap *bitmap); - void md_bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e); /* these are exported */ diff --git a/drivers/md/md.c b/drivers/md/md.c index 6c184748f3174..1dc800113b7bb 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -9544,7 +9544,7 @@ static void md_start_sync(struct work_struct *ws) * stored on all devices. So make sure all bitmap pages get written. */ if (spares) - md_bitmap_write_all(mddev->bitmap); + mddev->bitmap_ops->write_all(mddev); name = test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) ? "reshape" : "resync"; From 2d3b130e177f14b461c47880b6e0b338fd6872f5 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:32 +0800 Subject: [PATCH 22/42] md/md-bitmap: merge md_bitmap_dirty_bits() into bitmap_operations So that the implementation won't be exposed, and it'll be possible to invent a new bitmap by replacing bitmap_operations. Also change the parameter from bitmap to mddev, to avoid access bitmap outside md-bitmap.c as much as possible. And while we're here, also fix coding style for bitmap_store(). Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-23-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 9 ++++++++- drivers/md/md-bitmap.h | 6 ++---- drivers/md/md.c | 14 ++++++++++---- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 47d074bf292d2..6448f78d50c2f 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -1753,12 +1753,18 @@ static void md_bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, in } /* dirty the memory and file bits for bitmap chunks "s" to "e" */ -void md_bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e) +static void bitmap_dirty_bits(struct mddev *mddev, unsigned long s, + unsigned long e) { unsigned long chunk; + struct bitmap *bitmap = mddev->bitmap; + + if (!bitmap) + return; for (chunk = s; chunk <= e; chunk++) { sector_t sec = (sector_t)chunk << bitmap->counts.chunkshift; + md_bitmap_set_memory_bits(bitmap, sec, 1); md_bitmap_file_set_bit(bitmap, sec); if (sec < bitmap->mddev->recovery_cp) @@ -2720,6 +2726,7 @@ static struct bitmap_operations bitmap_ops = { .destroy = bitmap_destroy, .flush = bitmap_flush, .write_all = bitmap_write_all, + .dirty_bits = bitmap_dirty_bits, .update_sb = bitmap_update_sb, .get_stats = bitmap_get_stats, diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index 89cd60a7bb071..875ecbb5b1e49 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -252,6 +252,8 @@ struct bitmap_operations { void (*destroy)(struct mddev *mddev); void (*flush)(struct mddev *mddev); void (*write_all)(struct mddev *mddev); + void (*dirty_bits)(struct mddev *mddev, unsigned long s, + unsigned long e); void (*update_sb)(struct bitmap *bitmap); int (*get_stats)(struct bitmap *bitmap, struct md_bitmap_stats *stats); @@ -260,10 +262,6 @@ struct bitmap_operations { /* the bitmap API */ void mddev_set_bitmap_ops(struct mddev *mddev); -/* these are used only by md/bitmap */ - -void md_bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e); - /* these are exported */ int md_bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, int behind); diff --git a/drivers/md/md.c b/drivers/md/md.c index 1dc800113b7bb..f72fa8e872f81 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -4699,14 +4699,20 @@ bitmap_store(struct mddev *mddev, const char *buf, size_t len) /* buf should be ... or - ... (range) */ while (*buf) { chunk = end_chunk = simple_strtoul(buf, &end, 0); - if (buf == end) break; + if (buf == end) + break; + if (*end == '-') { /* range */ buf = end + 1; end_chunk = simple_strtoul(buf, &end, 0); - if (buf == end) break; + if (buf == end) + break; } - if (*end && !isspace(*end)) break; - md_bitmap_dirty_bits(mddev->bitmap, chunk, end_chunk); + + if (*end && !isspace(*end)) + break; + + mddev->bitmap_ops->dirty_bits(mddev, chunk, end_chunk); buf = skip_spaces(end); } md_bitmap_unplug(mddev->bitmap); /* flush the bits to disk */ From c2257df4108ed872f46c96d6ea6092f17a747632 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:33 +0800 Subject: [PATCH 23/42] md/md-bitmap: merge md_bitmap_startwrite() into bitmap_operations So that the implementation won't be exposed, and it'll be possible to invent a new bitmap by replacing bitmap_operations. Also change the parameter from bitmap to mddev, to avoid access bitmap outside md-bitmap.c as much as possible. And change the type of 'behind' from int to bool. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-24-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 8 ++++++-- drivers/md/md-bitmap.h | 5 +++-- drivers/md/raid1.c | 5 +++-- drivers/md/raid10.c | 3 ++- drivers/md/raid5.c | 13 +++++-------- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 6448f78d50c2f..0168dbd5ecb0f 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -1458,8 +1458,11 @@ __acquires(bitmap->lock) &(bitmap->bp[page].map[pageoff]); } -int md_bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, int behind) +static int bitmap_startwrite(struct mddev *mddev, sector_t offset, + unsigned long sectors, bool behind) { + struct bitmap *bitmap = mddev->bitmap; + if (!bitmap) return 0; @@ -1520,7 +1523,6 @@ int md_bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long s } return 0; } -EXPORT_SYMBOL(md_bitmap_startwrite); void md_bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, int success, int behind) @@ -2728,6 +2730,8 @@ static struct bitmap_operations bitmap_ops = { .write_all = bitmap_write_all, .dirty_bits = bitmap_dirty_bits, + .startwrite = bitmap_startwrite, + .update_sb = bitmap_update_sb, .get_stats = bitmap_get_stats, }; diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index 875ecbb5b1e49..1433d13e447a6 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -255,6 +255,9 @@ struct bitmap_operations { void (*dirty_bits)(struct mddev *mddev, unsigned long s, unsigned long e); + int (*startwrite)(struct mddev *mddev, sector_t offset, + unsigned long sectors, bool behind); + void (*update_sb)(struct bitmap *bitmap); int (*get_stats)(struct bitmap *bitmap, struct md_bitmap_stats *stats); }; @@ -263,8 +266,6 @@ struct bitmap_operations { void mddev_set_bitmap_ops(struct mddev *mddev); /* these are exported */ -int md_bitmap_startwrite(struct bitmap *bitmap, sector_t offset, - unsigned long sectors, int behind); void md_bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, int success, int behind); int md_bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int degraded); diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index d490a9ac484f8..708687cb28d56 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1604,8 +1604,9 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio, stats.behind_writes < max_write_behind) alloc_behind_master_bio(r1_bio, bio); - md_bitmap_startwrite(bitmap, r1_bio->sector, r1_bio->sectors, - test_bit(R1BIO_BehindIO, &r1_bio->state)); + mddev->bitmap_ops->startwrite( + mddev, r1_bio->sector, r1_bio->sectors, + test_bit(R1BIO_BehindIO, &r1_bio->state)); first_clone = 0; } diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index e55e020b55711..8f9172c3329a8 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1492,7 +1492,8 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio, md_account_bio(mddev, &bio); r10_bio->master_bio = bio; atomic_set(&r10_bio->remaining, 1); - md_bitmap_startwrite(mddev->bitmap, r10_bio->sector, r10_bio->sectors, 0); + mddev->bitmap_ops->startwrite(mddev, r10_bio->sector, r10_bio->sectors, + false); for (i = 0; i < conf->copies; i++) { if (r10_bio->devs[i].bio) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index c14cf2410365d..c24036d1e6dad 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3563,8 +3563,8 @@ static void __add_stripe_bio(struct stripe_head *sh, struct bio *bi, */ set_bit(STRIPE_BITMAP_PENDING, &sh->state); spin_unlock_irq(&sh->stripe_lock); - md_bitmap_startwrite(conf->mddev->bitmap, sh->sector, - RAID5_STRIPE_SECTORS(conf), 0); + conf->mddev->bitmap_ops->startwrite(conf->mddev, sh->sector, + RAID5_STRIPE_SECTORS(conf), false); spin_lock_irq(&sh->stripe_lock); clear_bit(STRIPE_BITMAP_PENDING, &sh->state); if (!sh->batch_head) { @@ -5788,13 +5788,10 @@ static void make_discard_request(struct mddev *mddev, struct bio *bi) } spin_unlock_irq(&sh->stripe_lock); if (conf->mddev->bitmap) { - for (d = 0; - d < conf->raid_disks - conf->max_degraded; + for (d = 0; d < conf->raid_disks - conf->max_degraded; d++) - md_bitmap_startwrite(mddev->bitmap, - sh->sector, - RAID5_STRIPE_SECTORS(conf), - 0); + mddev->bitmap_ops->startwrite(mddev, sh->sector, + RAID5_STRIPE_SECTORS(conf), false); sh->bm_seq = conf->seq_flush + 1; set_bit(STRIPE_BIT_DELAY, &sh->state); } From 3486015facc030f30d694b92dc18e58073c6c9e0 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:34 +0800 Subject: [PATCH 24/42] md/md-bitmap: merge md_bitmap_endwrite() into bitmap_operations So that the implementation won't be exposed, and it'll be possible to invent a new bitmap by replacing bitmap_operations. Also change the parameter from bitmap to mddev, to avoid access bitmap outside md-bitmap.c as much as possible. And change the type of 'success' and 'behind' from int to bool. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-25-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 9 ++++++--- drivers/md/md-bitmap.h | 4 ++-- drivers/md/raid1.c | 12 +++++++----- drivers/md/raid10.c | 11 ++++++----- drivers/md/raid5-cache.c | 8 ++++---- drivers/md/raid5.c | 18 ++++++++++-------- 6 files changed, 35 insertions(+), 27 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 0168dbd5ecb0f..4d174ab253398 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -1524,11 +1524,14 @@ static int bitmap_startwrite(struct mddev *mddev, sector_t offset, return 0; } -void md_bitmap_endwrite(struct bitmap *bitmap, sector_t offset, - unsigned long sectors, int success, int behind) +static void bitmap_endwrite(struct mddev *mddev, sector_t offset, + unsigned long sectors, bool success, bool behind) { + struct bitmap *bitmap = mddev->bitmap; + if (!bitmap) return; + if (behind) { if (atomic_dec_and_test(&bitmap->behind_writes)) wake_up(&bitmap->behind_wait); @@ -1575,7 +1578,6 @@ void md_bitmap_endwrite(struct bitmap *bitmap, sector_t offset, sectors = 0; } } -EXPORT_SYMBOL(md_bitmap_endwrite); static int __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int degraded) @@ -2731,6 +2733,7 @@ static struct bitmap_operations bitmap_ops = { .dirty_bits = bitmap_dirty_bits, .startwrite = bitmap_startwrite, + .endwrite = bitmap_endwrite, .update_sb = bitmap_update_sb, .get_stats = bitmap_get_stats, diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index 1433d13e447a6..056a80ee500f5 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -257,6 +257,8 @@ struct bitmap_operations { int (*startwrite)(struct mddev *mddev, sector_t offset, unsigned long sectors, bool behind); + void (*endwrite)(struct mddev *mddev, sector_t offset, + unsigned long sectors, bool success, bool behind); void (*update_sb)(struct bitmap *bitmap); int (*get_stats)(struct bitmap *bitmap, struct md_bitmap_stats *stats); @@ -266,8 +268,6 @@ struct bitmap_operations { void mddev_set_bitmap_ops(struct mddev *mddev); /* these are exported */ -void md_bitmap_endwrite(struct bitmap *bitmap, sector_t offset, - unsigned long sectors, int success, int behind); int md_bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int degraded); void md_bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int aborted); void md_bitmap_close_sync(struct bitmap *bitmap); diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 708687cb28d56..b335293ec4728 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -411,18 +411,20 @@ static void raid1_end_read_request(struct bio *bio) static void close_write(struct r1bio *r1_bio) { + struct mddev *mddev = r1_bio->mddev; + /* it really is the end of this request */ if (test_bit(R1BIO_BehindIO, &r1_bio->state)) { bio_free_pages(r1_bio->behind_master_bio); bio_put(r1_bio->behind_master_bio); r1_bio->behind_master_bio = NULL; } + /* clear the bitmap if all writes complete successfully */ - md_bitmap_endwrite(r1_bio->mddev->bitmap, r1_bio->sector, - r1_bio->sectors, - !test_bit(R1BIO_Degraded, &r1_bio->state), - test_bit(R1BIO_BehindIO, &r1_bio->state)); - md_write_end(r1_bio->mddev); + mddev->bitmap_ops->endwrite(mddev, r1_bio->sector, r1_bio->sectors, + !test_bit(R1BIO_Degraded, &r1_bio->state), + test_bit(R1BIO_BehindIO, &r1_bio->state)); + md_write_end(mddev); } static void r1_bio_write_done(struct r1bio *r1_bio) diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 8f9172c3329a8..ce28150e0464a 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -426,12 +426,13 @@ static void raid10_end_read_request(struct bio *bio) static void close_write(struct r10bio *r10_bio) { + struct mddev *mddev = r10_bio->mddev; + /* clear the bitmap if all writes complete successfully */ - md_bitmap_endwrite(r10_bio->mddev->bitmap, r10_bio->sector, - r10_bio->sectors, - !test_bit(R10BIO_Degraded, &r10_bio->state), - 0); - md_write_end(r10_bio->mddev); + mddev->bitmap_ops->endwrite(mddev, r10_bio->sector, r10_bio->sectors, + !test_bit(R10BIO_Degraded, &r10_bio->state), + false); + md_write_end(mddev); } static void one_write_done(struct r10bio *r10_bio) diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c index 874874fe4fa12..23f2cbcf1a6c4 100644 --- a/drivers/md/raid5-cache.c +++ b/drivers/md/raid5-cache.c @@ -313,10 +313,10 @@ void r5c_handle_cached_data_endio(struct r5conf *conf, if (sh->dev[i].written) { set_bit(R5_UPTODATE, &sh->dev[i].flags); r5c_return_dev_pending_writes(conf, &sh->dev[i]); - md_bitmap_endwrite(conf->mddev->bitmap, sh->sector, - RAID5_STRIPE_SECTORS(conf), - !test_bit(STRIPE_DEGRADED, &sh->state), - 0); + conf->mddev->bitmap_ops->endwrite(conf->mddev, + sh->sector, RAID5_STRIPE_SECTORS(conf), + !test_bit(STRIPE_DEGRADED, &sh->state), + false); } } } diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index c24036d1e6dad..93d582b9f922e 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3663,8 +3663,9 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh, bi = nextbi; } if (bitmap_end) - md_bitmap_endwrite(conf->mddev->bitmap, sh->sector, - RAID5_STRIPE_SECTORS(conf), 0, 0); + conf->mddev->bitmap_ops->endwrite(conf->mddev, + sh->sector, RAID5_STRIPE_SECTORS(conf), + false, false); bitmap_end = 0; /* and fail all 'written' */ bi = sh->dev[i].written; @@ -3709,8 +3710,9 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh, } } if (bitmap_end) - md_bitmap_endwrite(conf->mddev->bitmap, sh->sector, - RAID5_STRIPE_SECTORS(conf), 0, 0); + conf->mddev->bitmap_ops->endwrite(conf->mddev, + sh->sector, RAID5_STRIPE_SECTORS(conf), + false, false); /* If we were in the middle of a write the parity block might * still be locked - so just clear all R5_LOCKED flags */ @@ -4059,10 +4061,10 @@ static void handle_stripe_clean_event(struct r5conf *conf, bio_endio(wbi); wbi = wbi2; } - md_bitmap_endwrite(conf->mddev->bitmap, sh->sector, - RAID5_STRIPE_SECTORS(conf), - !test_bit(STRIPE_DEGRADED, &sh->state), - 0); + conf->mddev->bitmap_ops->endwrite(conf->mddev, + sh->sector, RAID5_STRIPE_SECTORS(conf), + !test_bit(STRIPE_DEGRADED, &sh->state), + false); if (head_sh->batch_head) { sh = list_first_entry(&sh->batch_list, struct stripe_head, From fe6a19d40ceb44281905485f56dda715e3214e0e Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:35 +0800 Subject: [PATCH 25/42] md/md-bitmap: merge md_bitmap_start_sync() into bitmap_operations So that the implementation won't be exposed, and it'll be possible to invent a new bitmap by replacing bitmap_operations. Also change the parameter from bitmap to mddev, to avoid access bitmap outside md-bitmap.c as much as possible. Also fix lots of code style. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-26-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 36 ++++++++++++++++++++---------------- drivers/md/md-bitmap.h | 3 ++- drivers/md/raid1.c | 10 +++++----- drivers/md/raid10.c | 22 ++++++++++++---------- drivers/md/raid5.c | 10 ++++++---- 5 files changed, 45 insertions(+), 36 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 4d174ab253398..57a4bae50e9cf 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -1579,24 +1579,26 @@ static void bitmap_endwrite(struct mddev *mddev, sector_t offset, } } -static int __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, - int degraded) +static bool __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, + sector_t *blocks, bool degraded) { bitmap_counter_t *bmc; - int rv; + bool rv; + if (bitmap == NULL) {/* FIXME or bitmap set as 'failed' */ *blocks = 1024; - return 1; /* always resync if no bitmap */ + 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); - rv = 0; if (bmc) { /* locked */ - if (RESYNC(*bmc)) - rv = 1; - else if (NEEDED(*bmc)) { - rv = 1; + if (RESYNC(*bmc)) { + rv = true; + } else if (NEEDED(*bmc)) { + rv = true; if (!degraded) { /* don't set/clear bits if degraded */ *bmc |= RESYNC_MASK; *bmc &= ~NEEDED_MASK; @@ -1604,11 +1606,12 @@ static int __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t } } spin_unlock_irq(&bitmap->counts.lock); + return rv; } -int md_bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, - int degraded) +static bool bitmap_start_sync(struct mddev *mddev, sector_t offset, + sector_t *blocks, bool degraded) { /* bitmap_start_sync must always report on multiples of whole * pages, otherwise resync (which is very PAGE_SIZE based) will @@ -1617,19 +1620,19 @@ int md_bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *block * At least PAGE_SIZE>>9 blocks are covered. * Return the 'or' of the result. */ - int rv = 0; + bool rv = false; sector_t blocks1; *blocks = 0; while (*blocks < (PAGE_SIZE>>9)) { - rv |= __bitmap_start_sync(bitmap, offset, + rv |= __bitmap_start_sync(mddev->bitmap, offset, &blocks1, degraded); offset += blocks1; *blocks += blocks1; } + return rv; } -EXPORT_SYMBOL(md_bitmap_start_sync); void md_bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int aborted) { @@ -1723,7 +1726,7 @@ void md_bitmap_sync_with_cluster(struct mddev *mddev, WARN((blocks > new_lo) && old_lo, "alignment is not correct for lo\n"); for (sector = old_hi; sector < new_hi; ) { - md_bitmap_start_sync(bitmap, sector, &blocks, 0); + bitmap_start_sync(mddev, sector, &blocks, false); sector += blocks; } WARN((blocks > new_hi) && old_hi, "alignment is not correct for hi\n"); @@ -2005,7 +2008,7 @@ static int bitmap_load(struct mddev *mddev) */ while (sector < mddev->resync_max_sectors) { sector_t blocks; - md_bitmap_start_sync(bitmap, sector, &blocks, 0); + bitmap_start_sync(mddev, sector, &blocks, false); sector += blocks; } md_bitmap_close_sync(bitmap); @@ -2734,6 +2737,7 @@ static struct bitmap_operations bitmap_ops = { .startwrite = bitmap_startwrite, .endwrite = bitmap_endwrite, + .start_sync = bitmap_start_sync, .update_sb = bitmap_update_sb, .get_stats = bitmap_get_stats, diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index 056a80ee500f5..67c8f22e8726d 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -259,6 +259,8 @@ struct bitmap_operations { unsigned long sectors, bool behind); void (*endwrite)(struct mddev *mddev, sector_t offset, unsigned long sectors, bool success, bool behind); + bool (*start_sync)(struct mddev *mddev, sector_t offset, + sector_t *blocks, bool degraded); void (*update_sb)(struct bitmap *bitmap); int (*get_stats)(struct bitmap *bitmap, struct md_bitmap_stats *stats); @@ -268,7 +270,6 @@ struct bitmap_operations { void mddev_set_bitmap_ops(struct mddev *mddev); /* these are exported */ -int md_bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int degraded); void md_bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int aborted); void md_bitmap_close_sync(struct bitmap *bitmap); void md_bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector, bool force); diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index b335293ec4728..8b83dd83e15f9 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -2755,7 +2755,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr, int wonly = -1; int write_targets = 0, read_targets = 0; sector_t sync_blocks; - int still_degraded = 0; + bool still_degraded = false; int good_sectors = RESYNC_SECTORS; int min_bad = 0; /* number of sectors that are bad in all devices */ int idx = sector_to_idx(sector_nr); @@ -2797,7 +2797,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 (!md_bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) && + if (!mddev->bitmap_ops->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; @@ -2848,7 +2848,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr, if (rdev == NULL || test_bit(Faulty, &rdev->flags)) { if (i < conf->raid_disks) - still_degraded = 1; + still_degraded = true; } else if (!test_bit(In_sync, &rdev->flags)) { bio->bi_opf = REQ_OP_WRITE; bio->bi_end_io = end_sync_write; @@ -2972,8 +2972,8 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr, if (len == 0) break; if (sync_blocks == 0) { - if (!md_bitmap_start_sync(mddev->bitmap, sector_nr, - &sync_blocks, still_degraded) && + if (!mddev->bitmap_ops->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 ce28150e0464a..d88878741ed47 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -3289,10 +3289,10 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr, r10_bio = NULL; for (i = 0 ; i < conf->geo.raid_disks; i++) { - int still_degraded; + bool still_degraded; struct r10bio *rb2; sector_t sect; - int must_sync; + bool must_sync; int any_working; struct raid10_info *mirror = &conf->mirrors[i]; struct md_rdev *mrdev, *mreplace; @@ -3309,7 +3309,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr, if (!mrdev && !mreplace) continue; - still_degraded = 0; + still_degraded = false; /* want to reconstruct this device */ rb2 = r10_bio; sect = raid10_find_virt(conf, sector_nr, i); @@ -3322,8 +3322,9 @@ 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 = md_bitmap_start_sync(mddev->bitmap, sect, - &sync_blocks, 1); + must_sync = mddev->bitmap_ops->start_sync(mddev, sect, + &sync_blocks, + true); if (sync_blocks < max_sync) max_sync = sync_blocks; if (!must_sync && @@ -3361,13 +3362,13 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr, struct md_rdev *rdev = conf->mirrors[j].rdev; if (rdev == NULL || test_bit(Faulty, &rdev->flags)) { - still_degraded = 1; + still_degraded = false; break; } } - must_sync = md_bitmap_start_sync(mddev->bitmap, sect, - &sync_blocks, still_degraded); + must_sync = mddev->bitmap_ops->start_sync(mddev, sect, + &sync_blocks, still_degraded); any_working = 0; for (j=0; jcopies;j++) { @@ -3544,8 +3545,9 @@ 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 (!md_bitmap_start_sync(mddev->bitmap, sector_nr, - &sync_blocks, mddev->degraded) && + if (!mddev->bitmap_ops->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 93d582b9f922e..313904dd6555b 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -6485,7 +6485,7 @@ static inline sector_t raid5_sync_request(struct mddev *mddev, sector_t sector_n struct r5conf *conf = mddev->private; struct stripe_head *sh; sector_t sync_blocks; - int still_degraded = 0; + bool still_degraded = false; int i; if (sector_nr >= max_sector) { @@ -6530,7 +6530,8 @@ static inline sector_t raid5_sync_request(struct mddev *mddev, sector_t sector_n } if (!test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) && !conf->fullsync && - !md_bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) && + !mddev->bitmap_ops->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)); @@ -6558,10 +6559,11 @@ static inline sector_t raid5_sync_request(struct mddev *mddev, sector_t sector_n struct md_rdev *rdev = conf->disks[i].rdev; if (rdev == NULL || test_bit(Faulty, &rdev->flags)) - still_degraded = 1; + still_degraded = true; } - md_bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, still_degraded); + mddev->bitmap_ops->start_sync(mddev, sector_nr, &sync_blocks, + still_degraded); set_bit(STRIPE_SYNC_REQUESTED, &sh->state); set_bit(STRIPE_HANDLE, &sh->state); From 9be669bd1b031f40b35034223517cf886e7a7fcc Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:36 +0800 Subject: [PATCH 26/42] md/md-bitmap: remove the parameter 'aborted' for md_bitmap_end_sync() For internal callers, aborted are always set to false, while for external callers, aborted are always set to true. Hence there is no need to always pass in true for exported api. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-27-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 15 +++++++++++---- drivers/md/md-bitmap.h | 3 ++- drivers/md/raid1.c | 4 ++-- drivers/md/raid10.c | 4 ++-- drivers/md/raid5.c | 2 +- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 57a4bae50e9cf..7e810fc2852e0 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -1634,7 +1634,8 @@ static bool bitmap_start_sync(struct mddev *mddev, sector_t offset, return rv; } -void md_bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int aborted) +static void __bitmap_end_sync(struct bitmap *bitmap, sector_t offset, + sector_t *blocks, bool aborted) { bitmap_counter_t *bmc; unsigned long flags; @@ -1663,6 +1664,12 @@ void md_bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks unlock: spin_unlock_irqrestore(&bitmap->counts.lock, flags); } + +void md_bitmap_end_sync(struct bitmap *bitmap, sector_t offset, + sector_t *blocks) +{ + __bitmap_end_sync(bitmap, offset, blocks, true); +} EXPORT_SYMBOL(md_bitmap_end_sync); void md_bitmap_close_sync(struct bitmap *bitmap) @@ -1676,7 +1683,7 @@ void md_bitmap_close_sync(struct bitmap *bitmap) if (!bitmap) return; while (sector < bitmap->mddev->resync_max_sectors) { - md_bitmap_end_sync(bitmap, sector, &blocks, 0); + __bitmap_end_sync(bitmap, sector, &blocks, false); sector += blocks; } } @@ -1704,7 +1711,7 @@ void md_bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector, bool force) sector &= ~((1ULL << bitmap->counts.chunkshift) - 1); s = 0; while (s < sector && s < bitmap->mddev->resync_max_sectors) { - md_bitmap_end_sync(bitmap, s, &blocks, 0); + __bitmap_end_sync(bitmap, s, &blocks, false); s += blocks; } bitmap->last_end_sync = jiffies; @@ -1720,7 +1727,7 @@ void md_bitmap_sync_with_cluster(struct mddev *mddev, sector_t sector, blocks = 0; for (sector = old_lo; sector < new_lo; ) { - md_bitmap_end_sync(bitmap, sector, &blocks, 0); + __bitmap_end_sync(bitmap, sector, &blocks, false); sector += blocks; } WARN((blocks > new_lo) && old_lo, "alignment is not correct for lo\n"); diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index 67c8f22e8726d..6691524bdc80d 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -270,7 +270,8 @@ struct bitmap_operations { void mddev_set_bitmap_ops(struct mddev *mddev); /* these are exported */ -void md_bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int aborted); +void md_bitmap_end_sync(struct bitmap *bitmap, sector_t offset, + sector_t *blocks); void md_bitmap_close_sync(struct bitmap *bitmap); void md_bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector, bool force); void md_bitmap_sync_with_cluster(struct mddev *mddev, diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 8b83dd83e15f9..5ee929c89cb1f 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -2026,7 +2026,7 @@ static void abort_sync_write(struct mddev *mddev, struct r1bio *r1_bio) /* make sure these bits don't get cleared. */ do { - md_bitmap_end_sync(mddev->bitmap, s, &sync_blocks, 1); + md_bitmap_end_sync(mddev->bitmap, s, &sync_blocks); s += sync_blocks; sectors_to_go -= sync_blocks; } while (sectors_to_go > 0); @@ -2773,7 +2773,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr, */ if (mddev->curr_resync < max_sector) /* aborted */ md_bitmap_end_sync(mddev->bitmap, mddev->curr_resync, - &sync_blocks, 1); + &sync_blocks); else /* completed sync */ conf->fullsync = 0; diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index d88878741ed47..33372d30fa99a 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -3195,12 +3195,12 @@ 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)) md_bitmap_end_sync(mddev->bitmap, mddev->curr_resync, - &sync_blocks, 1); + &sync_blocks); else for (i = 0; i < conf->geo.raid_disks; i++) { sector_t sect = raid10_find_virt(conf, mddev->curr_resync, i); md_bitmap_end_sync(mddev->bitmap, sect, - &sync_blocks, 1); + &sync_blocks); } } else { /* completed sync */ diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 313904dd6555b..3e9fed1e11536 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -6498,7 +6498,7 @@ static inline sector_t raid5_sync_request(struct mddev *mddev, sector_t sector_n if (mddev->curr_resync < max_sector) /* aborted */ md_bitmap_end_sync(mddev->bitmap, mddev->curr_resync, - &sync_blocks, 1); + &sync_blocks); else /* completed sync */ conf->fullsync = 0; md_bitmap_close_sync(mddev->bitmap); From 1415f402e1a1e6054377ed15f249589204cfb8b7 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:37 +0800 Subject: [PATCH 27/42] md/md-bitmap: merge md_bitmap_end_sync() into bitmap_operations So that the implementation won't be exposed, and it'll be possible to invent a new bitmap by replacing bitmap_operations. Also change the parameter from bitmap to mddev, to avoid access bitmap outside md-bitmap.c as much as possible. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-28-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 8 ++++---- drivers/md/md-bitmap.h | 3 +-- drivers/md/raid1.c | 6 +++--- drivers/md/raid10.c | 10 ++++++---- drivers/md/raid5.c | 4 ++-- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 7e810fc2852e0..8aef907da1581 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -1665,12 +1665,11 @@ static void __bitmap_end_sync(struct bitmap *bitmap, sector_t offset, spin_unlock_irqrestore(&bitmap->counts.lock, flags); } -void md_bitmap_end_sync(struct bitmap *bitmap, sector_t offset, - sector_t *blocks) +static void bitmap_end_sync(struct mddev *mddev, sector_t offset, + sector_t *blocks) { - __bitmap_end_sync(bitmap, offset, blocks, true); + __bitmap_end_sync(mddev->bitmap, offset, blocks, true); } -EXPORT_SYMBOL(md_bitmap_end_sync); void md_bitmap_close_sync(struct bitmap *bitmap) { @@ -2745,6 +2744,7 @@ static struct bitmap_operations bitmap_ops = { .startwrite = bitmap_startwrite, .endwrite = bitmap_endwrite, .start_sync = bitmap_start_sync, + .end_sync = bitmap_end_sync, .update_sb = bitmap_update_sb, .get_stats = bitmap_get_stats, diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index 6691524bdc80d..d6f2d5979da4d 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -261,6 +261,7 @@ struct bitmap_operations { unsigned long sectors, bool success, bool behind); bool (*start_sync)(struct mddev *mddev, sector_t offset, sector_t *blocks, bool degraded); + void (*end_sync)(struct mddev *mddev, sector_t offset, sector_t *blocks); void (*update_sb)(struct bitmap *bitmap); int (*get_stats)(struct bitmap *bitmap, struct md_bitmap_stats *stats); @@ -270,8 +271,6 @@ struct bitmap_operations { void mddev_set_bitmap_ops(struct mddev *mddev); /* these are exported */ -void md_bitmap_end_sync(struct bitmap *bitmap, sector_t offset, - sector_t *blocks); void md_bitmap_close_sync(struct bitmap *bitmap); void md_bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector, bool force); void md_bitmap_sync_with_cluster(struct mddev *mddev, diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 5ee929c89cb1f..b50ba80742811 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -2026,7 +2026,7 @@ static void abort_sync_write(struct mddev *mddev, struct r1bio *r1_bio) /* make sure these bits don't get cleared. */ do { - md_bitmap_end_sync(mddev->bitmap, s, &sync_blocks); + mddev->bitmap_ops->end_sync(mddev, s, &sync_blocks); s += sync_blocks; sectors_to_go -= sync_blocks; } while (sectors_to_go > 0); @@ -2772,8 +2772,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 */ - md_bitmap_end_sync(mddev->bitmap, mddev->curr_resync, - &sync_blocks); + mddev->bitmap_ops->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 33372d30fa99a..15299a7774a06 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -3194,13 +3194,15 @@ 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)) - md_bitmap_end_sync(mddev->bitmap, mddev->curr_resync, - &sync_blocks); + mddev->bitmap_ops->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); - md_bitmap_end_sync(mddev->bitmap, sect, - &sync_blocks); + + mddev->bitmap_ops->end_sync(mddev, sect, + &sync_blocks); } } else { /* completed sync */ diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 3e9fed1e11536..89ae149bf28e5 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -6497,8 +6497,8 @@ static inline sector_t raid5_sync_request(struct mddev *mddev, sector_t sector_n } if (mddev->curr_resync < max_sector) /* aborted */ - md_bitmap_end_sync(mddev->bitmap, mddev->curr_resync, - &sync_blocks); + mddev->bitmap_ops->end_sync(mddev, mddev->curr_resync, + &sync_blocks); else /* completed sync */ conf->fullsync = 0; md_bitmap_close_sync(mddev->bitmap); From 077b18abde12f27da9776563413bbad4918ecb52 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:38 +0800 Subject: [PATCH 28/42] md/md-bitmap: merge md_bitmap_close_sync() into bitmap_operations So that the implementation won't be exposed, and it'll be possible to invent a new bitmap by replacing bitmap_operations. Also change the parameter from bitmap to mddev, to avoid access bitmap outside md-bitmap.c as much as possible. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-29-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 9 ++++++--- drivers/md/md-bitmap.h | 2 +- drivers/md/raid1.c | 2 +- drivers/md/raid10.c | 2 +- drivers/md/raid5.c | 2 +- 5 files changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 8aef907da1581..e1dceff2d9a5c 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -1671,7 +1671,7 @@ static void bitmap_end_sync(struct mddev *mddev, sector_t offset, __bitmap_end_sync(mddev->bitmap, offset, blocks, true); } -void md_bitmap_close_sync(struct bitmap *bitmap) +static void bitmap_close_sync(struct mddev *mddev) { /* Sync has finished, and any bitmap chunks that weren't synced * properly have been aborted. It remains to us to clear the @@ -1679,14 +1679,16 @@ void md_bitmap_close_sync(struct bitmap *bitmap) */ sector_t sector = 0; sector_t blocks; + struct bitmap *bitmap = mddev->bitmap; + if (!bitmap) return; + while (sector < bitmap->mddev->resync_max_sectors) { __bitmap_end_sync(bitmap, sector, &blocks, false); sector += blocks; } } -EXPORT_SYMBOL(md_bitmap_close_sync); void md_bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector, bool force) { @@ -2017,7 +2019,7 @@ static int bitmap_load(struct mddev *mddev) bitmap_start_sync(mddev, sector, &blocks, false); sector += blocks; } - md_bitmap_close_sync(bitmap); + bitmap_close_sync(mddev); if (mddev->degraded == 0 || bitmap->events_cleared == mddev->events) @@ -2745,6 +2747,7 @@ static struct bitmap_operations bitmap_ops = { .endwrite = bitmap_endwrite, .start_sync = bitmap_start_sync, .end_sync = bitmap_end_sync, + .close_sync = bitmap_close_sync, .update_sb = bitmap_update_sb, .get_stats = bitmap_get_stats, diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index d6f2d5979da4d..5d919b5303176 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -262,6 +262,7 @@ struct bitmap_operations { bool (*start_sync)(struct mddev *mddev, sector_t offset, sector_t *blocks, bool degraded); void (*end_sync)(struct mddev *mddev, sector_t offset, sector_t *blocks); + void (*close_sync)(struct mddev *mddev); void (*update_sb)(struct bitmap *bitmap); int (*get_stats)(struct bitmap *bitmap, struct md_bitmap_stats *stats); @@ -271,7 +272,6 @@ struct bitmap_operations { void mddev_set_bitmap_ops(struct mddev *mddev); /* these are exported */ -void md_bitmap_close_sync(struct bitmap *bitmap); void md_bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector, bool force); void md_bitmap_sync_with_cluster(struct mddev *mddev, sector_t old_lo, sector_t old_hi, diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index b50ba80742811..a6757c9a28940 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -2777,7 +2777,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr, else /* completed sync */ conf->fullsync = 0; - md_bitmap_close_sync(mddev->bitmap); + mddev->bitmap_ops->close_sync(mddev); close_sync(conf); if (mddev_is_clustered(mddev)) { diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 15299a7774a06..5b1c86c368b19 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -3222,7 +3222,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr, } conf->fullsync = 0; } - md_bitmap_close_sync(mddev->bitmap); + mddev->bitmap_ops->close_sync(mddev); close_sync(conf); *skipped = 1; return sectors_skipped; diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 89ae149bf28e5..d2b8d2517abf8 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -6501,7 +6501,7 @@ static inline sector_t raid5_sync_request(struct mddev *mddev, sector_t sector_n &sync_blocks); else /* completed sync */ conf->fullsync = 0; - md_bitmap_close_sync(mddev->bitmap); + mddev->bitmap_ops->close_sync(mddev); return 0; } From 15db1eca63bd954997058edc1563223d7b525003 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:39 +0800 Subject: [PATCH 29/42] md/md-bitmap: merge md_bitmap_cond_end_sync() into bitmap_operations So that the implementation won't be exposed, and it'll be possible to invent a new bitmap by replacing bitmap_operations. Also change the parameter from bitmap to mddev, to avoid access bitmap outside md-bitmap.c as much as possible. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-30-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 6 ++++-- drivers/md/md-bitmap.h | 2 +- drivers/md/raid1.c | 6 +++--- drivers/md/raid10.c | 2 +- drivers/md/raid5.c | 2 +- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index e1dceff2d9a5c..2d9d9689f7212 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -1690,10 +1690,12 @@ static void bitmap_close_sync(struct mddev *mddev) } } -void md_bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector, bool force) +static void bitmap_cond_end_sync(struct mddev *mddev, sector_t sector, + bool force) { sector_t s = 0; sector_t blocks; + struct bitmap *bitmap = mddev->bitmap; if (!bitmap) return; @@ -1718,7 +1720,6 @@ void md_bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector, bool force) bitmap->last_end_sync = jiffies; sysfs_notify_dirent_safe(bitmap->mddev->sysfs_completed); } -EXPORT_SYMBOL(md_bitmap_cond_end_sync); void md_bitmap_sync_with_cluster(struct mddev *mddev, sector_t old_lo, sector_t old_hi, @@ -2747,6 +2748,7 @@ static struct bitmap_operations bitmap_ops = { .endwrite = bitmap_endwrite, .start_sync = bitmap_start_sync, .end_sync = bitmap_end_sync, + .cond_end_sync = bitmap_cond_end_sync, .close_sync = bitmap_close_sync, .update_sb = bitmap_update_sb, diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index 5d919b5303176..027de097f96a9 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -262,6 +262,7 @@ struct bitmap_operations { bool (*start_sync)(struct mddev *mddev, sector_t offset, sector_t *blocks, bool degraded); void (*end_sync)(struct mddev *mddev, sector_t offset, sector_t *blocks); + void (*cond_end_sync)(struct mddev *mddev, sector_t sector, bool force); void (*close_sync)(struct mddev *mddev); void (*update_sb)(struct bitmap *bitmap); @@ -272,7 +273,6 @@ struct bitmap_operations { void mddev_set_bitmap_ops(struct mddev *mddev); /* these are exported */ -void md_bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector, bool force); void md_bitmap_sync_with_cluster(struct mddev *mddev, sector_t old_lo, sector_t old_hi, sector_t new_lo, sector_t new_hi); diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index a6757c9a28940..119c9477a453c 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -2815,9 +2815,9 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr, * sector_nr + two times RESYNC_SECTORS */ - md_bitmap_cond_end_sync(mddev->bitmap, sector_nr, - mddev_is_clustered(mddev) && (sector_nr + 2 * RESYNC_SECTORS > conf->cluster_sync_high)); - + 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; diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 5b1c86c368b19..5a7b19f48c45a 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -3543,7 +3543,7 @@ 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. */ - md_bitmap_cond_end_sync(mddev->bitmap, sector_nr, + mddev->bitmap_ops->cond_end_sync(mddev, sector_nr, mddev_is_clustered(mddev) && (sector_nr + 2 * RESYNC_SECTORS > conf->cluster_sync_high)); diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index d2b8d2517abf8..87b8d19ab6014 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -6540,7 +6540,7 @@ static inline sector_t raid5_sync_request(struct mddev *mddev, sector_t sector_n return sync_blocks * RAID5_STRIPE_SECTORS(conf); } - md_bitmap_cond_end_sync(mddev->bitmap, sector_nr, false); + mddev->bitmap_ops->cond_end_sync(mddev, sector_nr, false); sh = raid5_get_active_stripe(conf, NULL, sector_nr, R5_GAS_NOBLOCK); From 4338b94271dd8cee8ce3b662b12528cd009325a3 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:40 +0800 Subject: [PATCH 30/42] md/md-bitmap: merge md_bitmap_sync_with_cluster() into bitmap_operations So that the implementation won't be exposed, and it'll be possible to invent a new bitmap by replacing bitmap_operations. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-31-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 9 +++++---- drivers/md/md-bitmap.h | 8 ++++---- drivers/md/md-cluster.c | 4 ++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 2d9d9689f7212..9fe97f14a7198 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -1721,9 +1721,9 @@ static void bitmap_cond_end_sync(struct mddev *mddev, sector_t sector, sysfs_notify_dirent_safe(bitmap->mddev->sysfs_completed); } -void md_bitmap_sync_with_cluster(struct mddev *mddev, - sector_t old_lo, sector_t old_hi, - sector_t new_lo, sector_t new_hi) +static void bitmap_sync_with_cluster(struct mddev *mddev, + sector_t old_lo, sector_t old_hi, + sector_t new_lo, sector_t new_hi) { struct bitmap *bitmap = mddev->bitmap; sector_t sector, blocks = 0; @@ -1740,7 +1740,6 @@ void md_bitmap_sync_with_cluster(struct mddev *mddev, } WARN((blocks > new_hi) && old_hi, "alignment is not correct for hi\n"); } -EXPORT_SYMBOL(md_bitmap_sync_with_cluster); static void md_bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed) { @@ -2753,6 +2752,8 @@ static struct bitmap_operations bitmap_ops = { .update_sb = bitmap_update_sb, .get_stats = bitmap_get_stats, + + .sync_with_cluster = bitmap_sync_with_cluster, }; void mddev_set_bitmap_ops(struct mddev *mddev) diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index 027de097f96a9..0953ac73735c7 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -267,16 +267,16 @@ struct bitmap_operations { void (*update_sb)(struct bitmap *bitmap); int (*get_stats)(struct bitmap *bitmap, struct md_bitmap_stats *stats); + + void (*sync_with_cluster)(struct mddev *mddev, + sector_t old_lo, sector_t old_hi, + sector_t new_lo, sector_t new_hi); }; /* the bitmap API */ void mddev_set_bitmap_ops(struct mddev *mddev); /* these are exported */ -void md_bitmap_sync_with_cluster(struct mddev *mddev, - sector_t old_lo, sector_t old_hi, - sector_t new_lo, sector_t new_hi); - void md_bitmap_unplug(struct bitmap *bitmap); void md_bitmap_unplug_async(struct bitmap *bitmap); void md_bitmap_daemon_work(struct mddev *mddev); diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index a5f1135cc1fa9..55feabe14ad3a 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -497,8 +497,8 @@ static void process_suspend_info(struct mddev *mddev, * we don't want to trigger lots of WARN. */ if (sb && !(le32_to_cpu(sb->feature_map) & MD_FEATURE_RESHAPE_ACTIVE)) - md_bitmap_sync_with_cluster(mddev, cinfo->sync_low, - cinfo->sync_hi, lo, hi); + mddev->bitmap_ops->sync_with_cluster(mddev, cinfo->sync_low, + cinfo->sync_hi, lo, hi); cinfo->sync_low = lo; cinfo->sync_hi = hi; From 48eb95810a9241afd871de917d70712e2ddfda31 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:41 +0800 Subject: [PATCH 31/42] md/md-bitmap: merge md_bitmap_unplug_async() into md_bitmap_unplug() Add a parameter 'bool sync' to distinguish them, and md_bitmap_unplug_async() won't be exported anymore, hence bitmap_operations only need one op to cover them. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-32-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 28 ++++++++++++++++++++-------- drivers/md/md-bitmap.h | 3 +-- drivers/md/md.c | 2 +- drivers/md/raid1-10.c | 7 ++----- drivers/md/raid1.c | 2 +- drivers/md/raid10.c | 4 ++-- drivers/md/raid5.c | 2 +- 7 files changed, 28 insertions(+), 20 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 9fe97f14a7198..ecfc3a02a9760 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -1026,7 +1026,7 @@ static int md_bitmap_file_test_bit(struct bitmap *bitmap, sector_t block) /* this gets called when the md device is ready to unplug its underlying * (slave) device queues -- before we let any writes go down, we need to * sync the dirty pages of the bitmap file to disk */ -void md_bitmap_unplug(struct bitmap *bitmap) +static void __bitmap_unplug(struct bitmap *bitmap) { unsigned long i; int dirty, need_write; @@ -1058,7 +1058,6 @@ void md_bitmap_unplug(struct bitmap *bitmap) if (test_bit(BITMAP_WRITE_ERROR, &bitmap->flags)) md_bitmap_file_kick(bitmap); } -EXPORT_SYMBOL(md_bitmap_unplug); struct bitmap_unplug_work { struct work_struct work; @@ -1071,11 +1070,11 @@ static void md_bitmap_unplug_fn(struct work_struct *work) struct bitmap_unplug_work *unplug_work = container_of(work, struct bitmap_unplug_work, work); - md_bitmap_unplug(unplug_work->bitmap); + __bitmap_unplug(unplug_work->bitmap); complete(unplug_work->done); } -void md_bitmap_unplug_async(struct bitmap *bitmap) +static void bitmap_unplug_async(struct bitmap *bitmap) { DECLARE_COMPLETION_ONSTACK(done); struct bitmap_unplug_work unplug_work; @@ -1087,7 +1086,20 @@ void md_bitmap_unplug_async(struct bitmap *bitmap) queue_work(md_bitmap_wq, &unplug_work.work); wait_for_completion(&done); } -EXPORT_SYMBOL(md_bitmap_unplug_async); + +void md_bitmap_unplug(struct mddev *mddev, bool sync) +{ + struct bitmap *bitmap = mddev->bitmap; + + if (!bitmap) + return; + + if (sync) + __bitmap_unplug(bitmap); + else + bitmap_unplug_async(bitmap); +} +EXPORT_SYMBOL_GPL(md_bitmap_unplug); static void md_bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed); @@ -2108,9 +2120,9 @@ int md_bitmap_copy_from_slot(struct mddev *mddev, int slot, for (i = 0; i < bitmap->storage.file_pages; i++) if (test_page_attr(bitmap, i, BITMAP_PAGE_PENDING)) set_page_attr(bitmap, i, BITMAP_PAGE_NEEDWRITE); - md_bitmap_unplug(bitmap); + __bitmap_unplug(bitmap); } - md_bitmap_unplug(mddev->bitmap); + __bitmap_unplug(mddev->bitmap); *low = lo; *high = hi; md_bitmap_free(bitmap); @@ -2351,7 +2363,7 @@ int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks, spin_unlock_irq(&bitmap->counts.lock); if (!init) { - md_bitmap_unplug(bitmap); + __bitmap_unplug(bitmap); bitmap->mddev->pers->quiesce(bitmap->mddev, 0); } ret = 0; diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index 0953ac73735c7..ba8ba7e49ef9e 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -277,8 +277,7 @@ struct bitmap_operations { void mddev_set_bitmap_ops(struct mddev *mddev); /* these are exported */ -void md_bitmap_unplug(struct bitmap *bitmap); -void md_bitmap_unplug_async(struct bitmap *bitmap); +void md_bitmap_unplug(struct mddev *mddev, bool sync); void md_bitmap_daemon_work(struct mddev *mddev); int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks, diff --git a/drivers/md/md.c b/drivers/md/md.c index f72fa8e872f81..b3bc0c76aeb88 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -4715,7 +4715,7 @@ bitmap_store(struct mddev *mddev, const char *buf, size_t len) mddev->bitmap_ops->dirty_bits(mddev, chunk, end_chunk); buf = skip_spaces(end); } - md_bitmap_unplug(mddev->bitmap); /* flush the bits to disk */ + md_bitmap_unplug(mddev, true); /* flush the bits to disk */ out: mddev_unlock(mddev); return len; diff --git a/drivers/md/raid1-10.c b/drivers/md/raid1-10.c index 2ea1710a3b705..45b30f08f3a50 100644 --- a/drivers/md/raid1-10.c +++ b/drivers/md/raid1-10.c @@ -166,12 +166,9 @@ static inline bool raid1_add_bio_to_plug(struct mddev *mddev, struct bio *bio, * while current io submission must wait for bitmap io to be done. In order to * avoid such deadlock, submit bitmap io asynchronously. */ -static inline void raid1_prepare_flush_writes(struct bitmap *bitmap) +static inline void raid1_prepare_flush_writes(struct mddev *mddev) { - if (current->bio_list) - md_bitmap_unplug_async(bitmap); - else - md_bitmap_unplug(bitmap); + md_bitmap_unplug(mddev, current->bio_list == NULL); } /* diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 119c9477a453c..f9338756088aa 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -896,7 +896,7 @@ static void wake_up_barrier(struct r1conf *conf) static void flush_bio_list(struct r1conf *conf, struct bio *bio) { /* flush any pending bitmap writes to disk before proceeding w/ I/O */ - raid1_prepare_flush_writes(conf->mddev->bitmap); + raid1_prepare_flush_writes(conf->mddev); wake_up_barrier(conf); while (bio) { /* submit pending writes */ diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 5a7b19f48c45a..c79f374668dde 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -885,7 +885,7 @@ static void flush_pending_writes(struct r10conf *conf) __set_current_state(TASK_RUNNING); blk_start_plug(&plug); - raid1_prepare_flush_writes(conf->mddev->bitmap); + raid1_prepare_flush_writes(conf->mddev); wake_up(&conf->wait_barrier); while (bio) { /* submit pending writes */ @@ -1101,7 +1101,7 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule) /* we aren't scheduling, so we can do the write-out directly. */ bio = bio_list_get(&plug->pending); - raid1_prepare_flush_writes(mddev->bitmap); + raid1_prepare_flush_writes(mddev); wake_up_barrier(conf); while (bio) { /* submit pending writes */ diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 87b8d19ab6014..e98061c01b44a 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -6768,7 +6768,7 @@ 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); - md_bitmap_unplug(mddev->bitmap); + md_bitmap_unplug(mddev, true); spin_lock_irq(&conf->device_lock); conf->seq_write = conf->seq_flush; activate_bit_delay(conf, conf->temp_inactive_list); From 3c9883e77a36ca76b8d92afa99599263ca587ae7 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:42 +0800 Subject: [PATCH 32/42] md/md-bitmap: merge bitmap_unplug() into bitmap_operations So that the implementation won't be exposed, and it'll be possible to invent a new bitmap by replacing bitmap_operations. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-33-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 4 ++-- drivers/md/md-bitmap.h | 2 +- drivers/md/md.c | 2 +- drivers/md/raid1-10.c | 2 +- drivers/md/raid5.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index ecfc3a02a9760..4e6e31e364f68 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -1087,7 +1087,7 @@ static void bitmap_unplug_async(struct bitmap *bitmap) wait_for_completion(&done); } -void md_bitmap_unplug(struct mddev *mddev, bool sync) +static void bitmap_unplug(struct mddev *mddev, bool sync) { struct bitmap *bitmap = mddev->bitmap; @@ -1099,7 +1099,6 @@ void md_bitmap_unplug(struct mddev *mddev, bool sync) else bitmap_unplug_async(bitmap); } -EXPORT_SYMBOL_GPL(md_bitmap_unplug); static void md_bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed); @@ -2754,6 +2753,7 @@ static struct bitmap_operations bitmap_ops = { .flush = bitmap_flush, .write_all = bitmap_write_all, .dirty_bits = bitmap_dirty_bits, + .unplug = bitmap_unplug, .startwrite = bitmap_startwrite, .endwrite = bitmap_endwrite, diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index ba8ba7e49ef9e..dbe9b27091f48 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -254,6 +254,7 @@ struct bitmap_operations { void (*write_all)(struct mddev *mddev); void (*dirty_bits)(struct mddev *mddev, unsigned long s, unsigned long e); + void (*unplug)(struct mddev *mddev, bool sync); int (*startwrite)(struct mddev *mddev, sector_t offset, unsigned long sectors, bool behind); @@ -277,7 +278,6 @@ struct bitmap_operations { void mddev_set_bitmap_ops(struct mddev *mddev); /* these are exported */ -void md_bitmap_unplug(struct mddev *mddev, bool sync); void md_bitmap_daemon_work(struct mddev *mddev); int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks, diff --git a/drivers/md/md.c b/drivers/md/md.c index b3bc0c76aeb88..b45d9b6456065 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -4715,7 +4715,7 @@ bitmap_store(struct mddev *mddev, const char *buf, size_t len) mddev->bitmap_ops->dirty_bits(mddev, chunk, end_chunk); buf = skip_spaces(end); } - md_bitmap_unplug(mddev, true); /* flush the bits to disk */ + mddev->bitmap_ops->unplug(mddev, true); /* flush the bits to disk */ out: mddev_unlock(mddev); return len; diff --git a/drivers/md/raid1-10.c b/drivers/md/raid1-10.c index 45b30f08f3a50..e8207513eb1b6 100644 --- a/drivers/md/raid1-10.c +++ b/drivers/md/raid1-10.c @@ -168,7 +168,7 @@ static inline bool raid1_add_bio_to_plug(struct mddev *mddev, struct bio *bio, */ static inline void raid1_prepare_flush_writes(struct mddev *mddev) { - md_bitmap_unplug(mddev, current->bio_list == NULL); + mddev->bitmap_ops->unplug(mddev, current->bio_list == NULL); } /* diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index e98061c01b44a..91b610d11c6a4 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -6768,7 +6768,7 @@ 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); - md_bitmap_unplug(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); From 18db2a9c60aefc61e796f6a384a952999d3b8885 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:43 +0800 Subject: [PATCH 33/42] md/md-bitmap: merge md_bitmap_daemon_work() into bitmap_operations So that the implementation won't be exposed, and it'll be possible to invent a new bitmap by replacing bitmap_operations. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-34-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 9 +++++---- drivers/md/md-bitmap.h | 2 +- drivers/md/md.c | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 4e6e31e364f68..efe928849c94b 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -1298,7 +1298,7 @@ static void mddev_set_timeout(struct mddev *mddev, unsigned long timeout, * bitmap daemon -- periodically wakes up to clean bits and flush pages * out to disk */ -void md_bitmap_daemon_work(struct mddev *mddev) +static void bitmap_daemon_work(struct mddev *mddev) { struct bitmap *bitmap; unsigned long j; @@ -1815,11 +1815,11 @@ static void bitmap_flush(struct mddev *mddev) */ sleep = mddev->bitmap_info.daemon_sleep * 2; bitmap->daemon_lastrun -= sleep; - md_bitmap_daemon_work(mddev); + bitmap_daemon_work(mddev); bitmap->daemon_lastrun -= sleep; - md_bitmap_daemon_work(mddev); + bitmap_daemon_work(mddev); bitmap->daemon_lastrun -= sleep; - md_bitmap_daemon_work(mddev); + bitmap_daemon_work(mddev); if (mddev->bitmap_info.external) md_super_wait(mddev); bitmap_update_sb(bitmap); @@ -2754,6 +2754,7 @@ static struct bitmap_operations bitmap_ops = { .write_all = bitmap_write_all, .dirty_bits = bitmap_dirty_bits, .unplug = bitmap_unplug, + .daemon_work = bitmap_daemon_work, .startwrite = bitmap_startwrite, .endwrite = bitmap_endwrite, diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index dbe9b27091f48..065b36c0c43af 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -255,6 +255,7 @@ struct bitmap_operations { void (*dirty_bits)(struct mddev *mddev, unsigned long s, unsigned long e); void (*unplug)(struct mddev *mddev, bool sync); + void (*daemon_work)(struct mddev *mddev); int (*startwrite)(struct mddev *mddev, sector_t offset, unsigned long sectors, bool behind); @@ -278,7 +279,6 @@ struct bitmap_operations { void mddev_set_bitmap_ops(struct mddev *mddev); /* these are exported */ -void md_bitmap_daemon_work(struct mddev *mddev); int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks, int chunksize, int init); diff --git a/drivers/md/md.c b/drivers/md/md.c index b45d9b6456065..00932bd9b0c8b 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -9638,7 +9638,7 @@ static void unregister_sync_thread(struct mddev *mddev) void md_check_recovery(struct mddev *mddev) { if (mddev->bitmap) - md_bitmap_daemon_work(mddev); + mddev->bitmap_ops->daemon_work(mddev); if (signal_pending(current)) { if (mddev->pers->sync_request && !mddev->external) { From e1791dae6cbd65e5102dca40b8adadef1d89c1b9 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:44 +0800 Subject: [PATCH 34/42] md/md-bitmap: pass in mddev directly for md_bitmap_resize() And move the condition "if (mddev->bitmap)" into md_bitmap_resize() as well, on the one hand make code cleaner, on the other hand try not to access bitmap directly. Since we are here, also change the parameter 'init' from int to bool. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-35-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/dm-raid.c | 2 +- drivers/md/md-bitmap.c | 21 ++++++++++++++++++--- drivers/md/md-bitmap.h | 4 ++-- drivers/md/md-cluster.c | 4 ++-- drivers/md/raid1.c | 12 +++++++----- drivers/md/raid10.c | 17 +++++++++-------- drivers/md/raid5.c | 11 ++++++----- 7 files changed, 45 insertions(+), 26 deletions(-) diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index c3e201fde4c5d..cc071fcd7a046 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) 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 = md_bitmap_resize(mddev->bitmap, mddev->dev_sectors, chunksize, 0); + r = md_bitmap_resize(mddev, mddev->dev_sectors, chunksize, false); if (r) DMERR("Failed to resize bitmap"); } diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index efe928849c94b..c2292546d6ce1 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -32,6 +32,9 @@ #include "md.h" #include "md-bitmap.h" +static int __bitmap_resize(struct bitmap *bitmap, sector_t blocks, + int chunksize, bool init); + static inline char *bmname(struct bitmap *bitmap) { return bitmap->mddev ? mdname(bitmap->mddev) : "mdX"; @@ -1975,7 +1978,8 @@ static struct bitmap *__bitmap_create(struct mddev *mddev, int slot) goto error; bitmap->daemon_lastrun = jiffies; - err = md_bitmap_resize(bitmap, blocks, mddev->bitmap_info.chunksize, 1); + err = __bitmap_resize(bitmap, blocks, mddev->bitmap_info.chunksize, + true); if (err) goto error; @@ -2163,8 +2167,8 @@ static int bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats return 0; } -int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks, - int chunksize, int init) +static int __bitmap_resize(struct bitmap *bitmap, sector_t blocks, + int chunksize, bool init) { /* If chunk_size is 0, choose an appropriate chunk size. * Then possibly allocate new storage space. @@ -2369,6 +2373,17 @@ int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks, err: return ret; } + +int md_bitmap_resize(struct mddev *mddev, sector_t blocks, int chunksize, + bool init) +{ + struct bitmap *bitmap = mddev->bitmap; + + if (!bitmap) + return 0; + + return __bitmap_resize(bitmap, blocks, chunksize, init); +} EXPORT_SYMBOL_GPL(md_bitmap_resize); static ssize_t diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index 065b36c0c43af..4610e50548ebf 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -280,8 +280,8 @@ void mddev_set_bitmap_ops(struct mddev *mddev); /* these are exported */ -int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks, - int chunksize, int init); +int md_bitmap_resize(struct mddev *mddev, sector_t blocks, int chunksize, + bool init); struct bitmap *get_bitmap_from_slot(struct mddev *mddev, int slot); int md_bitmap_copy_from_slot(struct mddev *mddev, int slot, sector_t *lo, sector_t *hi, bool clear_bits); diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index 55feabe14ad3a..a7e5ead71c2f9 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -628,8 +628,8 @@ static int process_recvd_msg(struct mddev *mddev, struct cluster_msg *msg) break; case BITMAP_RESIZE: if (le64_to_cpu(msg->high) != mddev->pers->size(mddev, 0, 0)) - ret = md_bitmap_resize(mddev->bitmap, - le64_to_cpu(msg->high), 0, 0); + ret = md_bitmap_resize(mddev, le64_to_cpu(msg->high), 0, + false); break; default: ret = -1; diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index f9338756088aa..cf05bafeae776 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -3297,14 +3297,16 @@ 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; - if (mddev->bitmap) { - int ret = md_bitmap_resize(mddev->bitmap, newsize, 0, 0); - if (ret) - return ret; - } + + ret = md_bitmap_resize(mddev, newsize, 0, false); + if (ret) + return ret; + md_set_array_sectors(mddev, newsize); if (sectors > mddev->dev_sectors && mddev->recovery_cp > mddev->dev_sectors) { diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index c79f374668dde..4512d285b76ad 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -4196,6 +4196,7 @@ 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; @@ -4208,11 +4209,11 @@ static int raid10_resize(struct mddev *mddev, sector_t sectors) if (mddev->external_size && mddev->array_sectors > size) return -EINVAL; - if (mddev->bitmap) { - int ret = md_bitmap_resize(mddev->bitmap, size, 0, 0); - if (ret) - return ret; - } + + ret = md_bitmap_resize(mddev, size, 0, false); + if (ret) + return ret; + md_set_array_sectors(mddev, size); if (sectors > mddev->dev_sectors && mddev->recovery_cp > oldsize) { @@ -4478,7 +4479,7 @@ static int raid10_start_reshape(struct mddev *mddev) newsize = raid10_size(mddev, 0, conf->geo.raid_disks); if (!mddev_is_clustered(mddev)) { - ret = md_bitmap_resize(mddev->bitmap, newsize, 0, 0); + ret = md_bitmap_resize(mddev, newsize, 0, false); if (ret) goto abort; else @@ -4500,13 +4501,13 @@ static int raid10_start_reshape(struct mddev *mddev) MD_FEATURE_RESHAPE_ACTIVE)) || (oldsize == newsize)) goto out; - ret = md_bitmap_resize(mddev->bitmap, newsize, 0, 0); + ret = md_bitmap_resize(mddev, newsize, 0, false); if (ret) goto abort; ret = md_cluster_ops->resize_bitmaps(mddev, newsize, oldsize); if (ret) { - md_bitmap_resize(mddev->bitmap, oldsize, 0, 0); + md_bitmap_resize(mddev, oldsize, 0, false); goto abort; } } diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 91b610d11c6a4..47c89f7b1dfe8 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -8313,6 +8313,7 @@ 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; @@ -8321,11 +8322,11 @@ static int raid5_resize(struct mddev *mddev, sector_t sectors) if (mddev->external_size && mddev->array_sectors > newsize) return -EINVAL; - if (mddev->bitmap) { - int ret = md_bitmap_resize(mddev->bitmap, sectors, 0, 0); - if (ret) - return ret; - } + + ret = md_bitmap_resize(mddev, sectors, 0, false); + if (ret) + return ret; + md_set_array_sectors(mddev, newsize); if (sectors > mddev->dev_sectors && mddev->recovery_cp > mddev->dev_sectors) { From 77c09640eea56dbfed069ac67b1cd79397d41be8 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:45 +0800 Subject: [PATCH 35/42] md/md-bitmap: merge md_bitmap_resize() into bitmap_operations So that the implementation won't be exposed, and it'll be possible to invent a new bitmap by replacing bitmap_operations. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-36-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/dm-raid.c | 3 ++- drivers/md/md-bitmap.c | 6 +++--- drivers/md/md-bitmap.h | 5 +++-- drivers/md/md-cluster.c | 5 +++-- drivers/md/raid1.c | 2 +- drivers/md/raid10.c | 10 +++++----- drivers/md/raid5.c | 2 +- 7 files changed, 18 insertions(+), 15 deletions(-) diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index cc071fcd7a046..63682d27fc8dd 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -4068,7 +4068,8 @@ 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 = md_bitmap_resize(mddev, mddev->dev_sectors, chunksize, false); + r = mddev->bitmap_ops->resize(mddev, mddev->dev_sectors, + chunksize, false); if (r) DMERR("Failed to resize bitmap"); } diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index c2292546d6ce1..0506b54f6322c 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -2374,8 +2374,8 @@ static int __bitmap_resize(struct bitmap *bitmap, sector_t blocks, return ret; } -int md_bitmap_resize(struct mddev *mddev, sector_t blocks, int chunksize, - bool init) +static int bitmap_resize(struct mddev *mddev, sector_t blocks, int chunksize, + bool init) { struct bitmap *bitmap = mddev->bitmap; @@ -2384,7 +2384,6 @@ int md_bitmap_resize(struct mddev *mddev, sector_t blocks, int chunksize, return __bitmap_resize(bitmap, blocks, chunksize, init); } -EXPORT_SYMBOL_GPL(md_bitmap_resize); static ssize_t location_show(struct mddev *mddev, char *page) @@ -2763,6 +2762,7 @@ const struct attribute_group md_bitmap_group = { static struct bitmap_operations bitmap_ops = { .create = bitmap_create, + .resize = bitmap_resize, .load = bitmap_load, .destroy = bitmap_destroy, .flush = bitmap_flush, diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index 4610e50548ebf..d05fc2f1451ed 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -248,6 +248,9 @@ struct md_bitmap_stats { struct bitmap_operations { int (*create)(struct mddev *mddev, int slot); + int (*resize)(struct mddev *mddev, sector_t blocks, int chunksize, + bool init); + int (*load)(struct mddev *mddev); void (*destroy)(struct mddev *mddev); void (*flush)(struct mddev *mddev); @@ -280,8 +283,6 @@ void mddev_set_bitmap_ops(struct mddev *mddev); /* these are exported */ -int md_bitmap_resize(struct mddev *mddev, sector_t blocks, int chunksize, - bool init); struct bitmap *get_bitmap_from_slot(struct mddev *mddev, int slot); int md_bitmap_copy_from_slot(struct mddev *mddev, int slot, sector_t *lo, sector_t *hi, bool clear_bits); diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index a7e5ead71c2f9..21cf0f38cbf8c 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -628,8 +628,9 @@ static int process_recvd_msg(struct mddev *mddev, struct cluster_msg *msg) break; case BITMAP_RESIZE: if (le64_to_cpu(msg->high) != mddev->pers->size(mddev, 0, 0)) - ret = md_bitmap_resize(mddev, le64_to_cpu(msg->high), 0, - false); + ret = mddev->bitmap_ops->resize(mddev, + le64_to_cpu(msg->high), + 0, false); break; default: ret = -1; diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index cf05bafeae776..3e678af8f28a2 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -3303,7 +3303,7 @@ static int raid1_resize(struct mddev *mddev, sector_t sectors) mddev->array_sectors > newsize) return -EINVAL; - ret = md_bitmap_resize(mddev, newsize, 0, false); + ret = mddev->bitmap_ops->resize(mddev, newsize, 0, false); if (ret) return ret; diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 4512d285b76ad..f3bf1116794a4 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -4210,7 +4210,7 @@ static int raid10_resize(struct mddev *mddev, sector_t sectors) mddev->array_sectors > size) return -EINVAL; - ret = md_bitmap_resize(mddev, size, 0, false); + ret = mddev->bitmap_ops->resize(mddev, size, 0, false); if (ret) return ret; @@ -4479,7 +4479,7 @@ static int raid10_start_reshape(struct mddev *mddev) newsize = raid10_size(mddev, 0, conf->geo.raid_disks); if (!mddev_is_clustered(mddev)) { - ret = md_bitmap_resize(mddev, newsize, 0, false); + ret = mddev->bitmap_ops->resize(mddev, newsize, 0, false); if (ret) goto abort; else @@ -4494,20 +4494,20 @@ static int raid10_start_reshape(struct mddev *mddev) /* * some node is already performing reshape, and no need to - * call md_bitmap_resize again since it should be called when + * call bitmap_ops->resize again since it should be called when * receiving BITMAP_RESIZE msg */ if ((sb && (le32_to_cpu(sb->feature_map) & MD_FEATURE_RESHAPE_ACTIVE)) || (oldsize == newsize)) goto out; - ret = md_bitmap_resize(mddev, newsize, 0, false); + ret = mddev->bitmap_ops->resize(mddev, newsize, 0, false); if (ret) goto abort; ret = md_cluster_ops->resize_bitmaps(mddev, newsize, oldsize); if (ret) { - md_bitmap_resize(mddev, oldsize, 0, false); + mddev->bitmap_ops->resize(mddev, oldsize, 0, false); goto abort; } } diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 47c89f7b1dfe8..c84a7e0263cde 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -8323,7 +8323,7 @@ static int raid5_resize(struct mddev *mddev, sector_t sectors) mddev->array_sectors > newsize) return -EINVAL; - ret = md_bitmap_resize(mddev, sectors, 0, false); + ret = mddev->bitmap_ops->resize(mddev, sectors, 0, false); if (ret) return ret; From 57d602414d2e327160f2e03c39eff3f2f895839c Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:46 +0800 Subject: [PATCH 36/42] md/md-bitmap: merge get_bitmap_from_slot() into bitmap_operations So that the implementation won't be exposed, and it'll be possible to invent a new bitmap by replacing bitmap_operations. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-37-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 6 +++--- drivers/md/md-bitmap.h | 2 +- drivers/md/md-cluster.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 0506b54f6322c..a75f4216fd409 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -2065,7 +2065,7 @@ static int bitmap_load(struct mddev *mddev) } /* caller need to free returned bitmap with md_bitmap_free() */ -struct bitmap *get_bitmap_from_slot(struct mddev *mddev, int slot) +static struct bitmap *bitmap_get_from_slot(struct mddev *mddev, int slot) { int rv = 0; struct bitmap *bitmap; @@ -2084,7 +2084,6 @@ struct bitmap *get_bitmap_from_slot(struct mddev *mddev, int slot) return bitmap; } -EXPORT_SYMBOL(get_bitmap_from_slot); /* Loads the bitmap associated with slot and copies the resync information * to our bitmap @@ -2097,7 +2096,7 @@ int md_bitmap_copy_from_slot(struct mddev *mddev, int slot, struct bitmap_counts *counts; struct bitmap *bitmap; - bitmap = get_bitmap_from_slot(mddev, slot); + bitmap = bitmap_get_from_slot(mddev, slot); if (IS_ERR(bitmap)) { pr_err("%s can't get bitmap from slot %d\n", __func__, slot); return -1; @@ -2782,6 +2781,7 @@ static struct bitmap_operations bitmap_ops = { .get_stats = bitmap_get_stats, .sync_with_cluster = bitmap_sync_with_cluster, + .get_from_slot = bitmap_get_from_slot, }; void mddev_set_bitmap_ops(struct mddev *mddev) diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index d05fc2f1451ed..6bcb88b713718 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -276,6 +276,7 @@ struct bitmap_operations { void (*sync_with_cluster)(struct mddev *mddev, sector_t old_lo, sector_t old_hi, sector_t new_lo, sector_t new_hi); + struct bitmap *(*get_from_slot)(struct mddev *mddev, int slot); }; /* the bitmap API */ @@ -283,7 +284,6 @@ void mddev_set_bitmap_ops(struct mddev *mddev); /* these are exported */ -struct bitmap *get_bitmap_from_slot(struct mddev *mddev, int slot); int md_bitmap_copy_from_slot(struct mddev *mddev, int slot, sector_t *lo, sector_t *hi, bool clear_bits); void md_bitmap_set_pages(struct bitmap *bitmap, unsigned long pages); diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index 21cf0f38cbf8c..81c630dcf9ea0 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -1169,7 +1169,7 @@ static int resize_bitmaps(struct mddev *mddev, sector_t newsize, sector_t oldsiz if (i == md_cluster_ops->slot_number(mddev)) continue; - bitmap = get_bitmap_from_slot(mddev, i); + bitmap = mddev->bitmap_ops->get_from_slot(mddev, i); if (IS_ERR(bitmap)) { pr_err("can't get bitmap from slot %d\n", i); bitmap = NULL; @@ -1236,7 +1236,7 @@ static int cluster_check_sync_size(struct mddev *mddev) if (i == current_slot) continue; - bitmap = get_bitmap_from_slot(mddev, i); + bitmap = mddev->bitmap_ops->get_from_slot(mddev, i); if (IS_ERR(bitmap)) { pr_err("can't get bitmap from slot %d\n", i); return -1; From 3dd9141a154785f10770fb3e8349f6b133b08b8a Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:47 +0800 Subject: [PATCH 37/42] md/md-bitmap: merge md_bitmap_copy_from_slot() into struct bitmap_operation. So that the implementation won't be exposed, and it'll be possible to invent a new bitmap by replacing bitmap_operations. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-38-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 6 +++--- drivers/md/md-bitmap.h | 4 ++-- drivers/md/md-cluster.c | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index a75f4216fd409..25126cdee4e11 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -2088,8 +2088,8 @@ static struct bitmap *bitmap_get_from_slot(struct mddev *mddev, int slot) /* Loads the bitmap associated with slot and copies the resync information * to our bitmap */ -int md_bitmap_copy_from_slot(struct mddev *mddev, int slot, - sector_t *low, sector_t *high, bool clear_bits) +static int bitmap_copy_from_slot(struct mddev *mddev, int slot, sector_t *low, + sector_t *high, bool clear_bits) { int rv = 0, i, j; sector_t block, lo = 0, hi = 0; @@ -2131,7 +2131,6 @@ int md_bitmap_copy_from_slot(struct mddev *mddev, int slot, return rv; } -EXPORT_SYMBOL_GPL(md_bitmap_copy_from_slot); void md_bitmap_set_pages(struct bitmap *bitmap, unsigned long pages) { @@ -2782,6 +2781,7 @@ static struct bitmap_operations bitmap_ops = { .sync_with_cluster = bitmap_sync_with_cluster, .get_from_slot = bitmap_get_from_slot, + .copy_from_slot = bitmap_copy_from_slot, }; void mddev_set_bitmap_ops(struct mddev *mddev) diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index 6bcb88b713718..94d9a6ae244aa 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -277,6 +277,8 @@ struct bitmap_operations { sector_t old_lo, sector_t old_hi, sector_t new_lo, sector_t new_hi); struct bitmap *(*get_from_slot)(struct mddev *mddev, int slot); + int (*copy_from_slot)(struct mddev *mddev, int slot, sector_t *lo, + sector_t *hi, bool clear_bits); }; /* the bitmap API */ @@ -284,8 +286,6 @@ void mddev_set_bitmap_ops(struct mddev *mddev); /* these are exported */ -int md_bitmap_copy_from_slot(struct mddev *mddev, int slot, - sector_t *lo, sector_t *hi, bool clear_bits); void md_bitmap_set_pages(struct bitmap *bitmap, unsigned long pages); void md_bitmap_free(struct bitmap *bitmap); void md_bitmap_wait_behind_writes(struct mddev *mddev); diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index 81c630dcf9ea0..515f46983ace5 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -317,7 +317,7 @@ static void recover_bitmaps(struct md_thread *thread) str, ret); goto clear_bit; } - ret = md_bitmap_copy_from_slot(mddev, slot, &lo, &hi, true); + ret = mddev->bitmap_ops->copy_from_slot(mddev, slot, &lo, &hi, true); if (ret) { pr_err("md-cluster: Could not copy data from bitmap %d\n", slot); goto clear_bit; @@ -857,7 +857,7 @@ static int gather_all_resync_info(struct mddev *mddev, int total_slots) } /* Read the disk bitmap sb and check if it needs recovery */ - ret = md_bitmap_copy_from_slot(mddev, i, &lo, &hi, false); + ret = mddev->bitmap_ops->copy_from_slot(mddev, i, &lo, &hi, false); if (ret) { pr_warn("md-cluster: Could not gather bitmaps from slot %d", i); lockres_free(bm_lockres); @@ -1600,7 +1600,7 @@ static int gather_bitmaps(struct md_rdev *rdev) for (sn = 0; sn < mddev->bitmap_info.nodes; sn++) { if (sn == (cinfo->slot_number - 1)) continue; - err = md_bitmap_copy_from_slot(mddev, sn, &lo, &hi, false); + err = mddev->bitmap_ops->copy_from_slot(mddev, sn, &lo, &hi, false); if (err) { pr_warn("md-cluster: Could not gather bitmaps from slot %d", sn); goto out; From ef1c400fafe27f06ba1e8050fc2f35662fe8e106 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:48 +0800 Subject: [PATCH 38/42] md/md-bitmap: merge md_bitmap_set_pages() into struct bitmap_operations o that the implementation won't be exposed, and it'll be possible o invent a new bitmap by replacing bitmap_operations. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-39-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 4 ++-- drivers/md/md-bitmap.h | 2 +- drivers/md/md-cluster.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 25126cdee4e11..70818c56004f6 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -2132,11 +2132,10 @@ static int bitmap_copy_from_slot(struct mddev *mddev, int slot, sector_t *low, return rv; } -void md_bitmap_set_pages(struct bitmap *bitmap, unsigned long pages) +static void bitmap_set_pages(struct bitmap *bitmap, unsigned long pages) { bitmap->counts.pages = pages; } -EXPORT_SYMBOL_GPL(md_bitmap_set_pages); static int bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats) { @@ -2782,6 +2781,7 @@ static struct bitmap_operations bitmap_ops = { .sync_with_cluster = bitmap_sync_with_cluster, .get_from_slot = bitmap_get_from_slot, .copy_from_slot = bitmap_copy_from_slot, + .set_pages = bitmap_set_pages, }; void mddev_set_bitmap_ops(struct mddev *mddev) diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index 94d9a6ae244aa..7fee98e3d517b 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -279,6 +279,7 @@ struct bitmap_operations { struct bitmap *(*get_from_slot)(struct mddev *mddev, int slot); int (*copy_from_slot)(struct mddev *mddev, int slot, sector_t *lo, sector_t *hi, bool clear_bits); + void (*set_pages)(struct bitmap *bitmap, unsigned long pages); }; /* the bitmap API */ @@ -286,7 +287,6 @@ void mddev_set_bitmap_ops(struct mddev *mddev); /* these are exported */ -void md_bitmap_set_pages(struct bitmap *bitmap, unsigned long pages); void md_bitmap_free(struct bitmap *bitmap); void md_bitmap_wait_behind_writes(struct mddev *mddev); diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index 515f46983ace5..3296925b84554 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -1192,7 +1192,7 @@ static int resize_bitmaps(struct mddev *mddev, sector_t newsize, sector_t oldsiz bm_lockres->flags |= DLM_LKF_NOQUEUE; rv = dlm_lock_sync(bm_lockres, DLM_LOCK_PW); if (!rv) - md_bitmap_set_pages(bitmap, my_pages); + mddev->bitmap_ops->set_pages(bitmap, my_pages); lockres_free(bm_lockres); if (my_pages != stats.pages) From c65c20dc504b08204d6c3effffa9409a526822aa Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:49 +0800 Subject: [PATCH 39/42] md/md-bitmap: merge md_bitmap_free() into bitmap_operations So that the implementation won't be exposed, and it'll be possible o invent a new bitmap by replacing bitmap_operations. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-40-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 7 ++----- drivers/md/md-bitmap.h | 3 +-- drivers/md/md-cluster.c | 12 ++++++------ 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 70818c56004f6..62e4f9d5a5591 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -1828,10 +1828,7 @@ static void bitmap_flush(struct mddev *mddev) bitmap_update_sb(bitmap); } -/* - * free memory that was allocated - */ -void md_bitmap_free(struct bitmap *bitmap) +static void md_bitmap_free(struct bitmap *bitmap) { unsigned long k, pages; struct bitmap_page *bp; @@ -1865,7 +1862,6 @@ void md_bitmap_free(struct bitmap *bitmap) kfree(bp); kfree(bitmap); } -EXPORT_SYMBOL(md_bitmap_free); void md_bitmap_wait_behind_writes(struct mddev *mddev) { @@ -2782,6 +2778,7 @@ static struct bitmap_operations bitmap_ops = { .get_from_slot = bitmap_get_from_slot, .copy_from_slot = bitmap_copy_from_slot, .set_pages = bitmap_set_pages, + .free = md_bitmap_free, }; void mddev_set_bitmap_ops(struct mddev *mddev) diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index 7fee98e3d517b..7f6cc6f616b36 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -280,14 +280,13 @@ struct bitmap_operations { int (*copy_from_slot)(struct mddev *mddev, int slot, sector_t *lo, sector_t *hi, bool clear_bits); void (*set_pages)(struct bitmap *bitmap, unsigned long pages); + void (*free)(struct bitmap *bitmap); }; /* the bitmap API */ void mddev_set_bitmap_ops(struct mddev *mddev); /* these are exported */ - -void md_bitmap_free(struct bitmap *bitmap); void md_bitmap_wait_behind_writes(struct mddev *mddev); static inline bool md_bitmap_enabled(struct bitmap *bitmap) diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index 3296925b84554..7647ce4f76fa5 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -1201,12 +1201,12 @@ static int resize_bitmaps(struct mddev *mddev, sector_t newsize, sector_t oldsiz * can't resize bitmap */ goto out; - md_bitmap_free(bitmap); + mddev->bitmap_ops->free(bitmap); } return 0; out: - md_bitmap_free(bitmap); + mddev->bitmap_ops->free(bitmap); update_bitmap_size(mddev, oldsize); return -1; } @@ -1250,7 +1250,7 @@ static int cluster_check_sync_size(struct mddev *mddev) bm_lockres = lockres_init(mddev, str, NULL, 1); if (!bm_lockres) { pr_err("md-cluster: Cannot initialize %s\n", str); - md_bitmap_free(bitmap); + mddev->bitmap_ops->free(bitmap); return -1; } bm_lockres->flags |= DLM_LKF_NOQUEUE; @@ -1261,17 +1261,17 @@ static int cluster_check_sync_size(struct mddev *mddev) rv = mddev->bitmap_ops->get_stats(bitmap, &stats); if (rv) { - md_bitmap_free(bitmap); + mddev->bitmap_ops->free(bitmap); return rv; } if (sync_size == 0) { sync_size = stats.sync_size; } else if (sync_size != stats.sync_size) { - md_bitmap_free(bitmap); + mddev->bitmap_ops->free(bitmap); return -1; } - md_bitmap_free(bitmap); + mddev->bitmap_ops->free(bitmap); } return (my_sync_size == sync_size) ? 0 : -1; From 49f5f5e309e6127957babed7834f5a0e1022f936 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:50 +0800 Subject: [PATCH 40/42] md/md-bitmap: merge md_bitmap_wait_behind_writes() into bitmap_operations So that the implementation won't be exposed, and it'll be possible to invent a new bitmap by replacing bitmap_operations. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-41-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 6 +++--- drivers/md/md-bitmap.h | 4 +--- drivers/md/md.c | 2 +- drivers/md/raid1.c | 2 +- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 62e4f9d5a5591..b5dbfa9728dc0 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -1863,7 +1863,7 @@ static void md_bitmap_free(struct bitmap *bitmap) kfree(bitmap); } -void md_bitmap_wait_behind_writes(struct mddev *mddev) +static void bitmap_wait_behind_writes(struct mddev *mddev) { struct bitmap *bitmap = mddev->bitmap; @@ -1876,7 +1876,6 @@ void md_bitmap_wait_behind_writes(struct mddev *mddev) atomic_read(&bitmap->behind_writes) == 0); } } -EXPORT_SYMBOL_GPL(md_bitmap_wait_behind_writes); static void bitmap_destroy(struct mddev *mddev) { @@ -1885,7 +1884,7 @@ static void bitmap_destroy(struct mddev *mddev) if (!bitmap) /* there was no bitmap */ return; - md_bitmap_wait_behind_writes(mddev); + bitmap_wait_behind_writes(mddev); if (!mddev->serialize_policy) mddev_destroy_serial_pool(mddev, NULL); @@ -2763,6 +2762,7 @@ static struct bitmap_operations bitmap_ops = { .dirty_bits = bitmap_dirty_bits, .unplug = bitmap_unplug, .daemon_work = bitmap_daemon_work, + .wait_behind_writes = bitmap_wait_behind_writes, .startwrite = bitmap_startwrite, .endwrite = bitmap_endwrite, diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index 7f6cc6f616b36..bc9cb4ca676e7 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -259,6 +259,7 @@ struct bitmap_operations { unsigned long e); void (*unplug)(struct mddev *mddev, bool sync); void (*daemon_work)(struct mddev *mddev); + void (*wait_behind_writes)(struct mddev *mddev); int (*startwrite)(struct mddev *mddev, sector_t offset, unsigned long sectors, bool behind); @@ -286,9 +287,6 @@ struct bitmap_operations { /* the bitmap API */ void mddev_set_bitmap_ops(struct mddev *mddev); -/* these are exported */ -void md_bitmap_wait_behind_writes(struct mddev *mddev); - static inline bool md_bitmap_enabled(struct bitmap *bitmap) { return bitmap && bitmap->storage.filemap && diff --git a/drivers/md/md.c b/drivers/md/md.c index 00932bd9b0c8b..6435688b7165e 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -6498,7 +6498,7 @@ EXPORT_SYMBOL_GPL(md_stop_writes); static void mddev_detach(struct mddev *mddev) { - md_bitmap_wait_behind_writes(mddev); + 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); diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 3e678af8f28a2..b15725a7a581b 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1371,7 +1371,7 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio, * over-take any writes that are 'behind' */ mddev_add_trace_msg(mddev, "raid1 wait behind writes"); - md_bitmap_wait_behind_writes(mddev); + mddev->bitmap_ops->wait_behind_writes(mddev); } if (max_sectors < bio_sectors(bio)) { From dab2ce5534ef7a7b8db70d1abd4225ee8a7798c7 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:51 +0800 Subject: [PATCH 41/42] md/md-bitmap: merge md_bitmap_enabled() into bitmap_operations So that the implementation won't be exposed, and it'll be possible to invent a new bitmap by replacing bitmap_operations. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-42-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 19 ++++++++++++++++++- drivers/md/md-bitmap.h | 8 +------- drivers/md/raid1-10.c | 2 +- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index b5dbfa9728dc0..098bffac21677 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -40,6 +40,22 @@ static inline char *bmname(struct bitmap *bitmap) return bitmap->mddev ? mdname(bitmap->mddev) : "mdX"; } +static bool __bitmap_enabled(struct bitmap *bitmap) +{ + return bitmap->storage.filemap && + !test_bit(BITMAP_STALE, &bitmap->flags); +} + +static bool bitmap_enabled(struct mddev *mddev) +{ + struct bitmap *bitmap = mddev->bitmap; + + if (!bitmap) + return false; + + return __bitmap_enabled(bitmap); +} + /* * check a page and, if necessary, allocate it (or hijack it if the alloc fails) * @@ -1035,7 +1051,7 @@ static void __bitmap_unplug(struct bitmap *bitmap) int dirty, need_write; int writing = 0; - if (!md_bitmap_enabled(bitmap)) + if (!__bitmap_enabled(bitmap)) return; /* look at each page to see if there are any set bits that need to be @@ -2753,6 +2769,7 @@ const struct attribute_group md_bitmap_group = { }; static struct bitmap_operations bitmap_ops = { + .enabled = bitmap_enabled, .create = bitmap_create, .resize = bitmap_resize, .load = bitmap_load, diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index bc9cb4ca676e7..c720729687e22 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -247,6 +247,7 @@ struct md_bitmap_stats { }; struct bitmap_operations { + bool (*enabled)(struct mddev *mddev); int (*create)(struct mddev *mddev, int slot); int (*resize)(struct mddev *mddev, sector_t blocks, int chunksize, bool init); @@ -287,12 +288,5 @@ struct bitmap_operations { /* the bitmap API */ void mddev_set_bitmap_ops(struct mddev *mddev); -static inline bool md_bitmap_enabled(struct bitmap *bitmap) -{ - return bitmap && bitmap->storage.filemap && - !test_bit(BITMAP_STALE, &bitmap->flags); -} - #endif - #endif diff --git a/drivers/md/raid1-10.c b/drivers/md/raid1-10.c index e8207513eb1b6..4378d3250bd75 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 (!md_bitmap_enabled(mddev->bitmap)) { + if (!mddev->bitmap_ops->enabled(mddev)) { raid1_submit_write(bio); return true; } From 59fdd43304f4cbb7ee8e281ca337afd803c309f6 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 26 Aug 2024 15:44:52 +0800 Subject: [PATCH 42/42] md/md-bitmap: make in memory structure internal Now that struct bitmap_page and bitmap is not used externally anymore, move them from md-bitmap.h to md-bitmap.c (expect that dm-raid is still using define marco 'COUNTER_MAX'). Also fix some checkpatch warnings. Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20240826074452.1490072-43-yukuai1@huaweicloud.com Signed-off-by: Song Liu --- drivers/md/md-bitmap.c | 247 ++++++++++++++++++++++++++++++++++++---- drivers/md/md-bitmap.h | 189 +----------------------------- drivers/md/md-cluster.c | 4 +- drivers/md/md.h | 2 +- drivers/md/raid1.c | 5 +- 5 files changed, 235 insertions(+), 212 deletions(-) diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 098bffac21677..864418c8c0288 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -32,6 +32,186 @@ #include "md.h" #include "md-bitmap.h" +#define BITMAP_MAJOR_LO 3 +/* version 4 insists the bitmap is in little-endian order + * with version 3, it is host-endian which is non-portable + * Version 5 is currently set only for clustered devices + */ +#define BITMAP_MAJOR_HI 4 +#define BITMAP_MAJOR_CLUSTERED 5 +#define BITMAP_MAJOR_HOSTENDIAN 3 + +/* + * in-memory bitmap: + * + * Use 16 bit block counters to track pending writes to each "chunk". + * The 2 high order bits are special-purpose, the first is a flag indicating + * whether a resync is needed. The second is a flag indicating whether a + * resync is active. + * This means that the counter is actually 14 bits: + * + * +--------+--------+------------------------------------------------+ + * | resync | resync | counter | + * | needed | active | | + * | (0-1) | (0-1) | (0-16383) | + * +--------+--------+------------------------------------------------+ + * + * The "resync needed" bit is set when: + * a '1' bit is read from storage at startup. + * a write request fails on some drives + * a resync is aborted on a chunk with 'resync active' set + * It is cleared (and resync-active set) when a resync starts across all drives + * of the chunk. + * + * + * The "resync active" bit is set when: + * a resync is started on all drives, and resync_needed is set. + * resync_needed will be cleared (as long as resync_active wasn't already set). + * It is cleared when a resync completes. + * + * The counter counts pending write requests, plus the on-disk bit. + * When the counter is '1' and the resync bits are clear, the on-disk + * bit can be cleared as well, thus setting the counter to 0. + * When we set a bit, or in the counter (to start a write), if the fields is + * 0, we first set the disk bit and set the counter to 1. + * + * If the counter is 0, the on-disk bit is clear and the stripe is clean + * Anything that dirties the stripe pushes the counter to 2 (at least) + * and sets the on-disk bit (lazily). + * If a periodic sweep find the counter at 2, it is decremented to 1. + * If the sweep find the counter at 1, the on-disk bit is cleared and the + * counter goes to zero. + * + * Also, we'll hijack the "map" pointer itself and use it as two 16 bit block + * counters as a fallback when "page" memory cannot be allocated: + * + * Normal case (page memory allocated): + * + * page pointer (32-bit) + * + * [ ] ------+ + * | + * +-------> [ ][ ]..[ ] (4096 byte page == 2048 counters) + * c1 c2 c2048 + * + * Hijacked case (page memory allocation failed): + * + * hijacked page pointer (32-bit) + * + * [ ][ ] (no page memory allocated) + * counter #1 (16-bit) counter #2 (16-bit) + * + */ + +#define PAGE_BITS (PAGE_SIZE << 3) +#define PAGE_BIT_SHIFT (PAGE_SHIFT + 3) + +#define NEEDED(x) (((bitmap_counter_t) x) & NEEDED_MASK) +#define RESYNC(x) (((bitmap_counter_t) x) & RESYNC_MASK) +#define COUNTER(x) (((bitmap_counter_t) x) & COUNTER_MAX) + +/* how many counters per page? */ +#define PAGE_COUNTER_RATIO (PAGE_BITS / COUNTER_BITS) +/* same, except a shift value for more efficient bitops */ +#define PAGE_COUNTER_SHIFT (PAGE_BIT_SHIFT - COUNTER_BIT_SHIFT) +/* same, except a mask value for more efficient bitops */ +#define PAGE_COUNTER_MASK (PAGE_COUNTER_RATIO - 1) + +#define BITMAP_BLOCK_SHIFT 9 + +/* + * bitmap structures: + */ + +/* the in-memory bitmap is represented by bitmap_pages */ +struct bitmap_page { + /* + * map points to the actual memory page + */ + char *map; + /* + * in emergencies (when map cannot be alloced), hijack the map + * pointer and use it as two counters itself + */ + unsigned int hijacked:1; + /* + * If any counter in this page is '1' or '2' - and so could be + * cleared then that page is marked as 'pending' + */ + unsigned int pending:1; + /* + * count of dirty bits on the page + */ + unsigned int count:30; +}; + +/* the main bitmap structure - one per mddev */ +struct bitmap { + + struct bitmap_counts { + spinlock_t lock; + struct bitmap_page *bp; + /* total number of pages in the bitmap */ + unsigned long pages; + /* number of pages not yet allocated */ + unsigned long missing_pages; + /* chunksize = 2^chunkshift (for bitops) */ + unsigned long chunkshift; + /* total number of data chunks for the array */ + unsigned long chunks; + } counts; + + struct mddev *mddev; /* the md device that the bitmap is for */ + + __u64 events_cleared; + int need_sync; + + struct bitmap_storage { + /* backing disk file */ + struct file *file; + /* cached copy of the bitmap file superblock */ + struct page *sb_page; + unsigned long sb_index; + /* list of cache pages for the file */ + struct page **filemap; + /* attributes associated filemap pages */ + unsigned long *filemap_attr; + /* number of pages in the file */ + unsigned long file_pages; + /* total bytes in the bitmap */ + unsigned long bytes; + } storage; + + unsigned long flags; + + int allclean; + + atomic_t behind_writes; + /* highest actual value at runtime */ + unsigned long behind_writes_used; + + /* + * the bitmap daemon - periodically wakes up and sweeps the bitmap + * file, cleaning up bits and flushing out pages to disk as necessary + */ + unsigned long daemon_lastrun; /* jiffies of last run */ + /* + * when we lasted called end_sync to update bitmap with resync + * progress. + */ + unsigned long last_end_sync; + + /* pending writes to the bitmap file */ + atomic_t pending_writes; + wait_queue_head_t write_wait; + wait_queue_head_t overflow_wait; + wait_queue_head_t behind_wait; + + struct kernfs_node *sysfs_can_clear; + /* slot offset for clustered env */ + int cluster_slot; +}; + static int __bitmap_resize(struct bitmap *bitmap, sector_t blocks, int chunksize, bool init); @@ -491,9 +671,10 @@ static void md_bitmap_wait_writes(struct bitmap *bitmap) /* update the event counter and sync the superblock to disk */ -static void bitmap_update_sb(struct bitmap *bitmap) +static void bitmap_update_sb(void *data) { bitmap_super_t *sb; + struct bitmap *bitmap = data; if (!bitmap || !bitmap->mddev) /* no bitmap for this array */ return; @@ -1844,10 +2025,11 @@ static void bitmap_flush(struct mddev *mddev) bitmap_update_sb(bitmap); } -static void md_bitmap_free(struct bitmap *bitmap) +static void md_bitmap_free(void *data) { unsigned long k, pages; struct bitmap_page *bp; + struct bitmap *bitmap = data; if (!bitmap) /* there was no bitmap */ return; @@ -2076,7 +2258,7 @@ static int bitmap_load(struct mddev *mddev) } /* caller need to free returned bitmap with md_bitmap_free() */ -static struct bitmap *bitmap_get_from_slot(struct mddev *mddev, int slot) +static void *bitmap_get_from_slot(struct mddev *mddev, int slot) { int rv = 0; struct bitmap *bitmap; @@ -2143,15 +2325,18 @@ static int bitmap_copy_from_slot(struct mddev *mddev, int slot, sector_t *low, return rv; } -static void bitmap_set_pages(struct bitmap *bitmap, unsigned long pages) +static void bitmap_set_pages(void *data, unsigned long pages) { + struct bitmap *bitmap = data; + bitmap->counts.pages = pages; } -static int bitmap_get_stats(struct bitmap *bitmap, struct md_bitmap_stats *stats) +static int bitmap_get_stats(void *data, struct md_bitmap_stats *stats) { struct bitmap_storage *storage; struct bitmap_counts *counts; + struct bitmap *bitmap = data; bitmap_super_t *sb; if (!bitmap) @@ -2510,6 +2695,7 @@ space_show(struct mddev *mddev, char *page) static ssize_t space_store(struct mddev *mddev, const char *buf, size_t len) { + struct bitmap *bitmap; unsigned long sectors; int rv; @@ -2520,8 +2706,8 @@ space_store(struct mddev *mddev, const char *buf, size_t len) if (sectors == 0) return -EINVAL; - if (mddev->bitmap && - sectors < (mddev->bitmap->storage.bytes + 511) >> 9) + bitmap = mddev->bitmap; + if (bitmap && sectors < (bitmap->storage.bytes + 511) >> 9) return -EFBIG; /* Bitmap is too big for this small space */ /* could make sure it isn't too big, but that isn't really @@ -2698,10 +2884,13 @@ __ATTR(metadata, S_IRUGO|S_IWUSR, metadata_show, metadata_store); static ssize_t can_clear_show(struct mddev *mddev, char *page) { int len; + struct bitmap *bitmap; + spin_lock(&mddev->lock); - if (mddev->bitmap) - len = sprintf(page, "%s\n", (mddev->bitmap->need_sync ? - "false" : "true")); + bitmap = mddev->bitmap; + if (bitmap) + len = sprintf(page, "%s\n", (bitmap->need_sync ? "false" : + "true")); else len = sprintf(page, "\n"); spin_unlock(&mddev->lock); @@ -2710,17 +2899,24 @@ static ssize_t can_clear_show(struct mddev *mddev, char *page) static ssize_t can_clear_store(struct mddev *mddev, const char *buf, size_t len) { - if (mddev->bitmap == NULL) + struct bitmap *bitmap = mddev->bitmap; + + if (!bitmap) return -ENOENT; - if (strncmp(buf, "false", 5) == 0) - mddev->bitmap->need_sync = 1; - else if (strncmp(buf, "true", 4) == 0) { + + if (strncmp(buf, "false", 5) == 0) { + bitmap->need_sync = 1; + return len; + } + + if (strncmp(buf, "true", 4) == 0) { if (mddev->degraded) return -EBUSY; - mddev->bitmap->need_sync = 0; - } else - return -EINVAL; - return len; + bitmap->need_sync = 0; + return len; + } + + return -EINVAL; } static struct md_sysfs_entry bitmap_can_clear = @@ -2730,21 +2926,26 @@ static ssize_t behind_writes_used_show(struct mddev *mddev, char *page) { ssize_t ret; + struct bitmap *bitmap; + spin_lock(&mddev->lock); - if (mddev->bitmap == NULL) + bitmap = mddev->bitmap; + if (!bitmap) ret = sprintf(page, "0\n"); else - ret = sprintf(page, "%lu\n", - mddev->bitmap->behind_writes_used); + ret = sprintf(page, "%lu\n", bitmap->behind_writes_used); spin_unlock(&mddev->lock); + return ret; } static ssize_t behind_writes_used_reset(struct mddev *mddev, const char *buf, size_t len) { - if (mddev->bitmap) - mddev->bitmap->behind_writes_used = 0; + struct bitmap *bitmap = mddev->bitmap; + + if (bitmap) + bitmap->behind_writes_used = 0; return len; } diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h index c720729687e22..662e6fc141a77 100644 --- a/drivers/md/md-bitmap.h +++ b/drivers/md/md-bitmap.h @@ -7,81 +7,7 @@ #ifndef BITMAP_H #define BITMAP_H 1 -#define BITMAP_MAJOR_LO 3 -/* version 4 insists the bitmap is in little-endian order - * with version 3, it is host-endian which is non-portable - * Version 5 is currently set only for clustered devices - */ -#define BITMAP_MAJOR_HI 4 -#define BITMAP_MAJOR_CLUSTERED 5 -#define BITMAP_MAJOR_HOSTENDIAN 3 - -/* - * in-memory bitmap: - * - * Use 16 bit block counters to track pending writes to each "chunk". - * The 2 high order bits are special-purpose, the first is a flag indicating - * whether a resync is needed. The second is a flag indicating whether a - * resync is active. - * This means that the counter is actually 14 bits: - * - * +--------+--------+------------------------------------------------+ - * | resync | resync | counter | - * | needed | active | | - * | (0-1) | (0-1) | (0-16383) | - * +--------+--------+------------------------------------------------+ - * - * The "resync needed" bit is set when: - * a '1' bit is read from storage at startup. - * a write request fails on some drives - * a resync is aborted on a chunk with 'resync active' set - * It is cleared (and resync-active set) when a resync starts across all drives - * of the chunk. - * - * - * The "resync active" bit is set when: - * a resync is started on all drives, and resync_needed is set. - * resync_needed will be cleared (as long as resync_active wasn't already set). - * It is cleared when a resync completes. - * - * The counter counts pending write requests, plus the on-disk bit. - * When the counter is '1' and the resync bits are clear, the on-disk - * bit can be cleared as well, thus setting the counter to 0. - * When we set a bit, or in the counter (to start a write), if the fields is - * 0, we first set the disk bit and set the counter to 1. - * - * If the counter is 0, the on-disk bit is clear and the stripe is clean - * Anything that dirties the stripe pushes the counter to 2 (at least) - * and sets the on-disk bit (lazily). - * If a periodic sweep find the counter at 2, it is decremented to 1. - * If the sweep find the counter at 1, the on-disk bit is cleared and the - * counter goes to zero. - * - * Also, we'll hijack the "map" pointer itself and use it as two 16 bit block - * counters as a fallback when "page" memory cannot be allocated: - * - * Normal case (page memory allocated): - * - * page pointer (32-bit) - * - * [ ] ------+ - * | - * +-------> [ ][ ]..[ ] (4096 byte page == 2048 counters) - * c1 c2 c2048 - * - * Hijacked case (page memory allocation failed): - * - * hijacked page pointer (32-bit) - * - * [ ][ ] (no page memory allocated) - * counter #1 (16-bit) counter #2 (16-bit) - * - */ - -#ifdef __KERNEL__ - -#define PAGE_BITS (PAGE_SIZE << 3) -#define PAGE_BIT_SHIFT (PAGE_SHIFT + 3) +#define BITMAP_MAGIC 0x6d746962 typedef __u16 bitmap_counter_t; #define COUNTER_BITS 16 @@ -91,26 +17,6 @@ typedef __u16 bitmap_counter_t; #define NEEDED_MASK ((bitmap_counter_t) (1 << (COUNTER_BITS - 1))) #define RESYNC_MASK ((bitmap_counter_t) (1 << (COUNTER_BITS - 2))) #define COUNTER_MAX ((bitmap_counter_t) RESYNC_MASK - 1) -#define NEEDED(x) (((bitmap_counter_t) x) & NEEDED_MASK) -#define RESYNC(x) (((bitmap_counter_t) x) & RESYNC_MASK) -#define COUNTER(x) (((bitmap_counter_t) x) & COUNTER_MAX) - -/* how many counters per page? */ -#define PAGE_COUNTER_RATIO (PAGE_BITS / COUNTER_BITS) -/* same, except a shift value for more efficient bitops */ -#define PAGE_COUNTER_SHIFT (PAGE_BIT_SHIFT - COUNTER_BIT_SHIFT) -/* same, except a mask value for more efficient bitops */ -#define PAGE_COUNTER_MASK (PAGE_COUNTER_RATIO - 1) - -#define BITMAP_BLOCK_SHIFT 9 - -#endif - -/* - * bitmap structures: - */ - -#define BITMAP_MAGIC 0x6d746962 /* use these for bitmap->flags and bitmap->sb->state bit-fields */ enum bitmap_state { @@ -152,88 +58,6 @@ typedef struct bitmap_super_s { * devices. For raid10 it is the size of the array. */ -#ifdef __KERNEL__ - -/* the in-memory bitmap is represented by bitmap_pages */ -struct bitmap_page { - /* - * map points to the actual memory page - */ - char *map; - /* - * in emergencies (when map cannot be alloced), hijack the map - * pointer and use it as two counters itself - */ - unsigned int hijacked:1; - /* - * If any counter in this page is '1' or '2' - and so could be - * cleared then that page is marked as 'pending' - */ - unsigned int pending:1; - /* - * count of dirty bits on the page - */ - unsigned int count:30; -}; - -/* the main bitmap structure - one per mddev */ -struct bitmap { - - struct bitmap_counts { - spinlock_t lock; - struct bitmap_page *bp; - unsigned long pages; /* total number of pages - * in the bitmap */ - unsigned long missing_pages; /* number of pages - * not yet allocated */ - unsigned long chunkshift; /* chunksize = 2^chunkshift - * (for bitops) */ - unsigned long chunks; /* Total number of data - * chunks for the array */ - } counts; - - struct mddev *mddev; /* the md device that the bitmap is for */ - - __u64 events_cleared; - int need_sync; - - struct bitmap_storage { - struct file *file; /* backing disk file */ - struct page *sb_page; /* cached copy of the bitmap - * file superblock */ - unsigned long sb_index; - struct page **filemap; /* list of cache pages for - * the file */ - unsigned long *filemap_attr; /* attributes associated - * w/ filemap pages */ - unsigned long file_pages; /* number of pages in the file*/ - unsigned long bytes; /* total bytes in the bitmap */ - } storage; - - unsigned long flags; - - int allclean; - - atomic_t behind_writes; - unsigned long behind_writes_used; /* highest actual value at runtime */ - - /* - * the bitmap daemon - periodically wakes up and sweeps the bitmap - * file, cleaning up bits and flushing out pages to disk as necessary - */ - unsigned long daemon_lastrun; /* jiffies of last run */ - unsigned long last_end_sync; /* when we lasted called end_sync to - * update bitmap with resync progress */ - - atomic_t pending_writes; /* pending writes to the bitmap file */ - wait_queue_head_t write_wait; - wait_queue_head_t overflow_wait; - wait_queue_head_t behind_wait; - - struct kernfs_node *sysfs_can_clear; - int cluster_slot; /* Slot offset for clustered env */ -}; - struct md_bitmap_stats { u64 events_cleared; int behind_writes; @@ -272,21 +96,20 @@ struct bitmap_operations { void (*cond_end_sync)(struct mddev *mddev, sector_t sector, bool force); void (*close_sync)(struct mddev *mddev); - void (*update_sb)(struct bitmap *bitmap); - int (*get_stats)(struct bitmap *bitmap, struct md_bitmap_stats *stats); + void (*update_sb)(void *data); + int (*get_stats)(void *data, struct md_bitmap_stats *stats); void (*sync_with_cluster)(struct mddev *mddev, sector_t old_lo, sector_t old_hi, sector_t new_lo, sector_t new_hi); - struct bitmap *(*get_from_slot)(struct mddev *mddev, int slot); + void *(*get_from_slot)(struct mddev *mddev, int slot); int (*copy_from_slot)(struct mddev *mddev, int slot, sector_t *lo, sector_t *hi, bool clear_bits); - void (*set_pages)(struct bitmap *bitmap, unsigned long pages); - void (*free)(struct bitmap *bitmap); + void (*set_pages)(void *data, unsigned long pages); + void (*free)(void *data); }; /* the bitmap API */ void mddev_set_bitmap_ops(struct mddev *mddev); #endif -#endif diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index 7647ce4f76fa5..6595f89becdb7 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -1144,7 +1144,7 @@ static int update_bitmap_size(struct mddev *mddev, sector_t size) static int resize_bitmaps(struct mddev *mddev, sector_t newsize, sector_t oldsize) { - struct bitmap *bitmap = mddev->bitmap; + void *bitmap = mddev->bitmap; struct md_bitmap_stats stats; unsigned long my_pages; int i, rv; @@ -1218,9 +1218,9 @@ static int cluster_check_sync_size(struct mddev *mddev) { int current_slot = md_cluster_ops->slot_number(mddev); int node_num = mddev->bitmap_info.nodes; - struct bitmap *bitmap = mddev->bitmap; struct dlm_lock_resource *bm_lockres; struct md_bitmap_stats stats; + void *bitmap = mddev->bitmap; unsigned long sync_size = 0; unsigned long my_sync_size; char str[64]; diff --git a/drivers/md/md.h b/drivers/md/md.h index e56193f71ab4e..1c6a5f41adca5 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -535,7 +535,7 @@ struct mddev { struct percpu_ref writes_pending; int sync_checkers; /* # of threads checking writes_pending */ - struct bitmap *bitmap; /* the bitmap for the device */ + void *bitmap; /* the bitmap for the device */ struct bitmap_operations *bitmap_ops; struct { struct file *file; /* the bitmap file */ diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index b15725a7a581b..f55c8e67d0593 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1412,7 +1412,6 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio, struct r1conf *conf = mddev->private; struct r1bio *r1_bio; int i, disks; - struct bitmap *bitmap = mddev->bitmap; unsigned long flags; struct md_rdev *blocked_rdev; int first_clone; @@ -1565,7 +1564,7 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio, * at a time and thus needs a new bio that can fit the whole payload * this bio in page sized chunks. */ - if (write_behind && bitmap) + if (write_behind && mddev->bitmap) max_sectors = min_t(int, max_sectors, BIO_MAX_VECS * (PAGE_SIZE >> 9)); if (max_sectors < bio_sectors(bio)) { @@ -1601,7 +1600,7 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio, * 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(bitmap, &stats); + 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);