[bug report] badblocks: improve badblocks_check() for multiple ranges handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Coly Li,

Commit 3ea3354cb9f0 ("badblocks: improve badblocks_check() for
multiple ranges handling") from Aug 12, 2023 (linux-next), leads to
the following Smatch static checker warning:

	block/badblocks.c:1251 _badblocks_check()
	warn: unsigned 'sectors' is never less than zero.

block/badblocks.c
    1186 static int _badblocks_check(struct badblocks *bb, sector_t s, sector_t sectors,
                                                                       ^^^^^^^^^^^^^^^^
sector_t is u64.

    1187                             sector_t *first_bad, sector_t *bad_sectors)
    1188 {
    1189         int prev = -1, hint = -1, set = 0;
    1190         struct badblocks_context bad;
    1191         int unacked_badblocks = 0;
    1192         int acked_badblocks = 0;
    1193         u64 *p = bb->page;
    1194         int len, rv;
    1195 
    1196 re_check:
    1197         bad.start = s;
    1198         bad.len = sectors;
    1199 
    1200         if (badblocks_empty(bb)) {
    1201                 len = sectors;
    1202                 goto update_sectors;
    1203         }
    1204 
    1205         prev = prev_badblocks(bb, &bad, hint);
    1206 
    1207         /* start after all badblocks */
    1208         if ((prev >= 0) &&
    1209             ((prev + 1) >= bb->count) && !overlap_front(bb, prev, &bad)) {
    1210                 len = sectors;
    1211                 goto update_sectors;
    1212         }
    1213 
    1214         /* Overlapped with front badblocks record */
    1215         if ((prev >= 0) && overlap_front(bb, prev, &bad)) {
    1216                 if (BB_ACK(p[prev]))
    1217                         acked_badblocks++;
    1218                 else
    1219                         unacked_badblocks++;
    1220 
    1221                 if (BB_END(p[prev]) >= (s + sectors))
    1222                         len = sectors;
    1223                 else
    1224                         len = BB_END(p[prev]) - s;
    1225 
    1226                 if (set == 0) {
    1227                         *first_bad = BB_OFFSET(p[prev]);
    1228                         *bad_sectors = BB_LEN(p[prev]);
    1229                         set = 1;
    1230                 }
    1231                 goto update_sectors;
    1232         }
    1233 
    1234         /* Not front overlap, but behind overlap */
    1235         if ((prev + 1) < bb->count && overlap_behind(bb, &bad, prev + 1)) {
    1236                 len = BB_OFFSET(p[prev + 1]) - bad.start;
    1237                 hint = prev + 1;
    1238                 goto update_sectors;
    1239         }
    1240 
    1241         /* not cover any badblocks range in the table */
    1242         len = sectors;
    1243 
    1244 update_sectors:
    1245         s += len;
    1246         sectors -= len;
                 ^^^^^^^^^^^^^^
Subtraction.

    1247 
    1248         if (sectors > 0)
    1249                 goto re_check;
    1250 
--> 1251         WARN_ON(sectors < 0);
                         ^^^^^^^^^^^

    1252 
    1253         if (unacked_badblocks > 0)
    1254                 rv = -1;
    1255         else if (acked_badblocks > 0)
    1256                 rv = 1;
    1257         else
    1258                 rv = 0;
    1259 
    1260         return rv;
    1261 }

regards,
dan carpenter




[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux