aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/bitmap.c')
-rw-r--r--drivers/md/bitmap.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 719943763391..8fa3277f72dc 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -111,9 +111,10 @@ static int bitmap_checkpage(struct bitmap *bitmap, unsigned long page, int creat
111 unsigned char *mappage; 111 unsigned char *mappage;
112 112
113 if (page >= bitmap->pages) { 113 if (page >= bitmap->pages) {
114 printk(KERN_ALERT 114 /* This can happen if bitmap_start_sync goes beyond
115 "%s: invalid bitmap page request: %lu (> %lu)\n", 115 * End-of-device while looking for a whole page.
116 bmname(bitmap), page, bitmap->pages-1); 116 * It is harmless.
117 */
117 return -EINVAL; 118 return -EINVAL;
118 } 119 }
119 120
@@ -570,7 +571,7 @@ static int bitmap_read_sb(struct bitmap *bitmap)
570 else if (le32_to_cpu(sb->version) < BITMAP_MAJOR_LO || 571 else if (le32_to_cpu(sb->version) < BITMAP_MAJOR_LO ||
571 le32_to_cpu(sb->version) > BITMAP_MAJOR_HI) 572 le32_to_cpu(sb->version) > BITMAP_MAJOR_HI)
572 reason = "unrecognized superblock version"; 573 reason = "unrecognized superblock version";
573 else if (chunksize < PAGE_SIZE) 574 else if (chunksize < 512)
574 reason = "bitmap chunksize too small"; 575 reason = "bitmap chunksize too small";
575 else if ((1 << ffz(~chunksize)) != chunksize) 576 else if ((1 << ffz(~chunksize)) != chunksize)
576 reason = "bitmap chunksize not a power of 2"; 577 reason = "bitmap chunksize not a power of 2";
@@ -1345,8 +1346,8 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto
1345 } 1346 }
1346} 1347}
1347 1348
1348int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks, 1349static int __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
1349 int degraded) 1350 int degraded)
1350{ 1351{
1351 bitmap_counter_t *bmc; 1352 bitmap_counter_t *bmc;
1352 int rv; 1353 int rv;
@@ -1374,6 +1375,29 @@ int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
1374 return rv; 1375 return rv;
1375} 1376}
1376 1377
1378int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
1379 int degraded)
1380{
1381 /* bitmap_start_sync must always report on multiples of whole
1382 * pages, otherwise resync (which is very PAGE_SIZE based) will
1383 * get confused.
1384 * So call __bitmap_start_sync repeatedly (if needed) until
1385 * At least PAGE_SIZE>>9 blocks are covered.
1386 * Return the 'or' of the result.
1387 */
1388 int rv = 0;
1389 int blocks1;
1390
1391 *blocks = 0;
1392 while (*blocks < (PAGE_SIZE>>9)) {
1393 rv |= __bitmap_start_sync(bitmap, offset,
1394 &blocks1, degraded);
1395 offset += blocks1;
1396 *blocks += blocks1;
1397 }
1398 return rv;
1399}
1400
1377void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted) 1401void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted)
1378{ 1402{
1379 bitmap_counter_t *bmc; 1403 bitmap_counter_t *bmc;