patch-2.0.18 linux/mm/filemap.c

Next file: linux/mm/mmap.c
Previous file: linux/kernel/sched.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.0.17/linux/mm/filemap.c linux/mm/filemap.c
@@ -255,13 +255,14 @@
 }
 
 static inline void add_to_page_cache(struct page * page,
-	struct inode * inode, unsigned long offset)
+	struct inode * inode, unsigned long offset,
+	struct page **hash)
 {
 	page->count++;
 	page->flags &= ~((1 << PG_uptodate) | (1 << PG_error));
 	page->offset = offset;
 	add_page_to_inode_queue(inode, page);
-	add_page_to_hash_queue(inode, page);
+	__add_page_to_hash_queue(page, hash);
 }
 
 /*
@@ -272,32 +273,31 @@
 static unsigned long try_to_read_ahead(struct inode * inode, unsigned long offset, unsigned long page_cache)
 {
 	struct page * page;
+	struct page ** hash;
 
 	offset &= PAGE_MASK;
-	if (!page_cache) {
+	switch (page_cache) {
+	case 0:
 		page_cache = __get_free_page(GFP_KERNEL);
 		if (!page_cache)
-			return 0;
-	}
-	if (offset >= inode->i_size)
-		return page_cache;
-#if 1
-	page = find_page(inode, offset);
-	if (page) {
+			break;
+	default:
+		if (offset >= inode->i_size)
+			break;
+		hash = page_hash(inode, offset);
+		page = __find_page(inode, offset, *hash);
+		if (!page) {
+			/*
+			 * Ok, add the new page to the hash-queues...
+			 */
+			page = mem_map + MAP_NR(page_cache);
+			add_to_page_cache(page, inode, offset, hash);
+			inode->i_op->readpage(inode, page);
+			page_cache = 0;
+		}
 		release_page(page);
-		return page_cache;
 	}
-	/*
-	 * Ok, add the new page to the hash-queues...
-	 */
-	page = mem_map + MAP_NR(page_cache);
-	add_to_page_cache(page, inode, offset);
-	inode->i_op->readpage(inode, page);
-	free_page(page_cache);
-	return 0;
-#else
 	return page_cache;
-#endif
 }
 
 /* 
@@ -457,13 +457,12 @@
 #endif
 
 static inline unsigned long generic_file_readahead(int reada_ok, struct file * filp, struct inode * inode,
-	unsigned long pos, struct page * page,
+	unsigned long ppos, struct page * page,
 	unsigned long page_cache)
 {
 	unsigned long max_ahead, ahead;
-	unsigned long raend, ppos;
+	unsigned long raend;
 
-	ppos = pos & PAGE_MASK;
 	raend = filp->f_raend & PAGE_MASK;
 	max_ahead = 0;
 
@@ -607,7 +606,7 @@
 	} else {
 		unsigned long needed;
 
-		needed = ((pos + count) & PAGE_MASK) - (pos & PAGE_MASK);
+		needed = ((pos + count) & PAGE_MASK) - ppos;
 
 		if (filp->f_ramax < needed)
 			filp->f_ramax = needed;
@@ -619,7 +618,7 @@
 	}
 
 	for (;;) {
-		struct page *page;
+		struct page *page, **hash;
 
 		if (pos >= inode->i_size)
 			break;
@@ -627,7 +626,8 @@
 		/*
 		 * Try to find the data in the page cache..
 		 */
-		page = find_page(inode, pos & PAGE_MASK);
+		hash = page_hash(inode, pos & PAGE_MASK);
+		page = __find_page(inode, pos & PAGE_MASK, *hash);
 		if (!page)
 			goto no_cached_page;
 
@@ -640,7 +640,7 @@
  * the page has been rewritten.
  */
 		if (PageUptodate(page) || PageLocked(page))
-			page_cache = generic_file_readahead(reada_ok, filp, inode, pos, page, page_cache);
+			page_cache = generic_file_readahead(reada_ok, filp, inode, pos & PAGE_MASK, page, page_cache);
 		else if (reada_ok && filp->f_ramax > MIN_READAHEAD)
 				filp->f_ramax = MIN_READAHEAD;
 
@@ -696,7 +696,7 @@
 		 */
 		page = mem_map + MAP_NR(page_cache);
 		page_cache = 0;
-		add_to_page_cache(page, inode, pos & PAGE_MASK);
+		add_to_page_cache(page, inode, pos & PAGE_MASK, hash);
 
 		/*
 		 * Error handling is tricky. If we get a read error,
@@ -764,7 +764,7 @@
 static unsigned long filemap_nopage(struct vm_area_struct * area, unsigned long address, int no_share)
 {
 	unsigned long offset;
-	struct page * page;
+	struct page * page, **hash;
 	struct inode * inode = area->vm_inode;
 	unsigned long old_page, new_page;
 
@@ -776,7 +776,8 @@
 	/*
 	 * Do we have something in the page cache already?
 	 */
-	page = find_page(inode, offset);
+	hash = page_hash(inode, offset);
+	page = __find_page(inode, offset, *hash);
 	if (!page)
 		goto no_cached_page;
 
@@ -841,7 +842,7 @@
 	 */
 	page = mem_map + MAP_NR(new_page);
 	new_page = 0;
-	add_to_page_cache(page, inode, offset);
+	add_to_page_cache(page, inode, offset, hash);
 
 	if (inode->i_op->readpage(inode, page) != 0)
 		goto failure;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov