提交 ef425673 编写于 作者: N NeilBrown

md/bitmap: optimise scanning of empty bitmaps.

A bitmap is stored as one page per 2048 bits.
If none of the bits are set, the page is not allocated.

When bitmap_get_counter finds that a page isn't allocate,
it just reports that one bit work of space isn't flagged,
rather than reporting that 2048 bits worth of space are
unflagged.
This can cause searches for flagged bits (e.g. bitmap_close_sync)
to do more work than is really necessary.

So change bitmap_get_counter (when creating) to report a number of
blocks that more accurately reports the range of the device for which
no counter currently exists.
Signed-off-by: NNeilBrown <neilb@suse.de>
上级 b63d7c2e
...@@ -1235,29 +1235,32 @@ __acquires(bitmap->lock) ...@@ -1235,29 +1235,32 @@ __acquires(bitmap->lock)
unsigned long page = chunk >> PAGE_COUNTER_SHIFT; unsigned long page = chunk >> PAGE_COUNTER_SHIFT;
unsigned long pageoff = (chunk & PAGE_COUNTER_MASK) << COUNTER_BYTE_SHIFT; unsigned long pageoff = (chunk & PAGE_COUNTER_MASK) << COUNTER_BYTE_SHIFT;
sector_t csize; sector_t csize;
int err;
err = bitmap_checkpage(bitmap, page, create);
if (bitmap_checkpage(bitmap, page, create) < 0) { if (bitmap->bp[page].hijacked ||
bitmap->bp[page].map == NULL)
csize = ((sector_t)1) << (CHUNK_BLOCK_SHIFT(bitmap) +
PAGE_COUNTER_SHIFT - 1);
else
csize = ((sector_t)1) << (CHUNK_BLOCK_SHIFT(bitmap)); csize = ((sector_t)1) << (CHUNK_BLOCK_SHIFT(bitmap));
*blocks = csize - (offset & (csize - 1)); *blocks = csize - (offset & (csize - 1));
if (err < 0)
return NULL; return NULL;
}
/* now locked ... */ /* now locked ... */
if (bitmap->bp[page].hijacked) { /* hijacked pointer */ if (bitmap->bp[page].hijacked) { /* hijacked pointer */
/* should we use the first or second counter field /* should we use the first or second counter field
* of the hijacked pointer? */ * of the hijacked pointer? */
int hi = (pageoff > PAGE_COUNTER_MASK); int hi = (pageoff > PAGE_COUNTER_MASK);
csize = ((sector_t)1) << (CHUNK_BLOCK_SHIFT(bitmap) +
PAGE_COUNTER_SHIFT - 1);
*blocks = csize - (offset & (csize - 1));
return &((bitmap_counter_t *) return &((bitmap_counter_t *)
&bitmap->bp[page].map)[hi]; &bitmap->bp[page].map)[hi];
} else { /* page is allocated */ } else /* page is allocated */
csize = ((sector_t)1) << (CHUNK_BLOCK_SHIFT(bitmap));
*blocks = csize - (offset & (csize - 1));
return (bitmap_counter_t *) return (bitmap_counter_t *)
&(bitmap->bp[page].map[pageoff]); &(bitmap->bp[page].map[pageoff]);
}
} }
int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, int behind) int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, int behind)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册