aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/bitmap.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@cse.unsw.edu.au>2005-09-09 19:23:44 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 19:39:09 -0400
commit6a07997fc34ac15a1c5dc650285d79b7604a2276 (patch)
tree7b16fb2b399e5f331ff899b21c5213b4bb35ef88 /drivers/md/bitmap.c
parent1923b99a0f4748aa6be0b9b9523ce224a3449b17 (diff)
[PATCH] md: improve handling of bitmap initialisation.
When we find a 'stale' bitmap, possibly because it is new, we should just assume every bit needs to be set, but rather base the setting of bits on the current state of the array (degraded and recovery_cp). Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
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;