[JFFS2] Optimise reading of eraseblock summary nodes

This improves the time to mount 512MiB of NAND flash on my OLPC prototype
by about 4%. We used to read the last page of the eraseblock twice -- once
to find the offset of the summary node, and again to actually _read_ the
summary node. Now we read the last page only once, and read more only if
we need to.

We also don't allocate a new buffer just for the summary code -- we use
the buffer which was already allocated for the scan. Better still, if the
'buffer' for the scan is actually just a pointer directly into NOR flash,
we use that too, avoiding the memcpy() which we used to do.

Signed-off-by: David Woodhouse <dwmw2@infradead.org>
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c
index 48293c1..82a3706 100644
--- a/fs/jffs2/summary.c
+++ b/fs/jffs2/summary.c
@@ -318,7 +318,6 @@
 				raw = jffs2_alloc_raw_node_ref();
 				if (!raw) {
 					JFFS2_NOTICE("allocation of node reference failed\n");
-					kfree(summary);
 					return -ENOMEM;
 				}
 
@@ -326,7 +325,6 @@
 				if (!ic) {
 					JFFS2_NOTICE("scan_make_ino_cache failed\n");
 					jffs2_free_raw_node_ref(raw);
-					kfree(summary);
 					return -ENOMEM;
 				}
 
@@ -358,10 +356,8 @@
 							jeb->offset + je32_to_cpu(spd->offset));
 
 				fd = jffs2_alloc_full_dirent(spd->nsize+1);
-				if (!fd) {
-					kfree(summary);
+				if (!fd)
 					return -ENOMEM;
-				}
 
 				memcpy(&fd->name, spd->name, spd->nsize);
 				fd->name[spd->nsize] = 0;
@@ -370,7 +366,6 @@
 				if (!raw) {
 					jffs2_free_full_dirent(fd);
 					JFFS2_NOTICE("allocation of node reference failed\n");
-					kfree(summary);
 					return -ENOMEM;
 				}
 
@@ -378,7 +373,6 @@
 				if (!ic) {
 					jffs2_free_full_dirent(fd);
 					jffs2_free_raw_node_ref(raw);
-					kfree(summary);
 					return -ENOMEM;
 				}
 
@@ -411,45 +405,28 @@
 
 			default : {
 				JFFS2_WARNING("Unsupported node type found in summary! Exiting...");
-				kfree(summary);
 				return -EIO;
 			}
 		}
 	}
 
-	kfree(summary);
 	return 0;
 }
 
 /* Process the summary node - called from jffs2_scan_eraseblock() */
-
 int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-				uint32_t ofs, uint32_t *pseudo_random)
+			   struct jffs2_raw_summary *summary, uint32_t sumsize,
+			   uint32_t *pseudo_random)
 {
 	struct jffs2_unknown_node crcnode;
 	struct jffs2_raw_node_ref *cache_ref;
-	struct jffs2_raw_summary *summary;
-	int ret, sumsize;
+	int ret, ofs;
 	uint32_t crc;
 
-	sumsize = c->sector_size - ofs;
-	ofs += jeb->offset;
+	ofs = jeb->offset + c->sector_size - sumsize;
 
 	dbg_summary("summary found for 0x%08x at 0x%08x (0x%x bytes)\n",
-				jeb->offset, ofs, sumsize);
-
-	summary = kmalloc(sumsize, GFP_KERNEL);
-
-	if (!summary) {
-		return -ENOMEM;
-	}
-
-	ret = jffs2_fill_scan_buf(c, (unsigned char *)summary, ofs, sumsize);
-
-	if (ret) {
-		kfree(summary);
-		return ret;
-	}
+		    jeb->offset, ofs, sumsize);
 
 	/* OK, now check for node validity and CRC */
 	crcnode.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
@@ -499,7 +476,6 @@
 
 			if (!marker_ref) {
 				JFFS2_NOTICE("Failed to allocate node ref for clean marker\n");
-				kfree(summary);
 				return -ENOMEM;
 			}