[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250512011927.2809400-17-yukuai1@huaweicloud.com>
Date: Mon, 12 May 2025 09:19:24 +0800
From: Yu Kuai <yukuai1@...weicloud.com>
To: hch@....de,
xni@...hat.com,
colyli@...nel.org,
agk@...hat.com,
snitzer@...nel.org,
mpatocka@...hat.com,
song@...nel.org,
yukuai3@...wei.com
Cc: linux-kernel@...r.kernel.org,
dm-devel@...ts.linux.dev,
linux-raid@...r.kernel.org,
yukuai1@...weicloud.com,
yi.zhang@...wei.com,
yangerkun@...wei.com,
johnny.chenyi@...wei.com
Subject: [PATCH RFC md-6.16 v3 16/19] md/md-llbitmap: implement APIs for sync_thread
From: Yu Kuai <yukuai3@...wei.com>
Include following APIs:
- llbitmap_blocks_synced
- llbitmap_skip_sync_blocks
- llbitmap_start_sync
- llbitmap_end_sync
- llbitmap_close_sync
Signed-off-by: Yu Kuai <yukuai3@...wei.com>
---
drivers/md/md-llbitmap.c | 83 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 83 insertions(+)
diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c
index 71234c0ae160..3169ae8b72be 100644
--- a/drivers/md/md-llbitmap.c
+++ b/drivers/md/md-llbitmap.c
@@ -1076,3 +1076,86 @@ static void llbitmap_flush(struct mddev *mddev)
blk_finish_plug(&plug);
md_super_wait(llbitmap->mddev);
}
+
+/* This is used for raid5 lazy initial recovery */
+static bool llbitmap_blocks_synced(struct mddev *mddev, sector_t offset)
+{
+ struct llbitmap *llbitmap = mddev->bitmap;
+ unsigned long p = offset >> llbitmap->chunkshift;
+ enum llbitmap_state c;
+ int ret;
+
+ ret = llbitmap_read(llbitmap, &c, p);
+ if (ret < 0) {
+ set_bit(BITMAP_WRITE_ERROR, &llbitmap->flags);
+ return false;
+ }
+
+ return c == BitClean || c == BitDirty;
+}
+
+static sector_t llbitmap_skip_sync_blocks(struct mddev *mddev, sector_t offset)
+{
+ struct llbitmap *llbitmap = mddev->bitmap;
+ unsigned long p = offset >> llbitmap->chunkshift;
+ int blocks = llbitmap->chunksize - (offset & (llbitmap->chunksize - 1));
+ enum llbitmap_state c;
+ int ret;
+
+ ret = llbitmap_read(llbitmap, &c, p);
+ if (ret < 0) {
+ set_bit(BITMAP_WRITE_ERROR, &llbitmap->flags);
+ return 0;
+ }
+
+ /* always skip unwritten blocks */
+ if (c == BitUnwritten)
+ return blocks;
+
+ /* For resync also skip clean/dirty blocks */
+ if ((c == BitClean || c == BitDirty) &&
+ test_bit(MD_RECOVERY_SYNC, &mddev->recovery) &&
+ !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
+ return blocks;
+
+ return 0;
+}
+
+static bool llbitmap_start_sync(struct mddev *mddev, sector_t offset,
+ sector_t *blocks, bool degraded)
+{
+ struct llbitmap *llbitmap = mddev->bitmap;
+ unsigned long p = offset >> llbitmap->chunkshift;
+
+ /*
+ * Handle one bit at a time, this is much simpler. And it doesn't matter
+ * if md_do_sync() loop more times.
+ */
+ *blocks = llbitmap->chunksize - (offset & (llbitmap->chunksize - 1));
+ return llbitmap_state_machine(llbitmap, p, p, BitmapActionStartsync) == BitSyncing;
+}
+
+static void llbitmap_end_sync(struct mddev *mddev, sector_t offset,
+ sector_t *blocks)
+{
+ struct llbitmap *llbitmap = mddev->bitmap;
+ unsigned long p = offset >> llbitmap->chunkshift;
+
+ *blocks = llbitmap->chunksize - (offset & (llbitmap->chunksize - 1));
+ llbitmap_state_machine(llbitmap, p, llbitmap->chunks - 1, BitmapActionAbortsync);
+}
+
+static void llbitmap_close_sync(struct mddev *mddev)
+{
+ struct llbitmap *llbitmap = mddev->bitmap;
+ int i;
+
+ for (i = 0; i < llbitmap->nr_pages; i++) {
+ struct llbitmap_barrier *barrier = &llbitmap->barrier[i];
+
+ /* let daemon_fn clear dirty bits immediately */
+ WRITE_ONCE(barrier->expire, jiffies);
+ }
+
+ llbitmap_state_machine(llbitmap, 0, llbitmap->chunks - 1, BitmapActionEndsync);
+}
--
2.39.2
Powered by blists - more mailing lists