• Coly Li's avatar
    badblocks: improve badblocks_check() for multiple ranges handling · 3ea3354c
    Coly Li authored
    This patch rewrites badblocks_check() with similar coding style as
    _badblocks_set() and _badblocks_clear(). The only difference is bad
    blocks checking may handle multiple ranges in bad tables now.
    
    If a checking range covers multiple bad blocks range in bad block table,
    like the following condition (C is the checking range, E1, E2, E3 are
    three bad block ranges in bad block table),
      +------------------------------------+
      |                C                   |
      +------------------------------------+
        +----+      +----+      +----+
        | E1 |      | E2 |      | E3 |
        +----+      +----+      +----+
    The improved badblocks_check() algorithm will divide checking range C
    into multiple parts, and handle them in 7 runs of a while-loop,
      +--+ +----+ +----+ +----+ +----+ +----+ +----+
      |C1| | C2 | | C3 | | C4 | | C5 | | C6 | | C7 |
      +--+ +----+ +----+ +----+ +----+ +----+ +----+
           +----+        +----+        +----+
           | E1 |        | E2 |        | E3 |
           +----+        +----+        +----+
    And the start LBA and length of range E1 will be set as first_bad and
    bad_sectors for the caller.
    
    The return value rule is consistent for multiple ranges. For example if
    there are following bad block ranges in bad block table,
       Index No.     Start        Len         Ack
           0          400          20          1
           1          500          50          1
           2          650          20          0
    the return value, first_bad, bad_sectors by calling badblocks_set() with
    different checking range can be the following values,
        Checking Start, Len     Return Value   first_bad    bad_sectors
                   100, 100          0           N/A           N/A
                   100, 310          1           400           10
                   100, 440          1           400           10
                   100, 540          1           400           10
                   100, 600         -1           400           10
                   100, 800         -1           400           10
    
    In order to make code review easier, this patch names the improved bad
    block range checking routine as _badblocks_check() and does not change
    existing badblock_check() code yet. Later patch will delete old code of
    badblocks_check() and make it as a wrapper to call _badblocks_check().
    Then the new added code won't mess up with the old deleted code, it will
    be more clear and easier for code review.
    Signed-off-by: default avatarColy Li <colyli@suse.de>
    Cc: Dan Williams <dan.j.williams@intel.com>
    Cc: Geliang Tang <geliang.tang@suse.com>
    Cc: Hannes Reinecke <hare@suse.de>
    Cc: Jens Axboe <axboe@kernel.dk>
    Cc: NeilBrown <neilb@suse.de>
    Cc: Vishal L Verma <vishal.l.verma@intel.com>
    Cc: Xiao Ni <xni@redhat.com>
    Reviewed-by: default avatarXiao Ni <xni@redhat.com>
    Acked-by: default avatarGeliang Tang <geliang.tang@suse.com>
    Link: https://lore.kernel.org/r/20230811170513.2300-6-colyli@suse.deSigned-off-by: default avatarJens Axboe <axboe@kernel.dk>
    3ea3354c
badblocks.c 56.2 KB