diff options
-rw-r--r-- | drivers/md/bitmap.c | 29 | ||||
-rw-r--r-- | include/linux/raid/bitmap.h | 1 |
2 files changed, 25 insertions, 5 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index b26927ce889..dedba16d42f 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -454,8 +454,11 @@ void bitmap_update_sb(struct bitmap *bitmap) | |||
454 | spin_unlock_irqrestore(&bitmap->lock, flags); | 454 | spin_unlock_irqrestore(&bitmap->lock, flags); |
455 | sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0); | 455 | sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0); |
456 | sb->events = cpu_to_le64(bitmap->mddev->events); | 456 | sb->events = cpu_to_le64(bitmap->mddev->events); |
457 | if (!bitmap->mddev->degraded) | 457 | if (bitmap->mddev->events < bitmap->events_cleared) { |
458 | sb->events_cleared = cpu_to_le64(bitmap->mddev->events); | 458 | /* rocking back to read-only */ |
459 | bitmap->events_cleared = bitmap->mddev->events; | ||
460 | sb->events_cleared = cpu_to_le64(bitmap->events_cleared); | ||
461 | } | ||
459 | kunmap_atomic(sb, KM_USER0); | 462 | kunmap_atomic(sb, KM_USER0); |
460 | write_page(bitmap, bitmap->sb_page, 1); | 463 | write_page(bitmap, bitmap->sb_page, 1); |
461 | } | 464 | } |
@@ -1085,9 +1088,19 @@ void bitmap_daemon_work(struct bitmap *bitmap) | |||
1085 | } else | 1088 | } else |
1086 | spin_unlock_irqrestore(&bitmap->lock, flags); | 1089 | spin_unlock_irqrestore(&bitmap->lock, flags); |
1087 | lastpage = page; | 1090 | lastpage = page; |
1088 | /* | 1091 | |
1089 | printk("bitmap clean at page %lu\n", j); | 1092 | /* We are possibly going to clear some bits, so make |
1090 | */ | 1093 | * sure that events_cleared is up-to-date. |
1094 | */ | ||
1095 | if (bitmap->need_sync) { | ||
1096 | bitmap_super_t *sb; | ||
1097 | bitmap->need_sync = 0; | ||
1098 | sb = kmap_atomic(bitmap->sb_page, KM_USER0); | ||
1099 | sb->events_cleared = | ||
1100 | cpu_to_le64(bitmap->events_cleared); | ||
1101 | kunmap_atomic(sb, KM_USER0); | ||
1102 | write_page(bitmap, bitmap->sb_page, 1); | ||
1103 | } | ||
1091 | spin_lock_irqsave(&bitmap->lock, flags); | 1104 | spin_lock_irqsave(&bitmap->lock, flags); |
1092 | clear_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); | 1105 | clear_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); |
1093 | } | 1106 | } |
@@ -1257,6 +1270,12 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto | |||
1257 | return; | 1270 | return; |
1258 | } | 1271 | } |
1259 | 1272 | ||
1273 | if (success && | ||
1274 | bitmap->events_cleared < bitmap->mddev->events) { | ||
1275 | bitmap->events_cleared = bitmap->mddev->events; | ||
1276 | bitmap->need_sync = 1; | ||
1277 | } | ||
1278 | |||
1260 | if (!success && ! (*bmc & NEEDED_MASK)) | 1279 | if (!success && ! (*bmc & NEEDED_MASK)) |
1261 | *bmc |= NEEDED_MASK; | 1280 | *bmc |= NEEDED_MASK; |
1262 | 1281 | ||
diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h index 78bfdea24a8..e98900671ca 100644 --- a/include/linux/raid/bitmap.h +++ b/include/linux/raid/bitmap.h | |||
@@ -221,6 +221,7 @@ struct bitmap { | |||
221 | unsigned long syncchunk; | 221 | unsigned long syncchunk; |
222 | 222 | ||
223 | __u64 events_cleared; | 223 | __u64 events_cleared; |
224 | int need_sync; | ||
224 | 225 | ||
225 | /* bitmap spinlock */ | 226 | /* bitmap spinlock */ |
226 | spinlock_t lock; | 227 | spinlock_t lock; |