Commit 93fac7041f082297b93655a0e49f659cd7520e40
Committed by
Linus Torvalds
1 parent
9bf9e89c3d
Exists in
master
and in
7 other branches
[PATCH] mm: schedule find_trylock_page() removal
find_trylock_page() is an odd interface in that it doesn't take a reference like the others. Now that XFS no longer uses it, and its last remaining caller actually wants an elevated refcount, opencode that callsite and schedule find_trylock_page() for removal. Signed-off-by: Nick Piggin <npiggin@suse.de> Acked-by: Hugh Dickins <hugh@veritas.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Showing 3 changed files with 24 additions and 6 deletions Side-by-side Diff
Documentation/feature-removal-schedule.txt
... | ... | @@ -241,4 +241,16 @@ |
241 | 241 | Who: Greg Kroah-Hartman <gregkh@suse.de> |
242 | 242 | |
243 | 243 | --------------------------- |
244 | + | |
245 | +What: find_trylock_page | |
246 | +When: January 2007 | |
247 | +Why: The interface no longer has any callers left in the kernel. It | |
248 | + is an odd interface (compared with other find_*_page functions), in | |
249 | + that it does not take a refcount to the page, only the page lock. | |
250 | + It should be replaced with find_get_page or find_lock_page if possible. | |
251 | + This feature removal can be reevaluated if users of the interface | |
252 | + cannot cleanly use something else. | |
253 | +Who: Nick Piggin <npiggin@suse.de> | |
254 | + | |
255 | +--------------------------- |
include/linux/pagemap.h
... | ... | @@ -72,8 +72,8 @@ |
72 | 72 | unsigned long index); |
73 | 73 | extern struct page * find_lock_page(struct address_space *mapping, |
74 | 74 | unsigned long index); |
75 | -extern struct page * find_trylock_page(struct address_space *mapping, | |
76 | - unsigned long index); | |
75 | +extern __deprecated_for_modules struct page * find_trylock_page( | |
76 | + struct address_space *mapping, unsigned long index); | |
77 | 77 | extern struct page * find_or_create_page(struct address_space *mapping, |
78 | 78 | unsigned long index, gfp_t gfp_mask); |
79 | 79 | unsigned find_get_pages(struct address_space *mapping, pgoff_t start, |
mm/swapfile.c
... | ... | @@ -397,18 +397,24 @@ |
397 | 397 | |
398 | 398 | p = swap_info_get(entry); |
399 | 399 | if (p) { |
400 | - if (swap_entry_free(p, swp_offset(entry)) == 1) | |
401 | - page = find_trylock_page(&swapper_space, entry.val); | |
400 | + if (swap_entry_free(p, swp_offset(entry)) == 1) { | |
401 | + page = find_get_page(&swapper_space, entry.val); | |
402 | + if (page && unlikely(TestSetPageLocked(page))) { | |
403 | + page_cache_release(page); | |
404 | + page = NULL; | |
405 | + } | |
406 | + } | |
402 | 407 | spin_unlock(&swap_lock); |
403 | 408 | } |
404 | 409 | if (page) { |
405 | 410 | int one_user; |
406 | 411 | |
407 | 412 | BUG_ON(PagePrivate(page)); |
408 | - page_cache_get(page); | |
409 | 413 | one_user = (page_count(page) == 2); |
410 | 414 | /* Only cache user (+us), or swap space full? Free it! */ |
411 | - if (!PageWriteback(page) && (one_user || vm_swap_full())) { | |
415 | + /* Also recheck PageSwapCache after page is locked (above) */ | |
416 | + if (PageSwapCache(page) && !PageWriteback(page) && | |
417 | + (one_user || vm_swap_full())) { | |
412 | 418 | delete_from_swap_cache(page); |
413 | 419 | SetPageDirty(page); |
414 | 420 | } |