diff options
author | Nick Piggin <npiggin@suse.de> | 2009-01-06 17:39:11 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-06 18:59:00 -0500 |
commit | d5482cdf8a0aacb1e6468a97d5544f5829c8d8c4 (patch) | |
tree | 3565702c805deecd51e32ed1458f567a0064815d /mm/page-writeback.c | |
parent | 515f4a037fb9ab736f8bad733fcd2ffd350cf265 (diff) |
mm: write_cache_pages terminate quickly
Terminate the write_cache_pages loop upon encountering the first page past
end, without locking the page. Pages cannot have their index change when
we have a reference on them (truncate, eg truncate_inode_pages_range
performs the same check without the page lock).
Signed-off-by: Nick Piggin <npiggin@suse.de>
Cc: Chris Mason <chris.mason@oracle.com>
Cc: Dave Chinner <david@fromorbit.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/page-writeback.c')
-rw-r--r-- | mm/page-writeback.c | 32 |
1 files changed, 16 insertions, 16 deletions
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 2e8c2b01d5d5..0d986c13d473 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -911,15 +911,24 @@ retry: | |||
911 | for (i = 0; i < nr_pages; i++) { | 911 | for (i = 0; i < nr_pages; i++) { |
912 | struct page *page = pvec.pages[i]; | 912 | struct page *page = pvec.pages[i]; |
913 | 913 | ||
914 | done_index = page->index + 1; | ||
915 | |||
916 | /* | 914 | /* |
917 | * At this point we hold neither mapping->tree_lock nor | 915 | * At this point, the page may be truncated or |
918 | * lock on the page itself: the page may be truncated or | 916 | * invalidated (changing page->mapping to NULL), or |
919 | * invalidated (changing page->mapping to NULL), or even | 917 | * even swizzled back from swapper_space to tmpfs file |
920 | * swizzled back from swapper_space to tmpfs file | 918 | * mapping. However, page->index will not change |
921 | * mapping | 919 | * because we have a reference on the page. |
922 | */ | 920 | */ |
921 | if (page->index > end) { | ||
922 | /* | ||
923 | * can't be range_cyclic (1st pass) because | ||
924 | * end == -1 in that case. | ||
925 | */ | ||
926 | done = 1; | ||
927 | break; | ||
928 | } | ||
929 | |||
930 | done_index = page->index + 1; | ||
931 | |||
923 | lock_page(page); | 932 | lock_page(page); |
924 | 933 | ||
925 | /* | 934 | /* |
@@ -936,15 +945,6 @@ continue_unlock: | |||
936 | continue; | 945 | continue; |
937 | } | 946 | } |
938 | 947 | ||
939 | if (page->index > end) { | ||
940 | /* | ||
941 | * can't be range_cyclic (1st pass) because | ||
942 | * end == -1 in that case. | ||
943 | */ | ||
944 | done = 1; | ||
945 | goto continue_unlock; | ||
946 | } | ||
947 | |||
948 | if (!PageDirty(page)) { | 948 | if (!PageDirty(page)) { |
949 | /* someone wrote it for us */ | 949 | /* someone wrote it for us */ |
950 | goto continue_unlock; | 950 | goto continue_unlock; |