diff options
Diffstat (limited to 'drivers/md/bitmap.c')
-rw-r--r-- | drivers/md/bitmap.c | 42 |
1 files changed, 22 insertions, 20 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 1fb91edc7de2..56df1cee8fb3 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -986,6 +986,9 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) | |||
986 | oldindex = index; | 986 | oldindex = index; |
987 | oldpage = page; | 987 | oldpage = page; |
988 | 988 | ||
989 | bitmap->filemap[bitmap->file_pages++] = page; | ||
990 | bitmap->last_page_size = count; | ||
991 | |||
989 | if (outofdate) { | 992 | if (outofdate) { |
990 | /* | 993 | /* |
991 | * if bitmap is out of date, dirty the | 994 | * if bitmap is out of date, dirty the |
@@ -998,15 +1001,9 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) | |||
998 | write_page(bitmap, page, 1); | 1001 | write_page(bitmap, page, 1); |
999 | 1002 | ||
1000 | ret = -EIO; | 1003 | ret = -EIO; |
1001 | if (bitmap->flags & BITMAP_WRITE_ERROR) { | 1004 | if (bitmap->flags & BITMAP_WRITE_ERROR) |
1002 | /* release, page not in filemap yet */ | ||
1003 | put_page(page); | ||
1004 | goto err; | 1005 | goto err; |
1005 | } | ||
1006 | } | 1006 | } |
1007 | |||
1008 | bitmap->filemap[bitmap->file_pages++] = page; | ||
1009 | bitmap->last_page_size = count; | ||
1010 | } | 1007 | } |
1011 | paddr = kmap_atomic(page, KM_USER0); | 1008 | paddr = kmap_atomic(page, KM_USER0); |
1012 | if (bitmap->flags & BITMAP_HOSTENDIAN) | 1009 | if (bitmap->flags & BITMAP_HOSTENDIAN) |
@@ -1016,9 +1013,11 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) | |||
1016 | kunmap_atomic(paddr, KM_USER0); | 1013 | kunmap_atomic(paddr, KM_USER0); |
1017 | if (b) { | 1014 | if (b) { |
1018 | /* if the disk bit is set, set the memory bit */ | 1015 | /* if the disk bit is set, set the memory bit */ |
1019 | bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap), | 1016 | int needed = ((sector_t)(i+1) << (CHUNK_BLOCK_SHIFT(bitmap)) |
1020 | ((i+1) << (CHUNK_BLOCK_SHIFT(bitmap)) >= start) | 1017 | >= start); |
1021 | ); | 1018 | bitmap_set_memory_bits(bitmap, |
1019 | (sector_t)i << CHUNK_BLOCK_SHIFT(bitmap), | ||
1020 | needed); | ||
1022 | bit_cnt++; | 1021 | bit_cnt++; |
1023 | set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); | 1022 | set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); |
1024 | } | 1023 | } |
@@ -1098,14 +1097,12 @@ void bitmap_daemon_work(struct bitmap *bitmap) | |||
1098 | } | 1097 | } |
1099 | bitmap->allclean = 1; | 1098 | bitmap->allclean = 1; |
1100 | 1099 | ||
1100 | spin_lock_irqsave(&bitmap->lock, flags); | ||
1101 | for (j = 0; j < bitmap->chunks; j++) { | 1101 | for (j = 0; j < bitmap->chunks; j++) { |
1102 | bitmap_counter_t *bmc; | 1102 | bitmap_counter_t *bmc; |
1103 | spin_lock_irqsave(&bitmap->lock, flags); | 1103 | if (!bitmap->filemap) |
1104 | if (!bitmap->filemap) { | ||
1105 | /* error or shutdown */ | 1104 | /* error or shutdown */ |
1106 | spin_unlock_irqrestore(&bitmap->lock, flags); | ||
1107 | break; | 1105 | break; |
1108 | } | ||
1109 | 1106 | ||
1110 | page = filemap_get_page(bitmap, j); | 1107 | page = filemap_get_page(bitmap, j); |
1111 | 1108 | ||
@@ -1122,6 +1119,8 @@ void bitmap_daemon_work(struct bitmap *bitmap) | |||
1122 | write_page(bitmap, page, 0); | 1119 | write_page(bitmap, page, 0); |
1123 | bitmap->allclean = 0; | 1120 | bitmap->allclean = 0; |
1124 | } | 1121 | } |
1122 | spin_lock_irqsave(&bitmap->lock, flags); | ||
1123 | j |= (PAGE_BITS - 1); | ||
1125 | continue; | 1124 | continue; |
1126 | } | 1125 | } |
1127 | 1126 | ||
@@ -1154,8 +1153,9 @@ void bitmap_daemon_work(struct bitmap *bitmap) | |||
1154 | spin_lock_irqsave(&bitmap->lock, flags); | 1153 | spin_lock_irqsave(&bitmap->lock, flags); |
1155 | clear_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); | 1154 | clear_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); |
1156 | } | 1155 | } |
1157 | bmc = bitmap_get_counter(bitmap, j << CHUNK_BLOCK_SHIFT(bitmap), | 1156 | bmc = bitmap_get_counter(bitmap, |
1158 | &blocks, 0); | 1157 | (sector_t)j << CHUNK_BLOCK_SHIFT(bitmap), |
1158 | &blocks, 0); | ||
1159 | if (bmc) { | 1159 | if (bmc) { |
1160 | /* | 1160 | /* |
1161 | if (j < 100) printk("bitmap: j=%lu, *bmc = 0x%x\n", j, *bmc); | 1161 | if (j < 100) printk("bitmap: j=%lu, *bmc = 0x%x\n", j, *bmc); |
@@ -1169,7 +1169,8 @@ void bitmap_daemon_work(struct bitmap *bitmap) | |||
1169 | } else if (*bmc == 1) { | 1169 | } else if (*bmc == 1) { |
1170 | /* we can clear the bit */ | 1170 | /* we can clear the bit */ |
1171 | *bmc = 0; | 1171 | *bmc = 0; |
1172 | bitmap_count_page(bitmap, j << CHUNK_BLOCK_SHIFT(bitmap), | 1172 | bitmap_count_page(bitmap, |
1173 | (sector_t)j << CHUNK_BLOCK_SHIFT(bitmap), | ||
1173 | -1); | 1174 | -1); |
1174 | 1175 | ||
1175 | /* clear the bit */ | 1176 | /* clear the bit */ |
@@ -1180,9 +1181,10 @@ void bitmap_daemon_work(struct bitmap *bitmap) | |||
1180 | ext2_clear_bit(file_page_offset(j), paddr); | 1181 | ext2_clear_bit(file_page_offset(j), paddr); |
1181 | kunmap_atomic(paddr, KM_USER0); | 1182 | kunmap_atomic(paddr, KM_USER0); |
1182 | } | 1183 | } |
1183 | } | 1184 | } else |
1184 | spin_unlock_irqrestore(&bitmap->lock, flags); | 1185 | j |= PAGE_COUNTER_MASK; |
1185 | } | 1186 | } |
1187 | spin_unlock_irqrestore(&bitmap->lock, flags); | ||
1186 | 1188 | ||
1187 | /* now sync the final page */ | 1189 | /* now sync the final page */ |
1188 | if (lastpage != NULL) { | 1190 | if (lastpage != NULL) { |
@@ -1514,7 +1516,7 @@ void bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e) | |||
1514 | unsigned long chunk; | 1516 | unsigned long chunk; |
1515 | 1517 | ||
1516 | for (chunk = s; chunk <= e; chunk++) { | 1518 | for (chunk = s; chunk <= e; chunk++) { |
1517 | sector_t sec = chunk << CHUNK_BLOCK_SHIFT(bitmap); | 1519 | sector_t sec = (sector_t)chunk << CHUNK_BLOCK_SHIFT(bitmap); |
1518 | bitmap_set_memory_bits(bitmap, sec, 1); | 1520 | bitmap_set_memory_bits(bitmap, sec, 1); |
1519 | bitmap_file_set_bit(bitmap, sec); | 1521 | bitmap_file_set_bit(bitmap, sec); |
1520 | } | 1522 | } |