Linux block layer
 help / color / mirror / Atom feed
From: Christoph Hellwig <hch@lst.de>
To: Song Liu <song@kernel.org>
Cc: linux-raid@vger.kernel.org, linux-block@vger.kernel.org,
	linux-fsdevel@vger.kernel.org
Subject: [PATCH 06/11] md-bitmap: refactor md_bitmap_init_from_disk
Date: Thu, 15 Jun 2023 08:48:35 +0200	[thread overview]
Message-ID: <20230615064840.629492-7-hch@lst.de> (raw)
In-Reply-To: <20230615064840.629492-1-hch@lst.de>

Split the confusing loop in md_bitmap_init_from_disk that iterates over
all chunks but also needs to read and map the pages into three separate
loops: one that iterates over the pages to read them, a second optional
one to iterate over the pages to mark them invalid if the bitmaps are
out of date, and a final one that actually iterates over the chunks.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/md/md-bitmap.c | 142 ++++++++++++++++++++---------------------
 1 file changed, 70 insertions(+), 72 deletions(-)

diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
index fa0f6ca7b61b0b..1f71683b417981 100644
--- a/drivers/md/md-bitmap.c
+++ b/drivers/md/md-bitmap.c
@@ -1065,33 +1065,31 @@ void md_bitmap_unplug_async(struct bitmap *bitmap)
 EXPORT_SYMBOL(md_bitmap_unplug_async);
 
 static void md_bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed);
-/* * bitmap_init_from_disk -- called at bitmap_create time to initialize
- * the in-memory bitmap from the on-disk bitmap -- also, sets up the
- * memory mapping of the bitmap file
- * Special cases:
- *   if there's no bitmap file, or if the bitmap file had been
- *   previously kicked from the array, we mark all the bits as
- *   1's in order to cause a full resync.
+
+/*
+ * Initialize the in-memory bitmap from the on-disk bitmap and set up the memory
+ * mapping of the bitmap file.
+ *
+ * Special case: If there's no bitmap file, or if the bitmap file had been
+ * previously kicked from the array, we mark all the bits as 1's in order to
+ * cause a full resync.
  *
  * We ignore all bits for sectors that end earlier than 'start'.
- * This is used when reading an out-of-date bitmap...
+ * This is used when reading an out-of-date bitmap.
  */
 static int md_bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
 {
-	unsigned long i, chunks, index, oldindex, bit, node_offset = 0;
-	struct page *page = NULL;
-	unsigned long bit_cnt = 0;
-	struct file *file;
-	unsigned long offset;
-	int outofdate;
-	int ret = -ENOSPC;
-	void *paddr;
+	bool outofdate = test_bit(BITMAP_STALE, &bitmap->flags);
+	struct mddev *mddev = bitmap->mddev;
+	unsigned long chunks = bitmap->counts.chunks;
 	struct bitmap_storage *store = &bitmap->storage;
+	struct file *file = store->file;
+	unsigned long node_offset = 0;
+	unsigned long bit_cnt = 0;
+	unsigned long i;
+	int ret;
 
-	chunks = bitmap->counts.chunks;
-	file = store->file;
-
-	if (!file && !bitmap->mddev->bitmap_info.offset) {
+	if (!file && !mddev->bitmap_info.offset) {
 		/* No permanent bitmap - fill with '1s'. */
 		store->filemap = NULL;
 		store->file_pages = 0;
@@ -1106,10 +1104,6 @@ static int md_bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
 		return 0;
 	}
 
-	outofdate = test_bit(BITMAP_STALE, &bitmap->flags);
-	if (outofdate)
-		pr_warn("%s: bitmap file is out of date, doing full recovery\n", bmname(bitmap));
-
 	if (file && i_size_read(file->f_mapping->host) < store->bytes) {
 		pr_warn("%s: bitmap file too short %lu < %lu\n",
 			bmname(bitmap),
@@ -1118,65 +1112,70 @@ static int md_bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
 		goto err;
 	}
 
-	oldindex = ~0L;
-	offset = 0;
-	if (!bitmap->mddev->bitmap_info.external)
-		offset = sizeof(bitmap_super_t);
-
-	if (mddev_is_clustered(bitmap->mddev))
+	if (mddev_is_clustered(mddev))
 		node_offset = bitmap->cluster_slot * (DIV_ROUND_UP(store->bytes, PAGE_SIZE));
 
-	for (i = 0; i < chunks; i++) {
-		int b;
-		index = file_page_index(&bitmap->storage, i);
-		bit = file_page_offset(&bitmap->storage, i);
-		if (index != oldindex) { /* this is a new page, read it in */
-			int count;
-			/* unmap the old page, we're done with it */
-			if (index == store->file_pages-1)
-				count = store->bytes - index * PAGE_SIZE;
-			else
-				count = PAGE_SIZE;
-			page = store->filemap[index];
-			if (file)
-				ret = read_file_page(file, index, bitmap,
-						count, page);
-			else
-				ret = read_sb_page(
-					bitmap->mddev,
-					bitmap->mddev->bitmap_info.offset,
-					page,
-					index + node_offset, count);
-
-			if (ret)
-				goto err;
+	for (i = 0; i < store->file_pages; i++) {
+		struct page *page = store->filemap[i];
+		int count;
 
-			oldindex = index;
+		/* unmap the old page, we're done with it */
+		if (i == store->file_pages - 1)
+			count = store->bytes - i * PAGE_SIZE;
+		else
+			count = PAGE_SIZE;
 
-			if (outofdate) {
-				/*
-				 * if bitmap is out of date, dirty the
-				 * whole page and write it out
-				 */
-				paddr = kmap_atomic(page);
-				memset(paddr + offset, 0xff,
-				       PAGE_SIZE - offset);
-				kunmap_atomic(paddr);
-				write_page(bitmap, page, 1);
+		if (file)
+			ret = read_file_page(file, i, bitmap, count, page);
+		else
+			ret = read_sb_page(mddev, mddev->bitmap_info.offset,
+					   page, i + node_offset, count);
+		if (ret)
+			goto err;
+	}
+
+	if (outofdate) {
+		pr_warn("%s: bitmap file is out of date, doing full recovery\n",
+			bmname(bitmap));
+
+		for (i = 0; i < store->file_pages; i++) {
+			struct page *page = store->filemap[i];
+			unsigned long offset = 0;
+			void *paddr;
+	
+			if (i == 0 && !mddev->bitmap_info.external)
+				offset = sizeof(bitmap_super_t);
+
+			/*
+			 * If the bitmap is out of date, dirty the whole page
+			 * and write it out
+			 */
+			paddr = kmap_atomic(page);
+			memset(paddr + offset, 0xff, PAGE_SIZE - offset);
+			kunmap_atomic(paddr);
 
+			write_page(bitmap, page, 1);
+			if (test_bit(BITMAP_WRITE_ERROR, &bitmap->flags)) {
 				ret = -EIO;
-				if (test_bit(BITMAP_WRITE_ERROR,
-					     &bitmap->flags))
-					goto err;
+				goto err;
 			}
 		}
+	}
+
+	for (i = 0; i < chunks; i++) {
+		struct page *page = filemap_get_page(&bitmap->storage, i);
+		unsigned long bit = file_page_offset(&bitmap->storage, i);
+		void *paddr;
+		bool was_set;
+
 		paddr = kmap_atomic(page);
 		if (test_bit(BITMAP_HOSTENDIAN, &bitmap->flags))
-			b = test_bit(bit, paddr);
+			was_set = test_bit(bit, paddr);
 		else
-			b = test_bit_le(bit, paddr);
+			was_set = test_bit_le(bit, paddr);
 		kunmap_atomic(paddr);
-		if (b) {
+
+		if (was_set) {
 			/* if the disk bit is set, set the memory bit */
 			int needed = ((sector_t)(i+1) << bitmap->counts.chunkshift
 				      >= start);
@@ -1185,7 +1184,6 @@ static int md_bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
 						  needed);
 			bit_cnt++;
 		}
-		offset = 0;
 	}
 
 	pr_debug("%s: bitmap initialized from disk: read %lu pages, set %lu of %lu bits\n",
-- 
2.39.2


  parent reply	other threads:[~2023-06-15  6:50 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-15  6:48 deprecate md bitmap file support Christoph Hellwig
2023-06-15  6:48 ` [PATCH 01/11] md-bitmap: set BITMAP_WRITE_ERROR in write_sb_page Christoph Hellwig
2023-06-15  6:56   ` Hannes Reinecke
2023-06-15 14:22   ` Johannes Thumshirn
2023-06-15 17:05   ` Himanshu Madhani
2023-06-15  6:48 ` [PATCH 02/11] md-bitmap: initialize variables at declaration time in md_bitmap_file_unmap Christoph Hellwig
2023-06-15  6:56   ` Hannes Reinecke
2023-06-15 14:23   ` Johannes Thumshirn
2023-06-15 17:05   ` Himanshu Madhani
2023-06-15  6:48 ` [PATCH 03/11] md-bitmap: use %pD to print the file name in md_bitmap_file_kick Christoph Hellwig
2023-06-15  6:58   ` Hannes Reinecke
2023-06-15 14:24   ` Johannes Thumshirn
2023-06-15 18:12   ` Himanshu Madhani
2023-06-15  6:48 ` [PATCH 04/11] md-bitmap: split file writes into a separate helper Christoph Hellwig
2023-06-15  6:59   ` Hannes Reinecke
2023-06-15 14:26   ` Johannes Thumshirn
2023-06-15 18:13   ` Himanshu Madhani
2023-06-15  6:48 ` [PATCH 05/11] md-bitmap: rename read_page to read_file_page Christoph Hellwig
2023-06-15  6:59   ` Hannes Reinecke
2023-06-15 14:38   ` Johannes Thumshirn
2023-06-15 18:14   ` Himanshu Madhani
2023-06-15  6:48 ` Christoph Hellwig [this message]
2023-06-15 21:59   ` [PATCH 06/11] md-bitmap: refactor md_bitmap_init_from_disk kernel test robot
2023-06-16  6:53     ` Song Liu
2023-06-16  7:01       ` Christoph Hellwig
2023-06-15  6:48 ` [PATCH 07/11] md-bitmap: cleanup read_sb_page Christoph Hellwig
2023-06-15  8:24   ` Hannes Reinecke
2023-06-15 14:42   ` Johannes Thumshirn
2023-06-15 18:30   ` Himanshu Madhani
2023-06-15  6:48 ` [PATCH 08/11] md-bitmap: account for mddev->bitmap_info.offset in read_sb_page Christoph Hellwig
2023-06-15  8:25   ` Hannes Reinecke
2023-06-15 18:38   ` Himanshu Madhani
2023-06-15  6:48 ` [PATCH 09/11] md-bitmap: don't use ->index for pages backing the bitmap file Christoph Hellwig
2023-06-15  8:37   ` Hannes Reinecke
2023-06-15  6:48 ` [PATCH 10/11] md: make bitmap file support optional Christoph Hellwig
2023-06-15  8:37   ` Hannes Reinecke
2023-06-15 19:37   ` Himanshu Madhani
2023-06-15  6:48 ` [PATCH 11/11] md: deprecate bitmap file support Christoph Hellwig
2023-06-15  8:38   ` Hannes Reinecke
2023-06-15 19:37   ` Himanshu Madhani
2023-06-15 19:37     ` Himanshu Madhani
2023-06-15  8:05 ` deprecate md " Mariusz Tkaczyk
2023-06-16  7:01   ` Christoph Hellwig

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230615064840.629492-7-hch@lst.de \
    --to=hch@lst.de \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-raid@vger.kernel.org \
    --cc=song@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox