From 6a5b31cefeb0d93cf4611171eef66c9a3d73f2d4 Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Sat, 28 Jun 2008 08:31:22 +1000 Subject: [PATCH] --- yaml --- r: 104233 b: refs/heads/master c: a0da84f35b25875870270d16b6eccda4884d61a7 h: refs/heads/master i: 104231: fcdcea1cca5c1b9e531c7940944734b602095f89 v: v3 --- [refs] | 2 +- trunk/drivers/md/bitmap.c | 29 ++++++++++++++++++++++++----- trunk/include/linux/raid/bitmap.h | 1 + 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/[refs] b/[refs] index 7837a993f3c8..073108293b73 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 0e13fe23a00ad88c737d91d94a050707c6139ce4 +refs/heads/master: a0da84f35b25875870270d16b6eccda4884d61a7 diff --git a/trunk/drivers/md/bitmap.c b/trunk/drivers/md/bitmap.c index b26927ce889c..dedba16d42f7 100644 --- a/trunk/drivers/md/bitmap.c +++ b/trunk/drivers/md/bitmap.c @@ -454,8 +454,11 @@ void bitmap_update_sb(struct bitmap *bitmap) spin_unlock_irqrestore(&bitmap->lock, flags); sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0); 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); write_page(bitmap, bitmap->sb_page, 1); } @@ -1085,9 +1088,19 @@ void bitmap_daemon_work(struct bitmap *bitmap) } else spin_unlock_irqrestore(&bitmap->lock, flags); 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); 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; } + if (success && + bitmap->events_cleared < bitmap->mddev->events) { + bitmap->events_cleared = bitmap->mddev->events; + bitmap->need_sync = 1; + } + if (!success && ! (*bmc & NEEDED_MASK)) *bmc |= NEEDED_MASK; diff --git a/trunk/include/linux/raid/bitmap.h b/trunk/include/linux/raid/bitmap.h index 78bfdea24a8e..e98900671ca9 100644 --- a/trunk/include/linux/raid/bitmap.h +++ b/trunk/include/linux/raid/bitmap.h @@ -221,6 +221,7 @@ struct bitmap { unsigned long syncchunk; __u64 events_cleared; + int need_sync; /* bitmap spinlock */ spinlock_t lock;