[linux-mm-cc] [PATCH 04/12] clean up filemap.c

IKEDA Munehiro m-ikeda at ds.jp.nec.com
Mon Jul 23 06:06:37 EDT 2007


There were some duplicated implementations in find_get_pages*()
in filemap.c.
This patch defines new functions named decomp_ccache_pages*()
to merge them.

Signed-off-by: IKEDA, Munehiro <m-ikeda at ds.jp.nec.com>
---
 mm/filemap.c |  126 ++++++++++++++++++++++++++++++---------------------------
 1 files changed, 66 insertions(+), 60 deletions(-)

diff --git a/mm/filemap.c b/mm/filemap.c
index 65121c7..75c1b73 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -719,6 +719,37 @@ repeat:
 }
 EXPORT_SYMBOL(find_or_create_page);
 
+/*
+ * Decompress ccache pages and fix up NULL returns
+ */
+static unsigned int decomp_ccache_pages(struct page **pages,
+					struct address_space *mapping,
+					unsigned int nr_pages)
+{
+	unsigned int i, out, decomped;
+	struct page *page;
+	
+	for (i = 0, out = 0, decomped = 0; i < nr_pages; i++) {
+		if (PageCompressed(pages[i])) {
+			page = handle_ccache_fault
+				((struct chunk_head *)pages[i], mapping);
+
+			if (!page) {
+				CC_INFO("HCF returned null");
+				release_chunk_heads_or_pages(pages,
+							     i + 1, nr_pages);
+				CC_INFO("done release ch_or_pages: ret=%d", i);
+				break;
+			}
+		} else
+			page = pages[i];
+
+		if (page)
+			pages[out++] = page;
+	}
+	return out;
+}
+
 /**
  * find_get_pages - gang pagecache lookup
  * @mapping:	The address_space to search
@@ -755,28 +786,41 @@ unsigned find_get_pages(struct address_space *mapping, pgoff_t start,
 			nr_comp_pages++;
 	}
 	read_unlock_irq(&mapping->tree_lock);
+	
+	if (nr_comp_pages)
+		ret = decomp_ccache_pages(pages, mapping, ret);
 
-	if (!nr_comp_pages) goto out;
+	return ret;
+}
 
-	CC_DEBUG("compressed pages: %d/%d", nr_comp_pages, ret);
-	for (i = 0; (i < ret) && nr_comp_pages; i++) {
-		CC_DEBUG("in loop: i=%d", i);
-		if (!PageCompressed(pages[i]))
-			continue;
-		pages[i] = handle_ccache_fault
+/*
+ * Decompress ccache pages and fix up NULL returns for contiguous indices
+ */
+static unsigned int decomp_ccache_pages_contig(struct page **pages,
+					struct address_space *mapping,
+					unsigned int nr_pages,
+					unsigned int nr_comp_pages)
+{
+	unsigned int i, decomped;
+	
+	for (i = 0, decomped = 0;
+		(i < nr_pages) && (decomped < nr_comp_pages); i++) {
+
+		if (PageCompressed(pages[i])) {
+			pages[i] = handle_ccache_fault
 				((struct chunk_head *)pages[i], mapping);
-		if (pages[i]) {
-			nr_comp_pages--;
-			continue;
+			decomped++;
 		}
+		if (pages[i])
+			continue;
+
+		/* Here, pages[i] == NULL */
+		release_chunk_heads_or_pages(pages, i + 1, nr_pages);
 		CC_INFO("HCF returned null");
-		release_chunk_heads_or_pages(pages, i + 1, ret);
-		ret = i;
-		CC_INFO("done release ch_or_pages: ret=%d", ret);
+		CC_INFO("done release ch_or_pages: ret=%d", i);
 		break;
 	}
-out:
-	return ret;
+	return i;
 }
 
 /**
@@ -809,40 +853,20 @@ unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t index,
 		if (PageCompressed(pages[i])) {
 			if (((struct chunk_head *)pages[i])->offset != index)
 				break;
-			page_cache_get(pages[i]);
 			nr_comp_pages++;
-			index++;
-			continue;
 		}
-		if (pages[i]->mapping == NULL || pages[i]->index != index)
+		else if (pages[i]->mapping == NULL || pages[i]->index != index)
 			break;
 		page_cache_get(pages[i]);
 		index++;
 	}
 	read_unlock_irq(&mapping->tree_lock);
 
-	if (!nr_comp_pages) goto out;
-
 	ret = i;
-	for (i = 0; (i < ret) && nr_comp_pages; i++) {
-		CC_DEBUG("in loop: i=%d", i);
-		if (!PageCompressed(pages[i]))
-			continue;
-		pages[i] = handle_ccache_fault
-				((struct chunk_head *)pages[i], mapping);
-		if (pages[i]) {
-			nr_comp_pages--;
-			continue;
-		}
-		CC_INFO("HCF returned null");
-		release_chunk_heads_or_pages(pages, i + 1, ret);
-		ret = i;
-		CC_INFO("done release ch_or_pages: ret=%d", ret);
-		break;
-	}
-	i = ret;
-out:
-	return i;
+	if (nr_comp_pages)
+		ret = decomp_ccache_pages_contig(pages, mapping,
+						 i, nr_comp_pages);
+	return ret;
 }
 
 /**
@@ -877,26 +901,8 @@ unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index,
 	}
 	read_unlock_irq(&mapping->tree_lock);
 
-	if (!nr_comp_pages) goto out;
-
-	CC_DEBUG("compressed pages found: %d", nr_comp_pages);
-	for (i = 0; (i < ret) && nr_comp_pages; i++) {
-		CC_DEBUG("in loop: i=%d", i);
-		if (!PageCompressed(pages[i]))
-			continue;
-		pages[i] = handle_ccache_fault
-				((struct chunk_head *)pages[i], mapping);
-		if (pages[i]) {
-			nr_comp_pages--;
-			continue;
-		}
-		CC_INFO("HCF returned null");
-		release_chunk_heads_or_pages(pages, i + 1, ret);
-		ret = i;
-		CC_INFO("done release ch_or_pages: ret=%d", ret);
-		break;
-	}
-out:
+	if (nr_comp_pages)
+		ret = decomp_ccache_pages(pages, mapping, nr_pages);
 	if (ret)
 		*index = pages[ret - 1]->index + 1;
 	return ret;
-- 
1.4.4.4



More information about the linux-mm-cc mailing list