|
@@ -454,8 +454,11 @@ void bitmap_update_sb(struct bitmap *bitmap)
|
|
spin_unlock_irqrestore(&bitmap->lock, flags);
|
|
spin_unlock_irqrestore(&bitmap->lock, flags);
|
|
sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0);
|
|
sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0);
|
|
sb->events = cpu_to_le64(bitmap->mddev->events);
|
|
sb->events = cpu_to_le64(bitmap->mddev->events);
|
|
- if (!bitmap->mddev->degraded)
|
|
|
|
- sb->events_cleared = cpu_to_le64(bitmap->mddev->events);
|
|
|
|
|
|
+ if (bitmap->mddev->events < bitmap->events_cleared) {
|
|
|
|
+ /* rocking back to read-only */
|
|
|
|
+ bitmap->events_cleared = bitmap->mddev->events;
|
|
|
|
+ sb->events_cleared = cpu_to_le64(bitmap->events_cleared);
|
|
|
|
+ }
|
|
kunmap_atomic(sb, KM_USER0);
|
|
kunmap_atomic(sb, KM_USER0);
|
|
write_page(bitmap, bitmap->sb_page, 1);
|
|
write_page(bitmap, bitmap->sb_page, 1);
|
|
}
|
|
}
|
|
@@ -1085,9 +1088,19 @@ void bitmap_daemon_work(struct bitmap *bitmap)
|
|
} else
|
|
} else
|
|
spin_unlock_irqrestore(&bitmap->lock, flags);
|
|
spin_unlock_irqrestore(&bitmap->lock, flags);
|
|
lastpage = page;
|
|
lastpage = page;
|
|
-/*
|
|
|
|
- printk("bitmap clean at page %lu\n", j);
|
|
|
|
-*/
|
|
|
|
|
|
+
|
|
|
|
+ /* We are possibly going to clear some bits, so make
|
|
|
|
+ * sure that events_cleared is up-to-date.
|
|
|
|
+ */
|
|
|
|
+ if (bitmap->need_sync) {
|
|
|
|
+ bitmap_super_t *sb;
|
|
|
|
+ bitmap->need_sync = 0;
|
|
|
|
+ sb = kmap_atomic(bitmap->sb_page, KM_USER0);
|
|
|
|
+ sb->events_cleared =
|
|
|
|
+ cpu_to_le64(bitmap->events_cleared);
|
|
|
|
+ kunmap_atomic(sb, KM_USER0);
|
|
|
|
+ write_page(bitmap, bitmap->sb_page, 1);
|
|
|
|
+ }
|
|
spin_lock_irqsave(&bitmap->lock, flags);
|
|
spin_lock_irqsave(&bitmap->lock, flags);
|
|
clear_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
|
|
clear_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
|
|
}
|
|
}
|
|
@@ -1257,6 +1270,12 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (success &&
|
|
|
|
+ bitmap->events_cleared < bitmap->mddev->events) {
|
|
|
|
+ bitmap->events_cleared = bitmap->mddev->events;
|
|
|
|
+ bitmap->need_sync = 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
if (!success && ! (*bmc & NEEDED_MASK))
|
|
if (!success && ! (*bmc & NEEDED_MASK))
|
|
*bmc |= NEEDED_MASK;
|
|
*bmc |= NEEDED_MASK;
|
|
|
|
|