[PATCH] md: add exact bitmap mapping and reshape hooks
Yu Kuai <[email protected]>
| Newsgroups | gmane.linux.raid,gmane.linux.kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Yu Kuai <[email protected]> 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 <[email protected]> --- 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