## Automatically generated incremental diff
## From:   linux-2.4.14-pre4
## To:     linux-2.4.14-pre5
## Robot:  $Id: make-incremental-diff,v 1.8 2001/12/04 06:05:04 hpa Exp $

diff -urN linux-2.4.14-pre4/include/linux/mm.h linux/include/linux/mm.h
--- linux-2.4.14-pre4/include/linux/mm.h	Mon Dec  3 23:24:03 2001
+++ linux/include/linux/mm.h	Mon Dec  3 23:24:18 2001
@@ -466,20 +466,7 @@
 	return page_count(page) - !!page->buffers == 1;
 }
 
-/*
- * Work out if there are any other processes sharing this
- * swap cache page. Never mind the buffers.
- */
-static inline int exclusive_swap_page(struct page *page)
-{
-	if (!PageLocked(page))
-		BUG();
-	if (!PageSwapCache(page))
-		return 0;
-	if (page_count(page) - !!page->buffers != 2)	/* 2: us + cache */
-		return 0;
-	return swap_count(page) == 1;			/* 1: just cache */
-}
+extern int remove_exclusive_swap_page(struct page *);
 
 extern void __free_pte(pte_t);
 
diff -urN linux-2.4.14-pre4/include/linux/pagemap.h linux/include/linux/pagemap.h
--- linux-2.4.14-pre4/include/linux/pagemap.h	Mon Dec  3 23:24:03 2001
+++ linux/include/linux/pagemap.h	Mon Dec  3 23:24:18 2001
@@ -29,7 +29,7 @@
 #define PAGE_CACHE_ALIGN(addr)	(((addr)+PAGE_CACHE_SIZE-1)&PAGE_CACHE_MASK)
 
 #define page_cache_get(x)	get_page(x)
-#define page_cache_release(x)	__free_page(x)
+#define page_cache_release(x)	free_lru_page(x)
 
 static inline struct page *page_cache_alloc(struct address_space *x)
 {
diff -urN linux-2.4.14-pre4/mm/memory.c linux/mm/memory.c
--- linux-2.4.14-pre4/mm/memory.c	Mon Dec  3 23:24:03 2001
+++ linux/mm/memory.c	Mon Dec  3 23:24:18 2001
@@ -939,9 +939,7 @@
 		if (TryLockPage(old_page))
 			break;
 		/* Recheck swapcachedness once the page is locked */
-		can_reuse = exclusive_swap_page(old_page);
-		if (can_reuse)
-			delete_from_swap_cache(old_page);
+		can_reuse = remove_exclusive_swap_page(old_page);
 		UnlockPage(old_page);
 		if (!can_reuse)
 			break;
@@ -965,7 +963,7 @@
 	if (!new_page)
 		goto no_mem;
 	copy_cow_page(old_page,new_page,address);
-	free_lru_page(old_page);
+	page_cache_release(old_page);
 
 	/*
 	 * Re-check the pte - we dropped the lock
@@ -981,7 +979,7 @@
 		new_page = old_page;
 	}
 	spin_unlock(&mm->page_table_lock);
-	free_lru_page(new_page);
+	page_cache_release(new_page);
 	return 1;	/* Minor fault */
 
 bad_wp_page:
@@ -989,7 +987,7 @@
 	printk("do_wp_page: bogus page at address %08lx (page 0x%lx)\n",address,(unsigned long)old_page);
 	return -1;
 no_mem:
-	free_lru_page(old_page);
+	page_cache_release(old_page);
 	return -1;
 }
 
@@ -1150,7 +1148,6 @@
 	 */
 	spin_lock(&mm->page_table_lock);
 	if (!pte_same(*page_table, orig_pte)) {
-		UnlockPage(page);
 		page_cache_release(page);
 		spin_unlock(&mm->page_table_lock);
 		return 1;
@@ -1283,7 +1280,7 @@
 		set_pte(page_table, entry);
 	} else {
 		/* One of our sibling threads was faster, back out. */
-		free_lru_page(new_page);
+		page_cache_release(new_page);
 		spin_unlock(&mm->page_table_lock);
 		return 1;
 	}
diff -urN linux-2.4.14-pre4/mm/swap_state.c linux/mm/swap_state.c
--- linux-2.4.14-pre4/mm/swap_state.c	Mon Dec  3 23:24:03 2001
+++ linux/mm/swap_state.c	Mon Dec  3 23:24:18 2001
@@ -137,11 +137,10 @@
 	 * 					- Marcelo
 	 */
 	if (PageSwapCache(page) && !TryLockPage(page)) {
-		if (exclusive_swap_page(page))
-			delete_from_swap_cache(page);
+		remove_exclusive_swap_page(page);
 		UnlockPage(page);
 	}
-	free_lru_page(page);
+	page_cache_release(page);
 }
 
 /*
diff -urN linux-2.4.14-pre4/mm/swapfile.c linux/mm/swapfile.c
--- linux-2.4.14-pre4/mm/swapfile.c	Mon Dec  3 23:24:03 2001
+++ linux/mm/swapfile.c	Mon Dec  3 23:24:18 2001
@@ -224,6 +224,50 @@
 }
 
 /*
+ * Work out if there are any other processes sharing this
+ * swap cache page. Free it if you can. Return success.
+ */
+int remove_exclusive_swap_page(struct page *page)
+{
+	int retval;
+	struct swap_info_struct * p;
+	swp_entry_t entry;
+
+	if (!PageLocked(page))
+		BUG();
+	if (!PageSwapCache(page))
+		return 0;
+	if (page_count(page) - !!page->buffers != 2)	/* 2: us + cache */
+		return 0;
+
+	entry.val = page->index;
+	p = swap_info_get(entry);
+	if (!p)
+		return 0;
+
+	/* Is the only swap cache user the cache itself? */
+	retval = 0;
+	if (p->swap_map[SWP_OFFSET(entry)] == 1) {
+		/* Recheck the page count with the pagecache lock held.. */
+		spin_lock(&pagecache_lock);
+		if (page_count(page) - !!page->buffers == 2) {
+			__delete_from_swap_cache(page);
+			retval = 1;
+		}
+		spin_unlock(&pagecache_lock);
+	}
+	swap_info_put(p);
+
+	if (retval) {
+		block_flushpage(page, 0);
+		swap_free(entry);
+		page_cache_release(page);
+	}
+
+	return retval;
+}
+
+/*
  * Free the swap entry like above, but also try to
  * free the page cache entry if it is the last user.
  */
@@ -242,7 +286,7 @@
 		page_cache_get(page);
 		delete_from_swap_cache(page);
 		UnlockPage(page);
-		free_lru_page(page);
+		page_cache_release(page);
 	}
 }
 
@@ -582,7 +626,7 @@
 		 */
 		SetPageDirty(page);
 		UnlockPage(page);
-		free_lru_page(page);
+		page_cache_release(page);
 
 		/*
 		 * Make sure that we aren't completely killing
