patch-2.4.27 linux-2.4.27/mm/shmem.c

Next file: linux-2.4.27/net/802/Makefile
Previous file: linux-2.4.27/mm/page_alloc.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.26/mm/shmem.c linux-2.4.27/mm/shmem.c
@@ -86,7 +86,7 @@
 
 static void shmem_removepage(struct page *page)
 {
-	if (!PageLaunder(page))
+	if (!PageLaunder(page) && !PageError(page))
 		shmem_free_block(page->mapping->host);
 }
 
@@ -626,8 +626,11 @@
 	swp_entry_t swap;
 	int error = 0;
 
-	if (idx >= SHMEM_MAX_INDEX)
-		return -EFBIG;
+	if (idx >= SHMEM_MAX_INDEX) {
+		error = -EFBIG;
+		goto failed;
+	}
+
 	/*
 	 * Normally, filepage is NULL on entry, and either found
 	 * uptodate immediately, or allocated and zeroed, or read
@@ -781,18 +784,24 @@
 	}
 done:
 	if (!*pagep) {
-		if (filepage) {
+		if (filepage)
 			UnlockPage(filepage);
-			*pagep = filepage;
-		} else
-			*pagep = ZERO_PAGE(0);
+		else
+			filepage = ZERO_PAGE(0);
+		*pagep = filepage;
 	}
+	if (PageError(filepage))
+		ClearPageError(filepage);
 	return 0;
 
 failed:
-	if (*pagep != filepage) {
-		UnlockPage(filepage);
-		page_cache_release(filepage);
+	if (filepage) {
+		if (*pagep == filepage)
+			SetPageError(filepage);
+		else {
+			UnlockPage(filepage);
+			page_cache_release(filepage);
+		}
 	}
 	return error;
 }
@@ -1042,9 +1051,13 @@
 	struct inode *inode = filp->f_dentry->d_inode;
 	struct address_space *mapping = inode->i_mapping;
 	unsigned long index, offset;
+	loff_t pos = *ppos;
+
+	if (unlikely(pos < 0))
+		return;
 
-	index = *ppos >> PAGE_CACHE_SHIFT;
-	offset = *ppos & ~PAGE_CACHE_MASK;
+	index = pos >> PAGE_CACHE_SHIFT;
+	offset = pos & ~PAGE_CACHE_MASK;
 
 	for (;;) {
 		struct page *page = NULL;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)