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.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 41df4cda66e2..2925219f0881 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -520,6 +520,8 @@ success:
520 bitmap->daemon_sleep = daemon_sleep; 520 bitmap->daemon_sleep = daemon_sleep;
521 bitmap->flags |= sb->state; 521 bitmap->flags |= sb->state;
522 bitmap->events_cleared = le64_to_cpu(sb->events_cleared); 522 bitmap->events_cleared = le64_to_cpu(sb->events_cleared);
523 if (sb->state & BITMAP_STALE)
524 bitmap->events_cleared = bitmap->mddev->events;
523 err = 0; 525 err = 0;
524out: 526out:
525 kunmap(bitmap->sb_page); 527 kunmap(bitmap->sb_page);
@@ -818,7 +820,7 @@ int bitmap_unplug(struct bitmap *bitmap)
818 return 0; 820 return 0;
819} 821}
820 822
821static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset); 823static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed);
822/* * bitmap_init_from_disk -- called at bitmap_create time to initialize 824/* * bitmap_init_from_disk -- called at bitmap_create time to initialize
823 * the in-memory bitmap from the on-disk bitmap -- also, sets up the 825 * the in-memory bitmap from the on-disk bitmap -- also, sets up the
824 * memory mapping of the bitmap file 826 * memory mapping of the bitmap file
@@ -826,8 +828,11 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset);
826 * if there's no bitmap file, or if the bitmap file had been 828 * if there's no bitmap file, or if the bitmap file had been
827 * previously kicked from the array, we mark all the bits as 829 * previously kicked from the array, we mark all the bits as
828 * 1's in order to cause a full resync. 830 * 1's in order to cause a full resync.
831 *
832 * We ignore all bits for sectors that end earlier than 'start'.
833 * This is used when reading an out-of-date bitmap...
829 */ 834 */
830static int bitmap_init_from_disk(struct bitmap *bitmap) 835static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
831{ 836{
832 unsigned long i, chunks, index, oldindex, bit; 837 unsigned long i, chunks, index, oldindex, bit;
833 struct page *page = NULL, *oldpage = NULL; 838 struct page *page = NULL, *oldpage = NULL;
@@ -914,7 +919,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap)
914 * whole page and write it out 919 * whole page and write it out
915 */ 920 */
916 memset(page_address(page) + offset, 0xff, 921 memset(page_address(page) + offset, 0xff,
917 PAGE_SIZE - offset); 922 PAGE_SIZE - offset);
918 ret = write_page(bitmap, page, 1); 923 ret = write_page(bitmap, page, 1);
919 if (ret) { 924 if (ret) {
920 kunmap(page); 925 kunmap(page);
@@ -928,8 +933,11 @@ static int bitmap_init_from_disk(struct bitmap *bitmap)
928 } 933 }
929 if (test_bit(bit, page_address(page))) { 934 if (test_bit(bit, page_address(page))) {
930 /* if the disk bit is set, set the memory bit */ 935 /* if the disk bit is set, set the memory bit */
931 bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap)); 936 bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap),
937 ((i+1) << (CHUNK_BLOCK_SHIFT(bitmap)) >= start)
938 );
932 bit_cnt++; 939 bit_cnt++;
940 set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
933 } 941 }
934 } 942 }
935 943
@@ -1424,7 +1432,7 @@ void bitmap_close_sync(struct bitmap *bitmap)
1424 } 1432 }
1425} 1433}
1426 1434
1427static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset) 1435static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed)
1428{ 1436{
1429 /* For each chunk covered by any of these sectors, set the 1437 /* For each chunk covered by any of these sectors, set the
1430 * counter to 1 and set resync_needed. They should all 1438 * counter to 1 and set resync_needed. They should all
@@ -1441,7 +1449,7 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset)
1441 } 1449 }
1442 if (! *bmc) { 1450 if (! *bmc) {
1443 struct page *page; 1451 struct page *page;
1444 *bmc = 1 | NEEDED_MASK; 1452 *bmc = 1 | (needed?NEEDED_MASK:0);
1445 bitmap_count_page(bitmap, offset, 1); 1453 bitmap_count_page(bitmap, offset, 1);
1446 page = filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap)); 1454 page = filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap));
1447 set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); 1455 set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
@@ -1517,6 +1525,7 @@ int bitmap_create(mddev_t *mddev)
1517 unsigned long pages; 1525 unsigned long pages;
1518 struct file *file = mddev->bitmap_file; 1526 struct file *file = mddev->bitmap_file;
1519 int err; 1527 int err;
1528 sector_t start;
1520 1529
1521 BUG_ON(sizeof(bitmap_super_t) != 256); 1530 BUG_ON(sizeof(bitmap_super_t) != 256);
1522 1531
@@ -1581,7 +1590,12 @@ int bitmap_create(mddev_t *mddev)
1581 1590
1582 /* now that we have some pages available, initialize the in-memory 1591 /* now that we have some pages available, initialize the in-memory
1583 * bitmap from the on-disk bitmap */ 1592 * bitmap from the on-disk bitmap */
1584 err = bitmap_init_from_disk(bitmap); 1593 start = 0;
1594 if (mddev->degraded == 0
1595 || bitmap->events_cleared == mddev->events)
1596 /* no need to keep dirty bits to optimise a re-add of a missing device */
1597 start = mddev->recovery_cp;
1598 err = bitmap_init_from_disk(bitmap, start);
1585 1599
1586 if (err) 1600 if (err)
1587 return err; 1601 return err;