[v2,09/11] block/badblocks: factor out a helper to combine badblocks

Message ID 20230504124828.679770-10-linan666@huaweicloud.com
State New
Headers
Series block/badblocks: fix badblocks setting error |

Commit Message

Li Nan May 4, 2023, 12:48 p.m. UTC
  From: Li Nan <linan122@huawei.com>

Add a helper badblocks_combine() to combine badblocks, it makes code more
readable. No functional change.

Signed-off-by: Li Nan <linan122@huawei.com>
---
 block/badblocks.c | 87 ++++++++++++++++++++++++++---------------------
 1 file changed, 48 insertions(+), 39 deletions(-)
  

Patch

diff --git a/block/badblocks.c b/block/badblocks.c
index f498fae201a1..c87c68d4bcac 100644
--- a/block/badblocks.c
+++ b/block/badblocks.c
@@ -218,6 +218,51 @@  static int badblocks_merge(struct badblocks *bb, sector_t s, int sectors,
 	return merged_sectors;
 }
 
+/*
+ * try to combine lo and hi(lo + 1) if lo intersects with hi
+ */
+static void badblocks_combine(struct badblocks *bb, int lo)
+{
+	u64 *p = bb->page;
+	sector_t loe = BB_OFFSET(p[lo]) + BB_LEN(p[lo]);
+	int hi = lo + 1;
+
+	if (hi >= bb->count)
+		return;
+	/* we might be able to combine lo and hi */
+
+	if (loe >= BB_OFFSET(p[hi])) {
+		sector_t loa = BB_OFFSET(p[lo]), hia = BB_OFFSET(p[hi]);
+		sector_t hie = hia + BB_LEN(p[hi]);
+		int newlen = max(loe, hie) - loa;
+		int ack = BB_ACK(p[lo]) && BB_ACK(p[hi]);
+
+		while (loe >= hie) {
+			/* lo contains hi, just remove hi */
+			memmove(p + hi, p + hi + 1,
+				(bb->count - hi - 1) * 8);
+			bb->count--;
+			if (hi >= bb->count)
+				break;
+			hia = BB_OFFSET(p[hi]);
+			hie = hia + BB_LEN(p[hi]);
+		}
+		if (loe >= hia && hi < bb->count) {
+			if (newlen > BB_MAX_LEN) {
+				p[lo] = BB_MAKE(loa, BB_MAX_LEN, ack);
+				p[hi] = BB_MAKE(loa + BB_MAX_LEN,
+						newlen - BB_MAX_LEN,
+						BB_ACK(p[hi]));
+			} else {
+				p[lo] = BB_MAKE(loa, newlen, ack);
+				memmove(p + hi, p + hi + 1,
+					(bb->count - hi - 1) * 8);
+				bb->count--;
+			}
+		}
+	}
+}
+
 /**
  * badblocks_set() - Add a range of bad blocks to the table.
  * @bb:		the badblocks structure that holds all badblock information
@@ -262,16 +307,13 @@  int badblocks_set(struct badblocks *bb, sector_t s, int sectors,
 	lo = 0;
 	hi = bb->count;
 	if (bb->count) {
-		sector_t a;
-		sector_t e;
-		int ack;
 		int merged_sectors;
 
 		/* Find the last range that starts at-or-before 's' */
 		while (hi - lo > 1) {
 			int mid = (lo + hi) / 2;
+			int a = BB_OFFSET(p[mid]);
 
-			a = BB_OFFSET(p[mid]);
 			if (a <= s)
 				lo = mid;
 			else
@@ -282,41 +324,8 @@  int badblocks_set(struct badblocks *bb, sector_t s, int sectors,
 						 &lo, &hi, &changed);
 		s += merged_sectors;
 		sectors -= merged_sectors;
-		if (sectors == 0 && hi < bb->count) {
-			/* we might be able to combine lo and hi */
-			/* Note: 's' is at the end of 'lo' */
-			sector_t loa = BB_OFFSET(p[lo]), hia = BB_OFFSET(p[hi]);
-			sector_t hie = hia + BB_LEN(p[hi]);
-			int newlen = max(s, hie) - loa;
-
-			ack = BB_ACK(p[lo]) && BB_ACK(p[hi]);
-			if (s >= hia) {
-				while (s >= hie) {
-					/* lo contains hi, just remove hi */
-					memmove(p + hi, p + hi + 1,
-						(bb->count - hi - 1) * 8);
-					bb->count--;
-					if (hi >= bb->count)
-						break;
-					hia = BB_OFFSET(p[hi]);
-					hie = hia + BB_LEN(p[hi]);
-				}
-				if (s >= hia && hi < bb->count) {
-					if (newlen > BB_MAX_LEN) {
-						p[lo] = BB_MAKE(loa, BB_MAX_LEN, ack);
-						p[hi] = BB_MAKE(loa + BB_MAX_LEN,
-								newlen - BB_MAX_LEN,
-								BB_ACK(p[hi]));
-					} else {
-						p[lo] = BB_MAKE(loa, newlen, ack);
-						memmove(p + hi, p + hi + 1,
-							(bb->count - hi - 1) * 8);
-						bb->count--;
-					}
-				}
-				changed = true;
-			}
-		}
+		if (sectors == 0)
+			badblocks_combine(bb, lo);
 	}
 	while (sectors) {
 		/* didn't merge (it all).