aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neilb@cse.unsw.edu.au>2005-06-21 17:17:22 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-21 19:07:45 -0700
commitaa3163f81654fa057039258e32a6811147bf0c14 (patch)
tree6b0fc95fc696ebdb1f5acc78df253b6c242de430
parent77ad4bc706fe6c52ab953f31c287a6af712d080c (diff)
[PATCH] md: don't skip bitmap pages due to lack of bit that we just cleared.
When looking for pages that need cleaning we skip pages that don't have BITMAP_PAGE_CLEAN set. But if it is the 'current' page we will have cleared that bit ourselves, so skipping it is wrong. So: move the 'skip this page' inside 'if page != lastpage'. Also fold call of file_page_offset into the one place where the value (bit) is used. Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/md/bitmap.c35
1 files changed, 17 insertions, 18 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 86b6b037fa4..204564dc6a0 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -897,7 +897,7 @@ static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap,
int bitmap_daemon_work(struct bitmap *bitmap)
{
- unsigned long bit, j;
+ unsigned long j;
unsigned long flags;
struct page *page = NULL, *lastpage = NULL;
int err = 0;
@@ -920,24 +920,23 @@ int bitmap_daemon_work(struct bitmap *bitmap)
}
page = filemap_get_page(bitmap, j);
- /* skip this page unless it's marked as needing cleaning */
- if (!((attr=get_page_attr(bitmap, page)) & BITMAP_PAGE_CLEAN)) {
- if (attr & BITMAP_PAGE_NEEDWRITE) {
- page_cache_get(page);
- clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE);
- }
- spin_unlock_irqrestore(&bitmap->lock, flags);
- if (attr & BITMAP_PAGE_NEEDWRITE) {
- if (write_page(bitmap, page, 0))
- bitmap_file_kick(bitmap);
- page_cache_release(page);
- }
- continue;
- }
-
- bit = file_page_offset(j);
if (page != lastpage) {
+ /* skip this page unless it's marked as needing cleaning */
+ if (!((attr=get_page_attr(bitmap, page)) & BITMAP_PAGE_CLEAN)) {
+ if (attr & BITMAP_PAGE_NEEDWRITE) {
+ page_cache_get(page);
+ clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE);
+ }
+ spin_unlock_irqrestore(&bitmap->lock, flags);
+ if (attr & BITMAP_PAGE_NEEDWRITE) {
+ if (write_page(bitmap, page, 0))
+ bitmap_file_kick(bitmap);
+ page_cache_release(page);
+ }
+ continue;
+ }
+
/* grab the new page, sync and release the old */
page_cache_get(page);
if (lastpage != NULL) {
@@ -979,7 +978,7 @@ int bitmap_daemon_work(struct bitmap *bitmap)
-1);
/* clear the bit */
- clear_bit(bit, page_address(page));
+ clear_bit(file_page_offset(j), page_address(page));
}
}
spin_unlock_irqrestore(&bitmap->lock, flags);