diff options
author | NeilBrown <neilb@cse.unsw.edu.au> | 2005-06-21 20:17:22 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-21 22:07:45 -0400 |
commit | aa3163f81654fa057039258e32a6811147bf0c14 (patch) | |
tree | 6b0fc95fc696ebdb1f5acc78df253b6c242de430 /drivers/md | |
parent | 77ad4bc706fe6c52ab953f31c287a6af712d080c (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>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/bitmap.c | 35 |
1 files changed, 17 insertions, 18 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 86b6b037fa44..204564dc6a0d 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, | |||
897 | 897 | ||
898 | int bitmap_daemon_work(struct bitmap *bitmap) | 898 | int bitmap_daemon_work(struct bitmap *bitmap) |
899 | { | 899 | { |
900 | unsigned long bit, j; | 900 | unsigned long j; |
901 | unsigned long flags; | 901 | unsigned long flags; |
902 | struct page *page = NULL, *lastpage = NULL; | 902 | struct page *page = NULL, *lastpage = NULL; |
903 | int err = 0; | 903 | int err = 0; |
@@ -920,24 +920,23 @@ int bitmap_daemon_work(struct bitmap *bitmap) | |||
920 | } | 920 | } |
921 | 921 | ||
922 | page = filemap_get_page(bitmap, j); | 922 | page = filemap_get_page(bitmap, j); |
923 | /* skip this page unless it's marked as needing cleaning */ | ||
924 | if (!((attr=get_page_attr(bitmap, page)) & BITMAP_PAGE_CLEAN)) { | ||
925 | if (attr & BITMAP_PAGE_NEEDWRITE) { | ||
926 | page_cache_get(page); | ||
927 | clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE); | ||
928 | } | ||
929 | spin_unlock_irqrestore(&bitmap->lock, flags); | ||
930 | if (attr & BITMAP_PAGE_NEEDWRITE) { | ||
931 | if (write_page(bitmap, page, 0)) | ||
932 | bitmap_file_kick(bitmap); | ||
933 | page_cache_release(page); | ||
934 | } | ||
935 | continue; | ||
936 | } | ||
937 | |||
938 | bit = file_page_offset(j); | ||
939 | 923 | ||
940 | if (page != lastpage) { | 924 | if (page != lastpage) { |
925 | /* skip this page unless it's marked as needing cleaning */ | ||
926 | if (!((attr=get_page_attr(bitmap, page)) & BITMAP_PAGE_CLEAN)) { | ||
927 | if (attr & BITMAP_PAGE_NEEDWRITE) { | ||
928 | page_cache_get(page); | ||
929 | clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE); | ||
930 | } | ||
931 | spin_unlock_irqrestore(&bitmap->lock, flags); | ||
932 | if (attr & BITMAP_PAGE_NEEDWRITE) { | ||
933 | if (write_page(bitmap, page, 0)) | ||
934 | bitmap_file_kick(bitmap); | ||
935 | page_cache_release(page); | ||
936 | } | ||
937 | continue; | ||
938 | } | ||
939 | |||
941 | /* grab the new page, sync and release the old */ | 940 | /* grab the new page, sync and release the old */ |
942 | page_cache_get(page); | 941 | page_cache_get(page); |
943 | if (lastpage != NULL) { | 942 | if (lastpage != NULL) { |
@@ -979,7 +978,7 @@ int bitmap_daemon_work(struct bitmap *bitmap) | |||
979 | -1); | 978 | -1); |
980 | 979 | ||
981 | /* clear the bit */ | 980 | /* clear the bit */ |
982 | clear_bit(bit, page_address(page)); | 981 | clear_bit(file_page_offset(j), page_address(page)); |
983 | } | 982 | } |
984 | } | 983 | } |
985 | spin_unlock_irqrestore(&bitmap->lock, flags); | 984 | spin_unlock_irqrestore(&bitmap->lock, flags); |