diff -urN 2.4.4pre6/include/linux/pagemap.h swapcachelookup/include/linux/pagemap.h
--- 2.4.4pre6/include/linux/pagemap.h	Tue Apr 24 14:01:18 2001
+++ swapcachelookup/include/linux/pagemap.h	Tue Apr 24 16:23:52 2001
@@ -77,7 +77,12 @@
 				unsigned long index, struct page **hash);
 extern void lock_page(struct page *page);
 #define find_lock_page(mapping, index) \
-		__find_lock_page(mapping, index, page_hash(mapping, index))
+	__find_lock_page(mapping, index, page_hash(mapping, index))
+
+extern struct page * __find_get_swapcache_page (int wait, struct address_space * mapping,
+				unsigned long index, struct page **hash);
+#define find_get_swapcache_page(wait, mapping, index) \
+	__find_get_swapcache_page(wait, mapping, index, page_hash(mapping, index))
 
 extern void __add_page_to_hash_queue(struct page * page, struct page **p);
 
diff -urN 2.4.4pre6/include/linux/swap.h swapcachelookup/include/linux/swap.h
--- 2.4.4pre6/include/linux/swap.h	Tue Apr 24 06:15:40 2001
+++ swapcachelookup/include/linux/swap.h	Tue Apr 24 16:23:52 2001
@@ -120,7 +120,7 @@
 extern void show_swap_cache_info(void);
 extern void add_to_swap_cache(struct page *, swp_entry_t);
 extern int swap_check_entry(unsigned long);
-extern struct page * lookup_swap_cache(swp_entry_t);
+extern struct page * lookup_swap_cache(swp_entry_t, int);
 extern struct page * read_swap_cache_async(swp_entry_t, int);
 #define read_swap_cache(entry) read_swap_cache_async(entry, 1);
 
diff -urN 2.4.4pre6/mm/filemap.c swapcachelookup/mm/filemap.c
--- 2.4.4pre6/mm/filemap.c	Sat Apr 21 20:04:24 2001
+++ swapcachelookup/mm/filemap.c	Tue Apr 24 16:23:52 2001
@@ -678,6 +678,43 @@
 }
 
 /*
+ * Find a swapcache page (and get a reference) or return NULL.
+ * The SwapCache check is protected by the pagecache lock.
+ */
+struct page * __find_get_swapcache_page(int wait, struct address_space *mapping,
+			      unsigned long offset, struct page **hash)
+{
+	struct page *page;
+
+	/*
+	 * We need the LRU lock to protect against page_launder().
+	 */
+repeat:
+	spin_lock(&pagecache_lock);
+	page = __find_page_nolock(mapping, offset, *hash);
+	if (page) {
+		spin_lock(&pagemap_lru_lock);
+		if (PageSwapCache(page)) {
+			page_cache_get(page);
+			if (!Page_Uptodate(page) && PageLocked(page) && wait) {
+				spin_unlock(&pagemap_lru_lock);
+				spin_unlock(&pagecache_lock);
+				___wait_on_page(page);
+				page_cache_release(page);
+				goto repeat;
+			}
+			if (wait && (!Page_Uptodate(page) && PageLocked(page)))
+				printk(KERN_ERR "hm: page not uptodate in __find_get_swapcache_page()? page flags: %08lx\n", page->flags);
+		} else
+			page = NULL;
+		spin_unlock(&pagemap_lru_lock);
+	}
+	spin_unlock(&pagecache_lock);
+
+	return page;
+}
+
+/*
  * Same as the above, but lock the page too, verifying that
  * it's still valid once we own it.
  */
diff -urN 2.4.4pre6/mm/memory.c swapcachelookup/mm/memory.c
--- 2.4.4pre6/mm/memory.c	Sat Apr 21 20:04:24 2001
+++ swapcachelookup/mm/memory.c	Tue Apr 24 16:23:52 2001
@@ -1059,7 +1059,7 @@
 	pte_t pte;
 
 	spin_unlock(&mm->page_table_lock);
-	page = lookup_swap_cache(entry);
+	page = lookup_swap_cache(entry, 1);
 	if (!page) {
 		lock_kernel();
 		swapin_readahead(entry);
diff -urN 2.4.4pre6/mm/shmem.c swapcachelookup/mm/shmem.c
--- 2.4.4pre6/mm/shmem.c	Sat Apr 21 20:04:24 2001
+++ swapcachelookup/mm/shmem.c	Tue Apr 24 16:23:52 2001
@@ -123,7 +123,7 @@
 		entry = *ptr;
 		*ptr = (swp_entry_t){0};
 		freed++;
-		if ((page = lookup_swap_cache(entry)) != NULL) {
+		if ((page = lookup_swap_cache(entry, 1)) != NULL) {
 			delete_from_swap_cache(page);
 			page_cache_release(page);	
 		}
diff -urN 2.4.4pre6/mm/swap_state.c swapcachelookup/mm/swap_state.c
--- 2.4.4pre6/mm/swap_state.c	Sat Apr 21 20:04:24 2001
+++ swapcachelookup/mm/swap_state.c	Tue Apr 24 16:23:52 2001
@@ -152,7 +152,7 @@
  * lock before returning.
  */
 
-struct page * lookup_swap_cache(swp_entry_t entry)
+struct page * lookup_swap_cache(swp_entry_t entry, int wait)
 {
 	struct page *found;
 
@@ -163,37 +163,18 @@
 		/*
 		 * Right now the pagecache is 32-bit only.  But it's a 32 bit index. =)
 		 */
-repeat:
-		found = find_lock_page(&swapper_space, entry.val);
+		found = find_get_swapcache_page(wait, &swapper_space, entry.val);
 		if (!found)
 			return 0;
-		/*
-		 * Though the "found" page was in the swap cache an instant
-		 * earlier, it might have been removed by refill_inactive etc.
-		 * Re search ... Since find_lock_page grabs a reference on
-		 * the page, it can not be reused for anything else, namely
-		 * it can not be associated with another swaphandle, so it
-		 * is enough to check whether the page is still in the scache.
-		 */
-		if (!PageSwapCache(found)) {
-			UnlockPage(found);
-			page_cache_release(found);
-			goto repeat;
-		}
+		if (!PageSwapCache(found))
+			BUG();
 		if (found->mapping != &swapper_space)
-			goto out_bad;
+			BUG();
 #ifdef SWAP_CACHE_INFO
 		swap_cache_find_success++;
 #endif
-		UnlockPage(found);
 		return found;
 	}
-
-out_bad:
-	printk (KERN_ERR "VM: Found a non-swapper swap page!\n");
-	UnlockPage(found);
-	page_cache_release(found);
-	return 0;
 }
 
 /* 
@@ -218,7 +199,7 @@
 	/*
 	 * Look for the page in the swap cache.
 	 */
-	found_page = lookup_swap_cache(entry);
+	found_page = lookup_swap_cache(entry, wait);
 	if (found_page)
 		goto out_free_swap;
 
@@ -230,7 +211,7 @@
 	/*
 	 * Check the swap cache again, in case we stalled above.
 	 */
-	found_page = lookup_swap_cache(entry);
+	found_page = lookup_swap_cache(entry, wait);
 	if (found_page)
 		goto out_free_page;
 	/*