Skip to content

Commit ef42567

Browse files
committed
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: NeilBrown <[email protected]>
1 parent b63d7c2 commit ef42567

File tree

1 file changed

+13
-10
lines changed

1 file changed

+13
-10
lines changed

drivers/md/bitmap.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,29 +1235,32 @@ __acquires(bitmap->lock)
12351235
unsigned long page = chunk >> PAGE_COUNTER_SHIFT;
12361236
unsigned long pageoff = (chunk & PAGE_COUNTER_MASK) << COUNTER_BYTE_SHIFT;
12371237
sector_t csize;
1238+
int err;
1239+
1240+
err = bitmap_checkpage(bitmap, page, create);
12381241

1239-
if (bitmap_checkpage(bitmap, page, create) < 0) {
1242+
if (bitmap->bp[page].hijacked ||
1243+
bitmap->bp[page].map == NULL)
1244+
csize = ((sector_t)1) << (CHUNK_BLOCK_SHIFT(bitmap) +
1245+
PAGE_COUNTER_SHIFT - 1);
1246+
else
12401247
csize = ((sector_t)1) << (CHUNK_BLOCK_SHIFT(bitmap));
1241-
*blocks = csize - (offset & (csize - 1));
1248+
*blocks = csize - (offset & (csize - 1));
1249+
1250+
if (err < 0)
12421251
return NULL;
1243-
}
1252+
12441253
/* now locked ... */
12451254

12461255
if (bitmap->bp[page].hijacked) { /* hijacked pointer */
12471256
/* should we use the first or second counter field
12481257
* of the hijacked pointer? */
12491258
int hi = (pageoff > PAGE_COUNTER_MASK);
1250-
csize = ((sector_t)1) << (CHUNK_BLOCK_SHIFT(bitmap) +
1251-
PAGE_COUNTER_SHIFT - 1);
1252-
*blocks = csize - (offset & (csize - 1));
12531259
return &((bitmap_counter_t *)
12541260
&bitmap->bp[page].map)[hi];
1255-
} else { /* page is allocated */
1256-
csize = ((sector_t)1) << (CHUNK_BLOCK_SHIFT(bitmap));
1257-
*blocks = csize - (offset & (csize - 1));
1261+
} else /* page is allocated */
12581262
return (bitmap_counter_t *)
12591263
&(bitmap->bp[page].map[pageoff]);
1260-
}
12611264
}
12621265

12631266
int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, int behind)

0 commit comments

Comments
 (0)