mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 03:35:32 -04:00
md/md-llbitmap: track target reshape geometry fields
Track llbitmap bookkeeping for the target reshape geometry while keeping a single live bitmap instance. Add the reshape geometry fields, refresh helper, and update the load and resize paths to keep the target geometry in sync. Tested-by: Mykola Marzhan <mykola@meshstor.io> Link: https://patch.msgid.link/20260802195038.164272-17-yukuai@kernel.org Signed-off-by: Yu Kuai <yukuai@fygo.io>
This commit is contained in:
@@ -289,6 +289,9 @@ struct llbitmap {
|
||||
unsigned long chunks;
|
||||
/* total number of sectors tracked by current bitmap geometry */
|
||||
sector_t sync_size;
|
||||
unsigned long reshape_chunksize;
|
||||
unsigned long reshape_chunks;
|
||||
sector_t reshape_sync_size;
|
||||
unsigned long last_end_sync;
|
||||
/*
|
||||
* time in seconds that dirty bits will be cleared if the page is not
|
||||
@@ -430,6 +433,39 @@ static void llbitmap_calculate_chunks(struct mddev *mddev, sector_t blocks,
|
||||
}
|
||||
}
|
||||
|
||||
static bool llbitmap_reshaping(struct llbitmap *llbitmap)
|
||||
{
|
||||
return llbitmap->mddev->reshape_position != MaxSector;
|
||||
}
|
||||
|
||||
static sector_t llbitmap_personality_sync_size(struct llbitmap *llbitmap,
|
||||
bool previous)
|
||||
{
|
||||
struct mddev *mddev = llbitmap->mddev;
|
||||
|
||||
if (!llbitmap_reshaping(llbitmap) || !mddev->private || !mddev->pers ||
|
||||
!mddev->pers->bitmap_sync_size)
|
||||
return llbitmap->sync_size;
|
||||
return mddev->pers->bitmap_sync_size(mddev, previous);
|
||||
}
|
||||
|
||||
static void llbitmap_refresh_reshape(struct llbitmap *llbitmap)
|
||||
{
|
||||
unsigned long old_chunks = DIV_ROUND_UP_SECTOR_T(llbitmap->sync_size,
|
||||
llbitmap->chunksize);
|
||||
sector_t blocks = llbitmap_personality_sync_size(llbitmap, false);
|
||||
unsigned long chunksize = llbitmap->chunksize;
|
||||
unsigned long chunks = DIV_ROUND_UP_SECTOR_T(blocks, chunksize);
|
||||
|
||||
llbitmap->reshape_sync_size = blocks;
|
||||
llbitmap->reshape_chunksize = chunksize;
|
||||
llbitmap->reshape_chunks = chunks;
|
||||
llbitmap_calculate_chunks(llbitmap->mddev, blocks,
|
||||
&llbitmap->reshape_chunksize,
|
||||
&llbitmap->reshape_chunks);
|
||||
llbitmap->chunks = max(old_chunks, llbitmap->reshape_chunks);
|
||||
}
|
||||
|
||||
static enum llbitmap_state llbitmap_read(struct llbitmap *llbitmap, loff_t pos)
|
||||
{
|
||||
unsigned int idx;
|
||||
@@ -1030,6 +1066,7 @@ static int llbitmap_init(struct llbitmap *llbitmap)
|
||||
llbitmap->chunksize = chunksize;
|
||||
llbitmap->chunks = chunks;
|
||||
llbitmap->sync_size = blocks;
|
||||
llbitmap_refresh_reshape(llbitmap);
|
||||
mddev->bitmap_info.daemon_sleep = DEFAULT_DAEMON_SLEEP;
|
||||
|
||||
ret = llbitmap_alloc_pages(llbitmap);
|
||||
@@ -1146,6 +1183,7 @@ static int llbitmap_read_sb(struct llbitmap *llbitmap)
|
||||
llbitmap->chunks = DIV_ROUND_UP_SECTOR_T(sync_size, chunksize);
|
||||
llbitmap->chunkshift = ffz(~chunksize);
|
||||
llbitmap->sync_size = sync_size;
|
||||
llbitmap_refresh_reshape(llbitmap);
|
||||
ret = llbitmap_alloc_pages(llbitmap);
|
||||
|
||||
out_put_page:
|
||||
@@ -1302,6 +1340,9 @@ static int llbitmap_resize(struct mddev *mddev, sector_t blocks, int chunksize)
|
||||
goto out;
|
||||
|
||||
if (reshape) {
|
||||
llbitmap->reshape_sync_size = blocks;
|
||||
llbitmap->reshape_chunksize = bitmap_chunksize;
|
||||
llbitmap->reshape_chunks = chunks;
|
||||
llbitmap->chunks = max(old_chunks, chunks);
|
||||
} else {
|
||||
if (blocks < old_blocks && chunks < old_chunks)
|
||||
@@ -1310,6 +1351,7 @@ static int llbitmap_resize(struct mddev *mddev, sector_t blocks, int chunksize)
|
||||
mddev->bitmap_info.chunksize = bitmap_chunksize;
|
||||
llbitmap->chunks = chunks;
|
||||
llbitmap->sync_size = blocks;
|
||||
llbitmap_refresh_reshape(llbitmap);
|
||||
llbitmap_update_sb(llbitmap);
|
||||
}
|
||||
__llbitmap_flush(mddev);
|
||||
|
||||
Reference in New Issue
Block a user