From: Li Nan <linan122@xxxxxxxxxx> Add a helper badblocks_combine() to combine badblocks, it makes code more readable. No functional change. Signed-off-by: Li Nan <linan122@xxxxxxxxxx> --- block/badblocks.c | 87 ++++++++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 39 deletions(-) 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). -- 2.31.1