Now that XFS is no longer using find_trylock_page, the interface can be easily changed so as to take a reference as well. This looks questionable now, but streamlines the lockless implementation. Index: linux-2.6/mm/filemap.c =================================================================== --- linux-2.6.orig/mm/filemap.c +++ linux-2.6/mm/filemap.c @@ -534,7 +534,7 @@ struct page * find_get_page(struct addre EXPORT_SYMBOL(find_get_page); /* - * Same as above, but trylock it instead of incrementing the count. + * Same as above, but trylock it as well. */ struct page *find_trylock_page(struct address_space *mapping, unsigned long offset) { @@ -542,8 +542,12 @@ struct page *find_trylock_page(struct ad read_lock_irq(&mapping->tree_lock); page = radix_tree_lookup(&mapping->page_tree, offset); - if (page && TestSetPageLocked(page)) - page = NULL; + if (page) { + if (unlikely(TestSetPageLocked(page))) + page = NULL; + else + get_page(page); + } read_unlock_irq(&mapping->tree_lock); return page; } Index: linux-2.6/mm/swapfile.c =================================================================== --- linux-2.6.orig/mm/swapfile.c +++ linux-2.6/mm/swapfile.c @@ -402,7 +402,6 @@ void free_swap_and_cache(swp_entry_t ent } if (page) { BUG_ON(PagePrivate(page)); - page_cache_get(page); /* No users, or swap space full? Free it! */ if (!PageWriteback(page) && (page_mapcount(page) == 0 || vm_swap_full())) {