| Kernel v2.4.13-ac8 /mm/swap_state.c |
|---|
 2.4.13-ac8
 mm
 swap_state.c
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/mm/swap_state.c linux.ac/mm/swap_state.c
--- linux.vanilla/mm/swap_state.c Thu Oct 11 13:52:14 2001
+++ linux.ac/mm/swap_state.c Fri Nov 2 14:52:58 2001
@@ -70,18 +70,24 @@
int add_to_swap_cache(struct page *page, swp_entry_t entry)
{
+ int referenced;
+
if (page->mapping)
BUG();
if (!swap_duplicate(entry)) {
INC_CACHE_INFO(noent_race);
return -ENOENT;
}
+ page->age = PAGE_AGE_START;
+ referenced = PageReferenced(page);
if (add_to_page_cache_unique(page, &swapper_space, entry.val,
page_hash(&swapper_space, entry.val)) != 0) {
swap_free(entry);
INC_CACHE_INFO(exist_race);
return -EEXIST;
}
+ if (referenced)
+ SetPageReferenced(page);
SetPageUptodate(page);
if (!PageLocked(page))
BUG();
@@ -156,6 +162,29 @@
}
/*
+ * Like the above, but used to clean up the non-resident pages of
+ * a process. If the page exists but we couldn't get the trylock,
+ * the pageout code will remove the page later.
+ */
+void free_swap_and_swap_cache(swp_entry_t entry)
+{
+ struct page * page;
+
+ /* Free our own reference to the swap space */
+ swap_free(entry);
+
+ /* If the swapcache is the only remaining user, free that too. */
+ page = find_trylock_page(&swapper_space, entry.val);
+ if (page) {
+ if (exclusive_swap_page(page)) {
+ delete_from_swap_cache(page);
+ }
+ UnlockPage(page);
+ page_cache_release(page);
+ }
+}
+
+/*
* Lookup a swap entry in the swap cache. A found page will be returned
* unlocked and with its refcount incremented - we rely on the kernel
* lock getting page table operations atomic even if we drop the page
@@ -173,8 +202,10 @@
* that, but no need to change: we _have_ got the right page.
*/
INC_CACHE_INFO(find_total);
- if (found)
+ if (found) {
+ touch_page(found);
INC_CACHE_INFO(find_success);
+ }
return found;
}
|