aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/bitmap.c29
-rw-r--r--include/linux/raid/bitmap.h1
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;