Skip to content

Commit 28243dc

Browse files
Li Nanaxboe
authored andcommitted
badblocks: return error directly when setting badblocks exceeds 512
In the current handling of badblocks settings, a lot of processing has been done for scenarios where the number of badblocks exceeds 512. This makes the code look quite complex and also introduces some issues, For example, if there is 512 badblocks already: for((i=0; i<510; i++)); do ((sector=i*2)); echo "$sector 1" > bad_blocks; done echo 2100 10 > bad_blocks echo 2200 10 > bad_blocks Set new one, exceed 512: echo 2000 500 > bad_blocks Expected: 2000 500 Actual: 2100 400 In fact, a disk shouldn't have too many badblocks, and for disks with 512 badblocks, attempting to set more bad blocks doesn't make much sense. At that point, the more appropriate action would be to replace the disk. Therefore, to resolve these issues and simplify the code somewhat, return error directly when setting badblocks exceeds 512. Fixes: aa511ff ("badblocks: switch to the improved badblock handling code") Signed-off-by: Li Nan <[email protected]> Reviewed-by: Yu Kuai <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent 32e9ad4 commit 28243dc

File tree

1 file changed

+19
-102
lines changed

1 file changed

+19
-102
lines changed

block/badblocks.c

Lines changed: 19 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -527,51 +527,6 @@ static int prev_badblocks(struct badblocks *bb, struct badblocks_context *bad,
527527
return ret;
528528
}
529529

530-
/*
531-
* Return 'true' if the range indicated by 'bad' can be backward merged
532-
* with the bad range (from the bad table) index by 'behind'.
533-
*/
534-
static bool can_merge_behind(struct badblocks *bb,
535-
struct badblocks_context *bad, int behind)
536-
{
537-
sector_t sectors = bad->len;
538-
sector_t s = bad->start;
539-
u64 *p = bb->page;
540-
541-
if ((s < BB_OFFSET(p[behind])) &&
542-
((s + sectors) >= BB_OFFSET(p[behind])) &&
543-
((BB_END(p[behind]) - s) <= BB_MAX_LEN) &&
544-
BB_ACK(p[behind]) == bad->ack)
545-
return true;
546-
return false;
547-
}
548-
549-
/*
550-
* Do backward merge for range indicated by 'bad' and the bad range
551-
* (from the bad table) indexed by 'behind'. The return value is merged
552-
* sectors from bad->len.
553-
*/
554-
static int behind_merge(struct badblocks *bb, struct badblocks_context *bad,
555-
int behind)
556-
{
557-
sector_t sectors = bad->len;
558-
sector_t s = bad->start;
559-
u64 *p = bb->page;
560-
int merged = 0;
561-
562-
WARN_ON(s >= BB_OFFSET(p[behind]));
563-
WARN_ON((s + sectors) < BB_OFFSET(p[behind]));
564-
565-
if (s < BB_OFFSET(p[behind])) {
566-
merged = BB_OFFSET(p[behind]) - s;
567-
p[behind] = BB_MAKE(s, BB_LEN(p[behind]) + merged, bad->ack);
568-
569-
WARN_ON((BB_LEN(p[behind]) + merged) >= BB_MAX_LEN);
570-
}
571-
572-
return merged;
573-
}
574-
575530
/*
576531
* Return 'true' if the range indicated by 'bad' can be forward
577532
* merged with the bad range (from the bad table) indexed by 'prev'.
@@ -884,11 +839,9 @@ static bool try_adjacent_combine(struct badblocks *bb, int prev)
884839
static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
885840
int acknowledged)
886841
{
887-
int retried = 0, space_desired = 0;
888-
int orig_len, len = 0, added = 0;
842+
int len = 0, added = 0;
889843
struct badblocks_context bad;
890844
int prev = -1, hint = -1;
891-
sector_t orig_start;
892845
unsigned long flags;
893846
int rv = 0;
894847
u64 *p;
@@ -912,8 +865,6 @@ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
912865

913866
write_seqlock_irqsave(&bb->lock, flags);
914867

915-
orig_start = s;
916-
orig_len = sectors;
917868
bad.ack = acknowledged;
918869
p = bb->page;
919870

@@ -922,6 +873,11 @@ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
922873
bad.len = sectors;
923874
len = 0;
924875

876+
if (badblocks_full(bb)) {
877+
rv = 1;
878+
goto out;
879+
}
880+
925881
if (badblocks_empty(bb)) {
926882
len = insert_at(bb, 0, &bad);
927883
bb->count++;
@@ -933,32 +889,14 @@ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
933889

934890
/* start before all badblocks */
935891
if (prev < 0) {
936-
if (!badblocks_full(bb)) {
937-
/* insert on the first */
938-
if (bad.len > (BB_OFFSET(p[0]) - bad.start))
939-
bad.len = BB_OFFSET(p[0]) - bad.start;
940-
len = insert_at(bb, 0, &bad);
941-
bb->count++;
942-
added++;
943-
hint = 0;
944-
goto update_sectors;
945-
}
946-
947-
/* No sapce, try to merge */
948-
if (overlap_behind(bb, &bad, 0)) {
949-
if (can_merge_behind(bb, &bad, 0)) {
950-
len = behind_merge(bb, &bad, 0);
951-
added++;
952-
} else {
953-
len = BB_OFFSET(p[0]) - s;
954-
space_desired = 1;
955-
}
956-
hint = 0;
957-
goto update_sectors;
958-
}
959-
960-
/* no table space and give up */
961-
goto out;
892+
/* insert on the first */
893+
if (bad.len > (BB_OFFSET(p[0]) - bad.start))
894+
bad.len = BB_OFFSET(p[0]) - bad.start;
895+
len = insert_at(bb, 0, &bad);
896+
bb->count++;
897+
added++;
898+
hint = 0;
899+
goto update_sectors;
962900
}
963901

964902
/* in case p[prev-1] can be merged with p[prev] */
@@ -978,6 +916,11 @@ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
978916
int extra = 0;
979917

980918
if (!can_front_overwrite(bb, prev, &bad, &extra)) {
919+
if (extra > 0) {
920+
rv = 1;
921+
goto out;
922+
}
923+
981924
len = min_t(sector_t,
982925
BB_END(p[prev]) - s, sectors);
983926
hint = prev;
@@ -1004,24 +947,6 @@ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
1004947
goto update_sectors;
1005948
}
1006949

1007-
/* if no space in table, still try to merge in the covered range */
1008-
if (badblocks_full(bb)) {
1009-
/* skip the cannot-merge range */
1010-
if (((prev + 1) < bb->count) &&
1011-
overlap_behind(bb, &bad, prev + 1) &&
1012-
((s + sectors) >= BB_END(p[prev + 1]))) {
1013-
len = BB_END(p[prev + 1]) - s;
1014-
hint = prev + 1;
1015-
goto update_sectors;
1016-
}
1017-
1018-
/* no retry any more */
1019-
len = sectors;
1020-
space_desired = 1;
1021-
hint = -1;
1022-
goto update_sectors;
1023-
}
1024-
1025950
/* cannot merge and there is space in bad table */
1026951
if ((prev + 1) < bb->count &&
1027952
overlap_behind(bb, &bad, prev + 1))
@@ -1049,14 +974,6 @@ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
1049974
*/
1050975
try_adjacent_combine(bb, prev);
1051976

1052-
if (space_desired && !badblocks_full(bb)) {
1053-
s = orig_start;
1054-
sectors = orig_len;
1055-
space_desired = 0;
1056-
if (retried++ < 3)
1057-
goto re_insert;
1058-
}
1059-
1060977
out:
1061978
if (added) {
1062979
set_changed(bb);

0 commit comments

Comments
 (0)