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 | |
| 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>
| -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); |
