drivers/md/md-bitmap.c | 8 ++++++++ drivers/md/md-bitmap.h | 8 ++++++++ drivers/md/md-llbitmap.c | 8 ++++++++ drivers/md/md.c | 12 ++++++++---- drivers/md/md.h | 4 ++++ 5 files changed, 36 insertions(+), 4 deletions(-)
From: Yu Kuai <yukuai@fygo.io>
Add bitmap mapping and reshape hooks needed by llbitmap reshape
support without teaching md core to account a single bio against
multiple bitmap ranges.
This also adds the old/new bitmap geometry helpers used by
personalities to describe reshape mapping to llbitmap.
Signed-off-by: Yu Kuai <yukuai@fygo.io>
---
drivers/md/md-bitmap.c | 8 ++++++++
drivers/md/md-bitmap.h | 8 ++++++++
drivers/md/md-llbitmap.c | 8 ++++++++
drivers/md/md.c | 12 ++++++++----
drivers/md/md.h | 4 ++++
5 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
index 028b9ca8ce52..e10296788cdd 100644
--- a/drivers/md/md-bitmap.c
+++ b/drivers/md/md-bitmap.c
@@ -1727,10 +1727,17 @@ static void bitmap_start_write(struct mddev *mddev, sector_t offset,
else
sectors = 0;
}
}
+static void bitmap_prepare_range(struct mddev *mddev, sector_t *offset,
+ unsigned long *sectors)
+{
+ if (mddev->pers->bitmap_sector)
+ mddev->pers->bitmap_sector(mddev, offset, sectors);
+}
+
static void bitmap_end_write(struct mddev *mddev, sector_t offset,
unsigned long sectors)
{
struct bitmap *bitmap = mddev->bitmap;
@@ -3075,10 +3082,11 @@ static struct bitmap_operations bitmap_ops = {
.load = bitmap_load,
.destroy = bitmap_destroy,
.flush = bitmap_flush,
.write_all = bitmap_write_all,
.dirty_bits = bitmap_dirty_bits,
+ .prepare_range = bitmap_prepare_range,
.unplug = bitmap_unplug,
.daemon_work = bitmap_daemon_work,
.start_behind_write = bitmap_start_behind_write,
.end_behind_write = bitmap_end_behind_write,
diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h
index 214f623c7e79..f0136fc02feb 100644
--- a/drivers/md/md-bitmap.h
+++ b/drivers/md/md-bitmap.h
@@ -91,10 +91,18 @@ 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);
+ /* Prepare a range for this bitmap implementation. */
+ void (*prepare_range)(struct mddev *mddev,
+ sector_t *offset,
+ unsigned long *sectors);
+ void (*reshape_finish)(struct mddev *mddev);
+ int (*reshape_can_start)(struct mddev *mddev);
+ void (*reshape_mark)(struct mddev *mddev, sector_t old_pos,
+ sector_t new_pos);
void (*unplug)(struct mddev *mddev, bool sync);
void (*daemon_work)(struct mddev *mddev);
void (*start_behind_write)(struct mddev *mddev);
void (*end_behind_write)(struct mddev *mddev);
diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c
index 1adc5b117821..bcf34f0c9af6 100644
--- a/drivers/md/md-llbitmap.c
+++ b/drivers/md/md-llbitmap.c
@@ -1186,10 +1186,17 @@ static void llbitmap_destroy(struct mddev *mddev)
llbitmap_free_pages(llbitmap);
kfree(llbitmap);
mutex_unlock(&mddev->bitmap_info.mutex);
}
+static void llbitmap_prepare_range(struct mddev *mddev, sector_t *offset,
+ unsigned long *sectors)
+{
+ if (mddev->pers->bitmap_sector)
+ mddev->pers->bitmap_sector(mddev, offset, sectors);
+}
+
static void llbitmap_start_write(struct mddev *mddev, sector_t offset,
unsigned long sectors)
{
struct llbitmap *llbitmap = mddev->bitmap;
unsigned long start = offset >> llbitmap->chunkshift;
@@ -1775,10 +1782,11 @@ static struct bitmap_operations llbitmap_ops = {
.cond_end_sync = llbitmap_cond_end_sync,
.update_sb = llbitmap_update_sb,
.get_stats = llbitmap_get_stats,
.dirty_bits = llbitmap_dirty_bits,
+ .prepare_range = llbitmap_prepare_range,
.write_all = llbitmap_write_all,
.groups = md_llbitmap_groups,
};
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 096bb64e87bd..08eabc7e5a71 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -9359,21 +9359,25 @@ void md_submit_discard_bio(struct mddev *mddev, struct md_rdev *rdev,
mddev_trace_remap(mddev, discard_bio, bio->bi_iter.bi_sector);
submit_bio_noacct(discard_bio);
}
EXPORT_SYMBOL_GPL(md_submit_discard_bio);
+static void md_bitmap_prepare_range(struct mddev *mddev, sector_t *offset,
+ unsigned long *sectors)
+{
+ mddev->bitmap_ops->prepare_range(mddev, offset, sectors);
+}
+
static void md_bitmap_start(struct mddev *mddev,
struct md_io_clone *md_io_clone)
{
md_bitmap_fn *fn = unlikely(md_io_clone->rw == STAT_DISCARD) ?
mddev->bitmap_ops->start_discard :
mddev->bitmap_ops->start_write;
- if (mddev->pers->bitmap_sector)
- mddev->pers->bitmap_sector(mddev, &md_io_clone->offset,
- &md_io_clone->sectors);
-
+ md_bitmap_prepare_range(mddev, &md_io_clone->offset,
+ &md_io_clone->sectors);
fn(mddev, md_io_clone->offset, md_io_clone->sectors);
}
static void md_bitmap_end(struct mddev *mddev, struct md_io_clone *md_io_clone)
{
diff --git a/drivers/md/md.h b/drivers/md/md.h
index d8daf0f75cbb..110cf0f8b107 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -796,10 +796,14 @@ struct md_personality
/* Changes the consistency policy of an active array. */
int (*change_consistency_policy)(struct mddev *mddev, const char *buf);
/* convert io ranges from array to bitmap */
void (*bitmap_sector)(struct mddev *mddev, sector_t *offset,
unsigned long *sectors);
+ void (*bitmap_sector_map)(struct mddev *mddev, sector_t *offset,
+ unsigned long *sectors, bool previous);
+ sector_t (*bitmap_sync_size)(struct mddev *mddev, bool previous);
+ sector_t (*bitmap_array_sectors)(struct mddev *mddev, bool previous);
};
struct md_sysfs_entry {
struct attribute attr;
ssize_t (*show)(struct mddev *, char *);
--
2.51.0
© 2016 - 2026 Red Hat, Inc.