Index: compcache.c
===================================================================
--- compcache.c	(revision 243)
+++ compcache.c	(working copy)
@@ -45,6 +45,28 @@
 #if defined(STATS)
 static struct proc_dir_entry *proc;
 
+static void compcache_free_page(int page_no)
+{
+	if (compcache.table[page_no].len==PAGE_SIZE) {
+		kfree((char*)compcache.table[page_no].pageNum);
+	} else {
+		xvFree(compcache.mem_pool,
+			compcache.table[page_no].pageNum,
+			compcache.table[page_no].offset);
+	}
+}
+
+static void __store_page (int page_no, void* page)
+{
+	compcache.table[0].pageNum = (u32)page;
+	compcache.table[0].len = PAGE_SIZE;
+}
+
+static char* __extract_page (int page_no) {
+	return (char*) compcache.table[0].pageNum;
+}
+
+
 static int proc_compcache_read(char *page, char **start, off_t off,
 				int count, int *eof, void *data)
 {
@@ -115,6 +137,7 @@
 	size_t clen, page_no;
 	void *user_mem, *cmem;
 	struct page *page;
+	int alloc_error;
 
 	if (!valid_swap_request(bio)) {
 		stat_inc(stats.invalid_io);
@@ -148,24 +171,33 @@
 
 
 		clen = PAGE_SIZE;
-		cmem = (char *)xvMapPage(compcache.table[page_no].pageNum) +
-				compcache.table[page_no].offset;
 
 		/* Page is stored uncompressed since its incompressible */
 		if (unlikely(compcache.table[page_no].len == PAGE_SIZE)) {
+//			if (page_no>0) {
+				cmem = __extract_page(page_no);
+//			} else {
+//				cmem = (char *)xvMapPage(compcache.table[page_no].pageNum) + compcache.table[page_no].offset;
+//			}
+
 			memcpy(user_mem, cmem, PAGE_SIZE);
 			kunmap(page);
-			xvUnmapPage(compcache.table[page_no].pageNum);
+//			if (page_no == 0) 
+//			   xvUnmapPage(compcache.table[page_no].pageNum);
 			set_bit(BIO_UPTODATE, &bio->bi_flags);
 			BIO_ENDIO(bio, 0);
 			return 0;
+		} else {
+			cmem = (char *)xvMapPage(compcache.table[page_no].pageNum) + compcache.table[page_no].offset;
 		}
 
 		ret = lzo1x_decompress_safe(
 			cmem, compcache.table[page_no].len,
 			user_mem, &clen);
 
-		xvUnmapPage(compcache.table[page_no].pageNum);
+		if (compcache.table[page_no].len != PAGE_SIZE) {
+			xvUnmapPage(compcache.table[page_no].pageNum);
+		}
 
 		/* should NEVER happen */
 		if (unlikely(ret != LZO_E_OK)) {
@@ -189,9 +221,7 @@
 		 * to free the memory that was allocated for this page.
 		 */
 		if (compcache.table[page_no].pageNum) {
-			xvFree(compcache.mem_pool,
-				compcache.table[page_no].pageNum,
-				compcache.table[page_no].offset);
+			compcache_free_page(page_no);
 			stat_dec(stats.curr_pages);
 			stat_set(stats.curr_mem, stats.curr_mem	-
 					compcache.table[page_no].len);
@@ -212,15 +242,28 @@
 			goto out;
 		}
 
+		alloc_error=0;
+
 		/* Page is incompressible - store it as is */
-		if (clen >= PAGE_SIZE) {
+		/*if (clen >= PAGE_SIZE) {*/
+		if (unlikely(clen > (PAGE_SIZE-512))){
 			clen = PAGE_SIZE;
 			src = user_mem;
+			if (!(cmem=kmalloc(PAGE_SIZE,GFP_NOIO))) {
+				alloc_error=1;
+			}
+			compcache.table[page_no].pageNum=(u32)(cmem); /*32bit*/
+		} else {
+			if (unlikely(xvMalloc(compcache.mem_pool, clen,
+				&compcache.table[page_no].pageNum,
+				&offset))) {
+			alloc_error=2;
+			} else { 
+				cmem = (char *)xvMapPage(compcache.table[page_no].pageNum) + offset;
+			}
 		}
 
-		if (xvMalloc(compcache.mem_pool, clen,
-				&compcache.table[page_no].pageNum,
-				&offset)) {
+		if (alloc_error) {
 			mutex_unlock(&compcache.lock);
 #if defined(VERBOSE)
 			pr_info(C "Error allocating memory for compressed "
@@ -235,12 +278,10 @@
 
 		compcache.table[page_no].offset = offset;
 		
-		cmem = (char *)xvMapPage(compcache.table[page_no].pageNum) +
-				compcache.table[page_no].offset;
-
 		memcpy(cmem, src, clen);
 
-		xvUnmapPage(compcache.table[page_no].pageNum);
+		if (clen!=PAGE_SIZE) 
+			xvUnmapPage(compcache.table[page_no].pageNum);
 
 		/* Update stats */
 		stat_inc(stats.curr_pages);
@@ -321,18 +362,23 @@
         }
         memset(compcache.table, 0, num_pages * sizeof(*compcache.table));
 
-	page = alloc_page(__GFP_ZERO);
+	//page = alloc_page(__GFP_ZERO);
+	page = kmalloc(PAGE_SIZE,GFP_KERNEL);
+        memset(page, 0, PAGE_SIZE);
+
 	if (page == NULL) {
 		pr_err(C "Error allocating swap header page\n");
 		ret = -ENOMEM;
 		goto fail;
 	}
-	compcache.table[0].pageNum = page_to_pfn(page);
-	compcache.table[0].len = PAGE_SIZE;
+	/*compcache.table[0].pageNum = page_to_pfn(page);
+	compcache.table[0].len = PAGE_SIZE;*/
+	__store_page(0,page);
 
-	swap_header = kmap(page);
+	//swap_header = kmap(page);
+	swap_header = page;
 	setup_swap_header((union swap_header *)(swap_header));
-	kunmap(page);
+	//kunmap(page);
 
 	compcache.disk = alloc_disk(1);
 	if (compcache.disk == NULL) {
@@ -398,7 +444,7 @@
 		del_gendisk(compcache.disk);
 	}
 
-	__free_page(pfn_to_page(compcache.table[0].pageNum));
+	//__free_page(pfn_to_page(compcache.table[0].pageNum));
 	kfree(compcache.compress_workmem);
 	kfree(compcache.compress_buffer);
 	vfree(compcache.table);
@@ -418,16 +464,14 @@
 
 	unregister_blkdev(compcache.disk->major, compcache.disk->disk_name);
 	del_gendisk(compcache.disk);
-	__free_page(pfn_to_page(compcache.table[0].pageNum));
+	//__free_page(pfn_to_page(compcache.table[0].pageNum));
 	kfree(compcache.compress_workmem);
 	kfree(compcache.compress_buffer);
 
 	/* Free all pages that are still in compcache */
-	for (i = 1; i < num_pages; i++) {
+	for (i = 0; i < num_pages; i++) {
 		if (compcache.table[i].pageNum) {
-			xvFree(compcache.mem_pool,
-				compcache.table[i].pageNum,
-				compcache.table[i].offset);
+			compcache_free_page(i);
 		}
 	}
 
