Re: [PATCH] badblocks: fix overlapping check for clearing

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

 



On Thu, Oct 6, 2016 at 9:50 PM, NeilBrown <neilb@xxxxxxxx> wrote:
> On Tue, Sep 06 2016, Tomasz Majchrzak wrote:
>
>> Current bad block clear implementation assumes the range to clear
>> overlaps with at least one bad block already stored. If given range to
>> clear precedes first bad block in a list, the first entry is incorrectly
>> updated.
>
> In the original md context, it would only ever be called on a block that
> was already in the list.
> But you are right that it is best not to assume this, and to code more
> safely.
>
>
>
>>
>> Check not only if stored block end is past clear block end but also if
>> stored block start is before clear block end.
>>
>> Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@xxxxxxxxx>
>
> Dan Williams seems to have taken responsibility for this code through
> his nvdimm tree, so I've added him to 'cc' in the hope that he looks at
> this (I wonder if he is even on linux-block ....)

I am, but I missed this, thanks for the cc.

>
>
>> ---
>>  block/badblocks.c | 6 ++++--
>>  1 file changed, 4 insertions(+), 2 deletions(-)
>>
>> diff --git a/block/badblocks.c b/block/badblocks.c
>> index 7be53cb..b2ffcc7 100644
>> --- a/block/badblocks.c
>> +++ b/block/badblocks.c
>> @@ -354,7 +354,8 @@ int badblocks_clear(struct badblocks *bb, sector_t s, int sectors)
>>                * current range.  Earlier ranges could also overlap,
>>                * but only this one can overlap the end of the range.
>>                */
>> -             if (BB_OFFSET(p[lo]) + BB_LEN(p[lo]) > target) {
>> +             if ((BB_OFFSET(p[lo]) + BB_LEN(p[lo]) > target) &&
>> +                 (BB_OFFSET(p[lo]) <= target)) {
>
> hmmm..
> 'target' is the sector just beyond the set of sectors to remove from the
> list.
> BB_OFFSET(p[lo]) is the first sector in a range that was found in the
> list.
> If these are equal, then are aren't clearing anything in this range.
> So I would have '<', not '<='.
>
> I don't think this makes the code wrong as we end up assigning to p[lo]
> the value that is already there.  But it might be confusing.
>
>
>>                       /* Partial overlap, leave the tail of this range */
>>                       int ack = BB_ACK(p[lo]);
>>                       sector_t a = BB_OFFSET(p[lo]);
>> @@ -377,7 +378,8 @@ int badblocks_clear(struct badblocks *bb, sector_t s, int sectors)
>>                       lo--;
>>               }
>>               while (lo >= 0 &&
>> -                    BB_OFFSET(p[lo]) + BB_LEN(p[lo]) > s) {
>> +                    (BB_OFFSET(p[lo]) + BB_LEN(p[lo]) > s) &&
>> +                    (BB_OFFSET(p[lo]) <= target)) {
>
> Ditto.
>
> But the code is, I think, correct. Just not how I would have written it.
> So
>
>  Acked-by: NeilBrown <neilb@xxxxxxxx>

I agree with the comments to change "<=" to "<".  Tomasz, care to
re-send with those changes?
--
To unsubscribe from this list: send the line "unsubscribe linux-block" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[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