drivers/md/md-llbitmap.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
From: Yu Kuai <yukuai@fygo.io>
Track llbitmap's own sync_size instead of always using
mddev->resync_max_sectors directly.
This is the minimal bookkeeping needed before llbitmap can track old
and new reshape geometry independently.
Signed-off-by: Yu Kuai <yukuai@fygo.io>
---
drivers/md/md-llbitmap.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c
index bcf34f0c9af6..ecf3ed712315 100644
--- a/drivers/md/md-llbitmap.c
+++ b/drivers/md/md-llbitmap.c
@@ -285,10 +285,12 @@ struct llbitmap {
unsigned long chunkshift;
/* size of one chunk in sector */
unsigned long chunksize;
/* total number of chunks */
unsigned long chunks;
+ /* total number of sectors tracked by current bitmap geometry */
+ sector_t sync_size;
unsigned long last_end_sync;
/*
* time in seconds that dirty bits will be cleared if the page is not
* accessed.
*/
@@ -916,10 +918,11 @@ static int llbitmap_init(struct llbitmap *llbitmap)
llbitmap->barrier_idle = DEFAULT_BARRIER_IDLE;
llbitmap->chunkshift = ffz(~chunksize);
llbitmap->chunksize = chunksize;
llbitmap->chunks = chunks;
+ llbitmap->sync_size = blocks;
mddev->bitmap_info.daemon_sleep = DEFAULT_DAEMON_SLEEP;
ret = llbitmap_cache_pages(llbitmap);
if (ret)
return ret;
@@ -936,10 +939,11 @@ static int llbitmap_read_sb(struct llbitmap *llbitmap)
{
struct mddev *mddev = llbitmap->mddev;
unsigned long daemon_sleep;
unsigned long chunksize;
unsigned long events;
+ sector_t sync_size;
struct page *sb_page;
bitmap_super_t *sb;
int ret = -EINVAL;
if (!mddev->bitmap_info.offset) {
@@ -985,10 +989,13 @@ static int llbitmap_read_sb(struct llbitmap *llbitmap)
if (test_and_clear_bit(BITMAP_FIRST_USE, &llbitmap->flags)) {
ret = llbitmap_init(llbitmap);
goto out_put_page;
}
+ sync_size = le64_to_cpu(sb->sync_size);
+ if (!sync_size)
+ sync_size = mddev->resync_max_sectors;
chunksize = le32_to_cpu(sb->chunksize);
if (!is_power_of_2(chunksize)) {
pr_err("md/llbitmap: %s: chunksize not a power of 2",
mdname(mddev));
goto out_put_page;
@@ -1020,12 +1027,13 @@ static int llbitmap_read_sb(struct llbitmap *llbitmap)
mddev->bitmap_info.chunksize = chunksize;
mddev->bitmap_info.daemon_sleep = daemon_sleep;
llbitmap->barrier_idle = DEFAULT_BARRIER_IDLE;
llbitmap->chunksize = chunksize;
- llbitmap->chunks = DIV_ROUND_UP_SECTOR_T(mddev->resync_max_sectors, chunksize);
+ llbitmap->chunks = DIV_ROUND_UP_SECTOR_T(sync_size, chunksize);
llbitmap->chunkshift = ffz(~chunksize);
+ llbitmap->sync_size = sync_size;
ret = llbitmap_cache_pages(llbitmap);
out_put_page:
__free_page(sb_page);
kunmap_local(sb);
@@ -1151,10 +1159,11 @@ static int llbitmap_resize(struct mddev *mddev, sector_t blocks, int chunksize)
}
llbitmap->chunkshift = ffz(~chunksize);
llbitmap->chunksize = chunksize;
llbitmap->chunks = chunks;
+ llbitmap->sync_size = blocks;
return 0;
}
static int llbitmap_load(struct mddev *mddev)
@@ -1524,11 +1533,11 @@ static void llbitmap_update_sb(void *data)
sb = kmap_local_page(sb_page);
sb->events = cpu_to_le64(mddev->events);
sb->state = cpu_to_le32(llbitmap->flags);
sb->chunksize = cpu_to_le32(llbitmap->chunksize);
- sb->sync_size = cpu_to_le64(mddev->resync_max_sectors);
+ sb->sync_size = cpu_to_le64(llbitmap->sync_size);
sb->events_cleared = cpu_to_le64(llbitmap->events_cleared);
sb->sectors_reserved = cpu_to_le32(mddev->bitmap_info.space);
sb->daemon_sleep = cpu_to_le32(mddev->bitmap_info.daemon_sleep);
kunmap_local(sb);
@@ -1542,10 +1551,11 @@ static int llbitmap_get_stats(void *data, struct md_bitmap_stats *stats)
memset(stats, 0, sizeof(*stats));
stats->missing_pages = 0;
stats->pages = llbitmap->nr_pages;
stats->file_pages = llbitmap->nr_pages;
+ stats->sync_size = llbitmap->sync_size;
stats->behind_writes = atomic_read(&llbitmap->behind_writes);
stats->behind_wait = wq_has_sleeper(&llbitmap->behind_wait);
stats->events_cleared = llbitmap->events_cleared;
--
2.51.0
© 2016 - 2026 Red Hat, Inc.