]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
md/bitmap: md_bitmap_get_counter returns wrong blocks
authorZhao Heming <heming.zhao@suse.com>
Mon, 5 Oct 2020 16:00:24 +0000 (00:00 +0800)
committerSong Liu <songliubraving@fb.com>
Fri, 9 Oct 2020 05:31:29 +0000 (22:31 -0700)
md_bitmap_get_counter() has code:

```
    if (bitmap->bp[page].hijacked ||
        bitmap->bp[page].map == NULL)
        csize = ((sector_t)1) << (bitmap->chunkshift +
                      PAGE_COUNTER_SHIFT - 1);
```

The minus 1 is wrong, this branch should report 2048 bits of space.
With "-1" action, this only report 1024 bit of space.

This bug code returns wrong blocks, but it doesn't inflence bitmap logic:
1. Most callers focus this function return value (the counter of offset),
   not the parameter blocks.
2. The bug is only triggered when hijacked is true or map is NULL.
   the hijacked true condition is very rare.
   the "map == null" only true when array is creating or resizing.
3. Even the caller gets wrong blocks, current code makes caller just to
   call md_bitmap_get_counter() one more time.

Signed-off-by: Zhao Heming <heming.zhao@suse.com>
Signed-off-by: Song Liu <songliubraving@fb.com>
drivers/md/md-bitmap.c

index cd9a12ca281d314eda056f9f379b57f7df7c35d3..b3f13105659dd5e5201aa4630cd3b59737a93664 100644 (file)
@@ -1368,7 +1368,7 @@ __acquires(bitmap->lock)
        if (bitmap->bp[page].hijacked ||
            bitmap->bp[page].map == NULL)
                csize = ((sector_t)1) << (bitmap->chunkshift +
-                                         PAGE_COUNTER_SHIFT - 1);
+                                         PAGE_COUNTER_SHIFT);
        else
                csize = ((sector_t)1) << bitmap->chunkshift;
        *blocks = csize - (offset & (csize - 1));