@@ -855,6 +855,31 @@ static void badblocks_update_acked(struct badblocks *bb)
855855 bb -> unacked_exist = 0 ;
856856}
857857
858+ /*
859+ * Return 'true' if the range indicated by 'bad' is exactly backward
860+ * overlapped with the bad range (from bad table) indexed by 'behind'.
861+ */
862+ static bool try_adjacent_combine (struct badblocks * bb , int prev )
863+ {
864+ u64 * p = bb -> page ;
865+
866+ if (prev >= 0 && (prev + 1 ) < bb -> count &&
867+ BB_END (p [prev ]) == BB_OFFSET (p [prev + 1 ]) &&
868+ (BB_LEN (p [prev ]) + BB_LEN (p [prev + 1 ])) <= BB_MAX_LEN &&
869+ BB_ACK (p [prev ]) == BB_ACK (p [prev + 1 ])) {
870+ p [prev ] = BB_MAKE (BB_OFFSET (p [prev ]),
871+ BB_LEN (p [prev ]) + BB_LEN (p [prev + 1 ]),
872+ BB_ACK (p [prev ]));
873+
874+ if ((prev + 2 ) < bb -> count )
875+ memmove (p + prev + 1 , p + prev + 2 ,
876+ (bb -> count - (prev + 2 )) * 8 );
877+ bb -> count -- ;
878+ return true;
879+ }
880+ return false;
881+ }
882+
858883/* Do exact work to set bad block range into the bad block table */
859884static int _badblocks_set (struct badblocks * bb , sector_t s , int sectors ,
860885 int acknowledged )
@@ -1022,20 +1047,7 @@ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
10221047 * merged. (prev < 0) condition is not handled here,
10231048 * because it's already complicated enough.
10241049 */
1025- if (prev >= 0 &&
1026- (prev + 1 ) < bb -> count &&
1027- BB_END (p [prev ]) == BB_OFFSET (p [prev + 1 ]) &&
1028- (BB_LEN (p [prev ]) + BB_LEN (p [prev + 1 ])) <= BB_MAX_LEN &&
1029- BB_ACK (p [prev ]) == BB_ACK (p [prev + 1 ])) {
1030- p [prev ] = BB_MAKE (BB_OFFSET (p [prev ]),
1031- BB_LEN (p [prev ]) + BB_LEN (p [prev + 1 ]),
1032- BB_ACK (p [prev ]));
1033-
1034- if ((prev + 2 ) < bb -> count )
1035- memmove (p + prev + 1 , p + prev + 2 ,
1036- (bb -> count - (prev + 2 )) * 8 );
1037- bb -> count -- ;
1038- }
1050+ try_adjacent_combine (bb , prev );
10391051
10401052 if (space_desired && !badblocks_full (bb )) {
10411053 s = orig_start ;
0 commit comments